Five live bugs surfaced on console.omantel.biz 2026-05-07:
TC-090..092 /cloud/architecture, /cloud/compute, /cloud/network/ingresses
returned the SPA shell with TanStack Router default 404 in
sovereign mode. The legacy redirects (LEGACY_CLOUD_REDIRECTS)
were only mounted under the mothership /provision/$id/cloud
subtree, never at root for sovereign mode.
TC-160 /notifications returned the SPA shell + 404 because the only
notifications route was /provision/$id/notifications and
NotificationsPage hard-required the URL :deploymentId param
via useParams({ from: '/provision/$deploymentId/notifications' }).
TC-211 /readyz returned the SPA shell (HTTP 200 + index.html)
instead of a real Go-handler probe response, because no
Gateway rule routed it to catalyst-api — nginx try_files
and the SPA catch-all both shadowed the path.
TC-004 /auth/handover with no token returned raw 401 JSON
{"error":"missing token parameter"} to browser visits,
breaking the seamless-handover UX promise for stale
email-link clicks.
Fixes:
* products/catalyst/chart/templates/httproute.yaml — Exact matches
for /readyz and /healthz on the console hostname route to catalyst-api.
External monitors pointing at console.<sov>/readyz now hit the real
Go probe; pod-level k8s probes still hit nginx-internal /healthz.
* products/catalyst/bootstrap/api/internal/handler/auth_handover.go —
Browser visits (Accept: text/html or Sec-Fetch-Mode: navigate) on
the missing-token path 302-redirect to /auth/handover-error?reason=
missing_token. Programmatic callers (Accept: application/json or no
Accept header) keep the legacy 401 JSON contract that the test
matrix pins. New tests cover both branches.
* products/catalyst/bootstrap/ui/src/app/router.tsx — Adds
authHandoverErrorRoute (/auth/handover-error) with a friendly
error surface; consoleNotificationsRoute (/notifications under the
Sovereign console layout); consoleLegacyCloudRedirectRoutes
(sovereign-mode siblings of legacyCloudRedirectRoutes, reusing
LEGACY_CLOUD_REDIRECTS verbatim so the two redirect sets cannot
drift). consoleCloudRoute gains validateSearch matching
provisionCloudRoute.
* products/catalyst/bootstrap/ui/src/pages/sovereign/NotificationsPage.tsx —
Replaces strict useParams({ from: '/provision/$deploymentId/...' })
with useResolvedDeploymentId so the page works on both /provision/$id/
notifications (URL param) and sovereign-mode /notifications
(/api/v1/sovereign/self self-discovery). Mirrors the pattern used by
JobsPage / SettingsPage / Dashboard.
Verification:
helm template products/catalyst/chart — clean
npm run build — clean (1.88MB bundle, vite v8)
npx tsc --noEmit — clean
go build ./... — clean
go test -run TestAuthHandover_MissingToken — PASS (legacy + new HTML branch)
Co-authored-by: hatiyildiz <hatice.yildiz@openova.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>