Skip to content

[cueweb/docs] Add Cuebot Facility switching (server-side gateway routing)#2433

Open
ramonfigueiredo wants to merge 3 commits into
AcademySoftwareFoundation:masterfrom
ramonfigueiredo:cueweb-facility-switching
Open

[cueweb/docs] Add Cuebot Facility switching (server-side gateway routing)#2433
ramonfigueiredo wants to merge 3 commits into
AcademySoftwareFoundation:masterfrom
ramonfigueiredo:cueweb-facility-switching

Conversation

@ramonfigueiredo

@ramonfigueiredo ramonfigueiredo commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

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.

  • lib/facility.ts: resolve a facility name to its REST gateway URL + JWT secret from CUEBOT_REST_GATEWAY_URL / CUEBOT_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__* vars in .env.example and docker-compose.yml.

[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.

  • 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_REST_GATEWAY_URL / CUEBOT_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.

LLM usage disclosure

Parts of this solution's implementation were developed with assistance from Claude Opus.

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.
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds multi-facility Cuebot gateway routing to CueWeb. A new lib/facility.ts module resolves per-facility REST gateway URLs and JWT secrets from environment variables. The useCuebotFacility hook now mirrors the selected facility into a cueweb.facility cookie and reloads the page on change. Server-side API routes (/api/health, fetchObjectFromRestGateway) use the resolver. The status bar gains an active-facility indicator. All new variables are documented.

Changes

CueWeb Multi-Facility Cuebot Gateway Routing

Layer / File(s) Summary
lib/facility.ts: server-side facility resolver
cueweb/lib/facility.ts
New module exports FACILITY_COOKIE, FacilityTarget interface, getConfiguredFacilities(), resolveFacilityTarget(), and getRequestFacilityTarget(). Reads NEXT_PUBLIC_CUEBOT_FACILITIES, maps facility names to CUEBOT_<NAME>_REST_GATEWAY_URL / CUEBOT_<NAME>_JWT_SECRET with fallback to legacy globals, and resolves the active facility from the request cookie via dynamic next/headers import.
useCuebotFacility: cookie mirroring and page reload
cueweb/app/utils/use_cuebot_facility.ts
Adds writeCookie/readCookie helpers with SSR guards; syncs localStorage selection into cueweb.facility cookie on mount; extends setFacility to write both localStorage and cookie, dispatch the facility-changed event, and trigger window.location.reload() when the facility actually changes.
Health route and fetchObjectFromRestGateway wired to resolver
cueweb/app/api/health/route.ts, cueweb/app/utils/api_utils.ts
Both call getRequestFacilityTarget() to obtain gatewayUrl and jwtSecret. createJwtToken gains an optional secret parameter defaulting to NEXT_JWT_SECRET and throws error when signing secret is missing. The health route updates its offline error message to name the selected facility.
Status bar active facility display
cueweb/components/ui/status-bar.tsx
Imports Server icon and useCuebotFacility; reads facility and renders a new StatusItem displaying the active Cuebot facility in uppercase with a preceding divider.
Environment config and documentation
cueweb/.env.example, docker-compose.yml, docs/_docs/.../*
Documents NEXT_PUBLIC_CUEBOT_FACILITIES, per-facility CUEBOT_<NAME>_REST_GATEWAY_URL / CUEBOT_<NAME>_JWT_SECRET with fallback behavior, cookie-based session persistence, lib/facility.ts resolution flow, and updated useCuebotFacility behavior across env example, docker-compose comments, developer guide, deployment guide, reference, other guides, and user guide.

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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • [cueweb] Add Cuebot Facility switching #2437: This PR directly implements the Cuebot Facility switching feature proposed in that issue, including lib/facility.ts for per-facility gateway routing, cookie-based persistence in useCuebotFacility, and dynamic routing of health checks and REST API requests to the selected facility's gateway.

Suggested reviewers

  • DiegoTavares
  • lithorus

Poem

🐇 Hop to Vegas, hop to Main,
The cookie knows which Cuebot's lane!
A server reads the crumb I set,
And fetches jobs without a fret.
The status bar now proudly shows
Which facility the data flows! 🌐

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: implementing server-side gateway routing for Cuebot Facility switching in CueWeb, which is the core feature across all modified files.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@ramonfigueiredo ramonfigueiredo changed the title [cueweb] Add Cuebot Facility switching (server-side gateway routing) [cueweb/docs] Add Cuebot Facility switching (server-side gateway routing) Jun 18, 2026
@ramonfigueiredo

Copy link
Copy Markdown
Collaborator Author
Screenshot 2026-06-17 at 4 27 07 PM Screenshot 2026-06-17 at 4 27 11 PM

@coderabbitai coderabbitai Bot 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.

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 win

Section title conflicts with the new server-side env vars.

CUEBOT_<NAME>_REST_GATEWAY_URL and CUEBOT_<NAME>_JWT_SECRET are 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 win

Refresh 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 from cueweb.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

📥 Commits

Reviewing files that changed from the base of the PR and between ca5f70f and 6908852.

📒 Files selected for processing (12)
  • cueweb/.env.example
  • cueweb/app/api/health/route.ts
  • cueweb/app/utils/api_utils.ts
  • cueweb/app/utils/use_cuebot_facility.ts
  • cueweb/components/ui/status-bar.tsx
  • cueweb/lib/facility.ts
  • docker-compose.yml
  • docs/_docs/developer-guide/cueweb-development.md
  • docs/_docs/getting-started/deploying-cueweb.md
  • docs/_docs/other-guides/cueweb.md
  • docs/_docs/reference/cueweb.md
  • docs/_docs/user-guides/cueweb-user-guide.md

Comment thread cueweb/app/utils/api_utils.ts
Comment thread cueweb/app/utils/api_utils.ts Outdated
Comment thread cueweb/app/utils/use_cuebot_facility.ts Outdated
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.
@ramonfigueiredo

Copy link
Copy Markdown
Collaborator Author

@DiegoTavares / @lithorus
Ready for review!

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant