[cueweb/docs] Add Cuebot Facility switching (server-side gateway routing)#2433
Conversation
Wire the existing "Cuebot Facility" header selector (CueGUI parity) to actually re-route REST gateway calls per facility. Until now the selector only persisted an informational value in localStorage; all gateway calls went to a single NEXT_PUBLIC_OPENCUE_ENDPOINT. - lib/facility.ts: resolve a facility name to its REST gateway URL + JWT secret from CUEBOT_<NAME>_REST_GATEWAY_URL / CUEBOT_<NAME>_JWT_SECRET, falling back to NEXT_PUBLIC_OPENCUE_ENDPOINT / NEXT_JWT_SECRET so the default deployment needs no new config. getRequestFacilityTarget() reads the selection from the request cookie and re-validates it against the configured list. next/headers is imported dynamically so the module stays out of the client bundle (api_utils is client-reachable). - api_utils.ts: fetchObjectFromRestGateway resolves the per-request facility (single choke point for all proxy routes); createJwtToken takes an optional per-facility signing secret. - api/health: probe the selected facility's gateway so the status bar reflects the active facility. - use_cuebot_facility.ts: mirror the selection into the cueweb.facility cookie (so server routes see it), sync it on mount for pre-existing users, and reload on switch to re-fetch all data against the new gateway (mirroring CueGUI, which clears and refetches on a facility change). - status-bar.tsx: show the active Cuebot facility. - Document NEXT_PUBLIC_CUEBOT_FACILITIES and the paired CUEBOT_<NAME>_* vars in .env.example and docker-compose.yml.
… routing) Update the CueWeb docs to reflect that the Cuebot Facility menu now actually re-routes REST gateway calls per facility, rather than persisting an informational-only selection. - getting-started/deploying-cueweb.md: remove the stale "per-facility routing is implemented in a separate page-level change" note; document that switching re-routes server-side via the cueweb.facility cookie and add the per-facility CUEBOT_<NAME>_REST_GATEWAY_URL / CUEBOT_<NAME>_JWT_SECRET vars (with fallback to NEXT_PUBLIC_OPENCUE_ENDPOINT / NEXT_JWT_SECRET). - other-guides/cueweb.md, user-guides/cueweb-user-guide.md: expand the Cuebot Facility menu description (selecting a facility re-fetches all data from that facility's gateway, the choice persists, the active facility shows in the status bar) - CueGUI parity, user-facing. - reference/cueweb.md: add the per-facility env-var rows; expand the dropdown entry with the cookie -> lib/facility.ts (getRequestFacilityTarget) -> per-request gateway resolution and the status-bar probe. - developer-guide/cueweb-development.md: expand the useCuebotFacility hook entry (cookie mirror, reload-on-switch, the lib/facility.ts resolver, env precedence, dynamic next/headers note) and add lib/facility.ts to the file tree.
📝 WalkthroughWalkthroughAdds multi-facility Cuebot gateway routing to CueWeb. A new ChangesCueWeb Multi-Facility Cuebot Gateway Routing
Sequence Diagram(s)sequenceDiagram
participant Browser as Browser
participant useCuebotFacility as useCuebotFacility Hook
participant Cookie as cueweb.facility Cookie
participant NextAPIRoute as Next.js API Route
participant getRequestFacilityTarget as getRequestFacilityTarget
participant CuebotGateway as Cuebot REST Gateway
Browser->>useCuebotFacility: setFacility("Vegas")
useCuebotFacility->>Cookie: writeCookie("cueweb.facility", "Vegas")
useCuebotFacility->>Browser: window.location.reload()
Browser->>NextAPIRoute: GET /api/health (Cookie: cueweb.facility=Vegas)
NextAPIRoute->>getRequestFacilityTarget: await getRequestFacilityTarget()
getRequestFacilityTarget->>Cookie: cookies().get("cueweb.facility") → "Vegas"
getRequestFacilityTarget-->>NextAPIRoute: FacilityTarget { gatewayUrl, jwtSecret }
NextAPIRoute->>CuebotGateway: POST GetActiveShows (facility-specific URL + JWT)
CuebotGateway-->>NextAPIRoute: Response
NextAPIRoute-->>Browser: HealthBody
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
docs/_docs/reference/cueweb.md (1)
87-94:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winSection title conflicts with the new server-side env vars.
CUEBOT_<NAME>_REST_GATEWAY_URLandCUEBOT_<NAME>_JWT_SECRETare documented as server-only, but they’re listed under “Optional Build-Time Variables.” Renaming this section avoids deployment confusion.Suggested fix
-### Optional Build-Time Variables +### Optional Variables🤖 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 `@docs/_docs/reference/cueweb.md` around lines 87 - 94, The section title "Optional Build-Time Variables" is misleading because the table includes server-only environment variables (CUEBOT_<NAME>_REST_GATEWAY_URL and CUEBOT_<NAME>_JWT_SECRET) that are not build-time variables. Rename the section title to accurately reflect that it contains both build-time variables and server-only runtime variables, or alternatively split the table into separate sections for each category to avoid deployment confusion.cueweb/app/utils/use_cuebot_facility.ts (1)
110-120:⚠️ Potential issue | 🟠 Major | ⚡ Quick winRefresh after out-of-band facility syncs.
setFacility()reloads only the tab that made the change. Line 115 backfills the server-visible cookie after the first request already used the old/default cookie, and Lines 117-120 update other tabs’ labels without clearing data fetched from the previous facility. Because server routes select the gateway fromcueweb.facility, these paths can leave stale cross-facility data on screen.Proposed fix
React.useEffect(() => { const current = readSelected(facilities); setFacilityState(current); // Propagate a pre-existing localStorage selection (set before the cookie // existed) to the cookie so server routes pick it up without a reselect. - if (readCookie() !== current) writeCookie(current); + const cookieFacility = readCookie(); + if (cookieFacility !== current) { + writeCookie(current); + const fallback = facilities[0] ?? "local"; + const wroteCookie = readCookie() === current; + const serverMayHaveUsedDifferentFacility = + current !== fallback || + (cookieFacility !== null && facilities.includes(cookieFacility)); + if (wroteCookie && serverMayHaveUsedDifferentFacility) { + window.location.reload(); + return; + } + } const customHandler = () => setFacilityState(readSelected(facilities)); const storageHandler = (e: StorageEvent) => { - if (e.key === STORAGE_KEY) setFacilityState(readSelected(facilities)); + if (e.key !== STORAGE_KEY) return; + const next = readSelected(facilities); + setFacilityState(next); + writeCookie(next); + if (e.oldValue !== e.newValue) window.location.reload(); };🤖 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 `@cueweb/app/utils/use_cuebot_facility.ts` around lines 110 - 120, The facility state updates in the useEffect hook do not trigger a refresh of cached data when the facility changes out-of-band, causing stale data from the previous facility to remain on screen. When the storageHandler function detects a facility change via the storage event (checking STORAGE_KEY), it currently only calls setFacilityState but should also clear any cached data or trigger a full refresh to ensure no stale cross-facility data persists. Additionally, the cookie backfill at line 115 using writeCookie should either happen before any data fetching or be accompanied by a mechanism to clear stale data so that subsequent server requests using the updated cueweb.facility value don't mix data from different facilities.
🤖 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.
Inline comments:
In `@cueweb/app/utils/api_utils.ts`:
- Around line 83-86: In the createJwtToken function, add validation after the
signingSecret assignment to ensure it is neither blank nor undefined. Check if
signingSecret is a valid non-empty string, and throw an error with a descriptive
message if it fails validation. This ensures the function fails fast with a
clear configuration error rather than attempting to sign a token with an invalid
secret.
- Around line 46-48: After destructuring gatewayUrl and jwtSecret from the
getRequestFacilityTarget() call, add a validation check to ensure gatewayUrl is
not empty before constructing the URL with the endpoint. If gatewayUrl is
missing or empty, return an explicit error response indicating that the gateway
URL is not configured, rather than allowing the code to proceed to a generic
fetch failure. This validation should occur before the line where the URL string
is constructed.
In `@cueweb/app/utils/use_cuebot_facility.ts`:
- Around line 57-62: The readCookie function does not handle exceptions that may
be thrown by decodeURIComponent when processing malformed cookie values. Wrap
the return statement containing the decodeURIComponent call in a try-catch
block, and return null in the catch block to gracefully handle decoding failures
instead of allowing the exception to propagate.
---
Outside diff comments:
In `@cueweb/app/utils/use_cuebot_facility.ts`:
- Around line 110-120: The facility state updates in the useEffect hook do not
trigger a refresh of cached data when the facility changes out-of-band, causing
stale data from the previous facility to remain on screen. When the
storageHandler function detects a facility change via the storage event
(checking STORAGE_KEY), it currently only calls setFacilityState but should also
clear any cached data or trigger a full refresh to ensure no stale
cross-facility data persists. Additionally, the cookie backfill at line 115
using writeCookie should either happen before any data fetching or be
accompanied by a mechanism to clear stale data so that subsequent server
requests using the updated cueweb.facility value don't mix data from different
facilities.
In `@docs/_docs/reference/cueweb.md`:
- Around line 87-94: The section title "Optional Build-Time Variables" is
misleading because the table includes server-only environment variables
(CUEBOT_<NAME>_REST_GATEWAY_URL and CUEBOT_<NAME>_JWT_SECRET) that are not
build-time variables. Rename the section title to accurately reflect that it
contains both build-time variables and server-only runtime variables, or
alternatively split the table into separate sections for each category to avoid
deployment confusion.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5482b176-e7bc-4437-8415-f8ed894c6102
📒 Files selected for processing (12)
cueweb/.env.examplecueweb/app/api/health/route.tscueweb/app/utils/api_utils.tscueweb/app/utils/use_cuebot_facility.tscueweb/components/ui/status-bar.tsxcueweb/lib/facility.tsdocker-compose.ymldocs/_docs/developer-guide/cueweb-development.mddocs/_docs/getting-started/deploying-cueweb.mddocs/_docs/other-guides/cueweb.mddocs/_docs/reference/cueweb.mddocs/_docs/user-guides/cueweb-user-guide.md
Address code review feedback on the Cuebot Facility switching path.
- api_utils.ts: fail fast on facility misconfiguration. fetchObjectFromRestGateway returns a 503 ("No REST gateway configured for the selected facility") when the resolved gateway URL is empty, instead of building a bogus fetch URL. createJwtToken throws on a missing/blank signing secret rather than signing with an empty key (validated via trim(), but signed with the original value so a gateway reading the same secret verbatim isn't mismatched).
- use_cuebot_facility.ts: treat the cueweb.facility cookie as untrusted — wrap decodeURIComponent in try/catch and return null on a malformed value, so a bad cookie can't throw during the mount effect and stop the hook from syncing.
|
@DiegoTavares / @lithorus |


Related Issues
Main issue:
Issues related to this PR:
Summarize your change.
[cueweb] Add Cuebot Facility switching (server-side gateway routing)
Wire the existing "Cuebot Facility" header selector (CueGUI parity) to actually re-route REST gateway calls per facility. Until now the selector only persisted an informational value in localStorage; all gateway calls went to a single NEXT_PUBLIC_OPENCUE_ENDPOINT.
[cueweb/docs] Document Cuebot Facility switching (server-side gateway routing)
Update the CueWeb docs to reflect that the Cuebot Facility menu now actually re-routes REST gateway calls per facility, rather than persisting an informational-only selection.
LLM usage disclosure
Parts of this solution's implementation were developed with assistance from Claude Opus.