Skip to content

fix: land issue 127 follow-up cleanup and hostname split#133

Merged
JustAGhosT merged 3 commits into
devfrom
fix/issue-127-followup-cleanup
Jul 13, 2026
Merged

fix: land issue 127 follow-up cleanup and hostname split#133
JustAGhosT merged 3 commits into
devfrom
fix/issue-127-followup-cleanup

Conversation

@JustAGhosT

@JustAGhosT JustAGhosT commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Validation

Summary by CodeRabbit

  • New Features

    • Added support for configuring public dashboard and gateway URLs.
    • Added custom domain support for dashboard access.
    • Improved automatic model routing and fallback behavior across available providers.
  • Bug Fixes

    • Fixed recent logs table rendering for smoother scrolling and consistent row layout.
    • Corrected key information requests in non-admin views.
    • Dashboard and analytics refresh indicators now show an unknown timestamp when update data is unavailable.

JustAGhosT and others added 3 commits May 18, 2026 12:53
Bundles all 8 follow-up items from issue #127.

Code correctness:
- recent-logs-table: switch virtualization from absolute-positioned <tr>
  (which browsers ignore on table rows) to the padding-rows technique
  per @tanstack/react-virtual table guidance. As a bonus, real <tr>s
  inherit thead's column widths, so the sticky header now aligns with
  body cells — obsoletes the column-drift TODO.
- sluice_aca/main.tf: define `auto` model alias unconditionally. It's
  allowlisted by every vkey in keys.yaml, so a deployment with no extra
  providers configured was 404'ing `model: "auto"` requests. With no
  extras it now points at Azure (same target as `premium`).
- sluice_aca/main.tf: split has_any_extra into per-alias guards. A
  gemini-only deployment was emitting fallback chains that referenced
  cheap-fast / cheap-reasoning (groq/together/fireworks only). Each
  chain entry is now gated on whether its source alias actually exists,
  and context_window_fallbacks is gated on has_cheap_long_context.
- use-keys: change non-admin fallback from /v1/key/info to /key/info to
  match the rest of the codebase's key-management endpoints (the
  /v1/key/* prefix is OpenAI-compat surface, not wired for key-info).
- analytics-view + admin-view: pass `null` to RefreshBar's lastUpdated
  until the first fetch completes, instead of constructing
  `new Date(0)` (= 1970-01-01) or `new Date(Date.now())`. Matches the
  pattern already used in components/dashboard.tsx:312.

Hygiene:
- Remove .claude/settings.local.json (developer-local Claude perms),
  .handoff.md (ephemeral session log), .pr-body.md (generated PR body).
- Add .claude/ to .gitignore so future local settings don't reappear.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 13, 2026 01:30
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR updates dashboard timestamp and key lookup handling, reworks recent-log virtualization, adds dashboard public URL and custom-domain Terraform configuration, makes LiteLLM fallbacks provider-aware, and ignores local Claude settings.

Changes

Dashboard behavior

Layer / File(s) Summary
Refresh and key data handling
dashboard/components/admin/admin-view.tsx, dashboard/components/analytics/analytics-view.tsx, dashboard/hooks/use-keys.ts
Refresh timestamps now remain null when unavailable, and non-admin key lookup uses /key/info.
Recent logs virtualization
dashboard/components/tables/recent-logs-table.tsx
Recent-log rows render in normal table flow with spacer rows rather than absolute positioning.

Dashboard public access

Layer / File(s) Summary
Public URL and domain inputs
infra/env/prod/variables.tf, infra/env/prod/terraform.tfvars, infra/env/prod/main.tf, infra/modules/dashboard_aca/variables.tf, infra/modules/dashboard_aca/main.tf
Terraform adds HTTPS URL inputs, dashboard hostname inputs, and derived gateway/dashboard URLs.
Custom-domain resources and outputs
infra/env/prod/main.tf, infra/modules/dashboard_aca/main.tf, infra/modules/dashboard_aca/outputs.tf
The dashboard Container App receives custom-domain bindings and exposes configured domain names and dashboard URLs.

Conditional gateway routing

Layer / File(s) Summary
Auto alias selection and model metadata
infra/modules/sluice_aca/main.tf
The auto alias selects valid targets, computes provider-specific costs, and applies Azure settings conditionally.
Provider-aware fallback settings
infra/modules/sluice_aca/main.tf
Fallback and context-window chains include only available cheap-* aliases.

Repository local settings

Layer / File(s) Summary
Claude settings ignore rule
.gitignore
The .claude/ directory is added to ignored paths.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • phoenixvc/sluice#128: Contains overlapping dashboard, key endpoint, virtualization, and LiteLLM fallback changes.
  • phoenixvc/sluice#95: Also modifies LiteLLM model-list and fallback configuration generation.
  • phoenixvc/sluice#102: Also modifies RecentLogsTable virtualization and rendering logic.

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main changes: issue 127 follow-up cleanup plus the hostname split.
Description check ✅ Passed The description covers summary and validation, but it omits deployment notes and risk/rollback details from the template.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/issue-127-followup-cleanup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR finishes the Issue #127 follow-up cleanup and completes the hostname split so the dashboard and LiteLLM gateway/admin UI live on separate public domains, while keeping Terraform aligned with the out-of-band DNS/cert bindings.

Changes:

  • Terraform: ensure the auto alias is always present and make fallback/context-window chains conditional on which alias groups actually exist.
  • Terraform: add explicit gateway_public_url, dashboard_public_url, and dashboard custom-domain bindings to support the split (sluice.phoenixvc.tech vs litellm.sluice.phoenixvc.tech).
  • Dashboard: fix table virtualization for recent logs, correct non-admin key-info endpoint usage, and prevent “1970-01-01” last-updated rendering.

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated no comments.

Show a summary per file
File Description
infra/modules/sluice_aca/main.tf Makes auto always defined and hardens fallbacks/context-window fallbacks against missing alias groups.
infra/modules/dashboard_aca/variables.tf Adds public URL + custom domain inputs for the dashboard module.
infra/modules/dashboard_aca/main.tf Uses public gateway/dashboard URLs for env vars and adds dashboard custom-domain bindings.
infra/modules/dashboard_aca/outputs.tf Outputs dashboard URL preferring configured public URL; exposes bound custom domains.
infra/env/prod/variables.tf Wires new public URL and dashboard custom-domain variables at the prod env layer.
infra/env/prod/terraform.tfvars Sets prod values for split hostnames and dashboard/gateway public URLs.
infra/env/prod/main.tf Updates out-of-band import adoption to match the new gateway + dashboard hostnames and passes new vars to the dashboard module.
dashboard/hooks/use-keys.ts Uses /key/info (not /v1/key/info) for non-admin key lookup.
dashboard/components/tables/recent-logs-table.tsx Switches recent-logs table virtualization to padding-row technique so <tr> stays in normal flow and aligns with sticky headers.
dashboard/components/analytics/analytics-view.tsx Avoids rendering epoch time by passing null until first successful refresh.
dashboard/components/admin/admin-view.tsx Matches refresh-bar behavior by passing null until first successful refresh.
.gitignore Ignores .claude/ to prevent developer-local Claude settings from being committed.
.pr-body.md Removes generated PR template file from the repo.
.handoff.md Removes ephemeral handoff log from the repo.
.claude/settings.local.json Removes developer-local Claude permissions config from the repo.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bbc4b6d37e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# Public dashboard entrypoint. The dashboard links through to the LiteLLM
# admin UI at gateway_public_url /ui.
dashboard_custom_domains = ["sluice.phoenixvc.tech"]
dashboard_public_url = "https://sluice.phoenixvc.tech"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update gateway docs before reusing the old host

When this maps sluice.phoenixvc.tech to the dashboard, the repo still tells agent/SDK consumers to use that same host as the gateway (AGENTS.md documents OPENAI_BASE_URL=https://sluice.phoenixvc.tech/v1 and Anthropic base URLs on the same hostname). The dashboard app only proxies LiteLLM under /api/gateway/[...path], so clients following those instructions will send /v1 or Anthropic requests to the Next app instead of LiteLLM and fail; update the consumer-facing instructions or add compatible passthroughs as part of this hostname split.

Useful? React with 👍 / 👎.

@JustAGhosT
JustAGhosT merged commit bde9bc2 into dev Jul 13, 2026
1 of 2 checks passed
@JustAGhosT
JustAGhosT deleted the fix/issue-127-followup-cleanup branch July 13, 2026 01:42

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
infra/modules/dashboard_aca/main.tf (1)

18-26: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cache normalized URLs in locals.

trimspace(var.gateway_public_url) and trimspace(var.dashboard_public_url) are each evaluated twice. Define each normalized value once and reuse it.

Proposed refactor
 locals {
   prefix           = "pvc-${var.env}-${var.projname}"
   ca_name          = "${local.prefix}-dashboard"
   use_shared_token = trimspace(var.state_service_shared_token) != ""
   use_entra        = var.auth_mode == "entra"

-  gateway_url = trimspace(var.gateway_public_url) != "" ? trimspace(var.gateway_public_url) : var.gateway_url
+  gateway_public_url = trimspace(var.gateway_public_url)
+  gateway_url        = local.gateway_public_url != "" ? local.gateway_public_url : var.gateway_url

   cae_suffix            = trimprefix(var.gateway_url, "https://${local.prefix}-ca.")
   derived_dashboard_url = local.cae_suffix == var.gateway_url ? "" : "https://${local.ca_name}.${local.cae_suffix}"
-  dashboard_url         = trimspace(var.dashboard_public_url) != "" ? trimspace(var.dashboard_public_url) : local.derived_dashboard_url
+  dashboard_public_url   = trimspace(var.dashboard_public_url)
+  dashboard_url          = local.dashboard_public_url != "" ? local.dashboard_public_url : local.derived_dashboard_url
 }

As per coding guidelines: Use local values for repeated expressions in Terraform.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@infra/modules/dashboard_aca/main.tf` around lines 18 - 26, Define locals for
the trimmed gateway and dashboard public URL values, then update gateway_url and
dashboard_url to reuse those locals instead of calling trimspace on each
variable twice. Keep the existing fallback behavior unchanged.

Source: Coding guidelines

dashboard/components/tables/recent-logs-table.tsx (1)

262-304: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Solid padding-rows virtualization implementation.

Correctly follows the @tanstack/react-virtual table pattern: spacer <tr>s sized from start/getTotalSize(), real rows in normal flow, colSpan matches the 8 header columns.

One optional improvement: estimateSize: () => 48 is a static guess, but DataRow renders two-line cells (App/Agent, Tokens), so actual row height can exceed 48px. Consider wiring up measureElement so the virtualizer measures real row heights, keeping paddingTop/paddingBottom accurate and avoiding scroll-position drift on longer lists.

♻️ Optional: enable dynamic row measurement
                       {virtualItems.map((virtualRow) => {
                         const d = sorted[virtualRow.index];
                         const tsFmt =
                           d.tsMs > 0 ? new Date(d.tsMs).toLocaleString() : d.ts || "—";
                         return (
                           <DataRow
                             key={d.raw.request_id || virtualRow.index}
+                            ref={rowVirtualizer.measureElement}
+                            data-index={virtualRow.index}
                             tsFmt={tsFmt}
                             derived={d}
                             onSelect={() => setSelectedRow(d.raw)}
                           />
                         );
                       })}

(Requires forwarding a ref to the underlying <tr> in DataRow.)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@dashboard/components/tables/recent-logs-table.tsx` around lines 262 - 304,
Optionally enable dynamic row-height measurement for the table virtualizer:
update the virtualizer configuration using measureElement and forward its ref
through DataRow to the underlying tr, while retaining estimateSize as the
fallback. Ensure measured two-line rows keep paddingTop, paddingBottom, and
scroll positioning accurate.
infra/modules/sluice_aca/main.tf (1)

439-469: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Extract provider pricing into shared locals
The Groq/Together/Fireworks token prices are duplicated in both the provider model entries and the auto fallback; a single source of truth would reduce drift when pricing changes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@infra/modules/sluice_aca/main.tf` around lines 439 - 469, Extract the Groq,
Together, and Fireworks input/output token prices into shared locals in the
module’s locals block, then reuse those locals in both the provider model
entries and the auto_model_cost_in/auto_model_cost_out fallback expressions.
Remove the duplicated numeric literals while preserving the existing
provider-specific pricing and fallback behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@dashboard/components/tables/recent-logs-table.tsx`:
- Around line 262-304: Optionally enable dynamic row-height measurement for the
table virtualizer: update the virtualizer configuration using measureElement and
forward its ref through DataRow to the underlying tr, while retaining
estimateSize as the fallback. Ensure measured two-line rows keep paddingTop,
paddingBottom, and scroll positioning accurate.

In `@infra/modules/dashboard_aca/main.tf`:
- Around line 18-26: Define locals for the trimmed gateway and dashboard public
URL values, then update gateway_url and dashboard_url to reuse those locals
instead of calling trimspace on each variable twice. Keep the existing fallback
behavior unchanged.

In `@infra/modules/sluice_aca/main.tf`:
- Around line 439-469: Extract the Groq, Together, and Fireworks input/output
token prices into shared locals in the module’s locals block, then reuse those
locals in both the provider model entries and the
auto_model_cost_in/auto_model_cost_out fallback expressions. Remove the
duplicated numeric literals while preserving the existing provider-specific
pricing and fallback behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d88375eb-8823-4985-9d5a-be7b7b1620b0

📥 Commits

Reviewing files that changed from the base of the PR and between 60e7b91 and bbc4b6d.

📒 Files selected for processing (15)
  • .claude/settings.local.json
  • .gitignore
  • .handoff.md
  • .pr-body.md
  • dashboard/components/admin/admin-view.tsx
  • dashboard/components/analytics/analytics-view.tsx
  • dashboard/components/tables/recent-logs-table.tsx
  • dashboard/hooks/use-keys.ts
  • infra/env/prod/main.tf
  • infra/env/prod/terraform.tfvars
  • infra/env/prod/variables.tf
  • infra/modules/dashboard_aca/main.tf
  • infra/modules/dashboard_aca/outputs.tf
  • infra/modules/dashboard_aca/variables.tf
  • infra/modules/sluice_aca/main.tf
💤 Files with no reviewable changes (3)
  • .claude/settings.local.json
  • .pr-body.md
  • .handoff.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants