feat(web): SPA cutover — root route (#91) #148

Merged
timothy merged 1 commits from feat/91-cutover into main 2026-07-07 11:12:50 +02:00
Owner

Phase (a) of #91: the ChicoryTV SPA becomes the default UI.

What

  • New LegacyUiRedirects map + middleware in the Blazor branch (before UseRouting): GET/HEAD to / and 12 legacy Blazor routes with SPA equivalents 302 to /app/..., preserving query strings and ETV_BASE_URL path base (Request.PathBase re-applied — UsePathBase never rewrites Location headers).
  • 302 not 301 deliberately: the map grows as parity lands; permanent-redirect caching would make rollback painful.
  • Blazor-only functionality keeps serving Blazor (collections, media browse/search, trakt, filler, watermarks, ffmpeg profiles, blocks/decos/templates, playout detail editors, logs, troubleshooting, channel edit). Blazor home stays reachable at /system/health. Parity gaps: #140–#146 (+ escape-hatch follow-up #147). Phase (b) (Blazor/MudBlazor removal) is gated on those.
  • Docker smoke test now also asserts /app/ serves the SPA (ChicoryTV title).

Known/accepted

  • OIDC installs: the default landing page changes from "challenged Blazor page" to the SPA, which (like all GET /api/*) was already reachable unauthenticated — no new exposure, but SPA auth remains a phase (b) gap; OIDC-protected Blazor stays at /system/health and un-redirected routes.
  • During startup (search index migrating), Blazor's pre-existing not-ready gate 302s non-root pages to /, which now bounces on to /app — users see the SPA instead of the Blazor splash. Pre-existing behavior, verified not caused by this diff.

Verification

  • ErsatzTV.Tests: 527 green (495 baseline + 32 new redirect tests).
  • Live-E2E on a fresh server: /→302→SPA, all 13 redirects verified (query strings, trailing slash, case-insensitivity), POST unaffected, /system/health + /media/collections still Blazor, /iptv/* + /api/* + /docs intact, SPA client-route fallback works.
  • Reviewed by 3 lenses (correctness fork, contract/tests, routing UX) + verification fork over the fix diff.

🤖 Generated with Claude Code

Phase (a) of #91: the ChicoryTV SPA becomes the default UI. **What** - New `LegacyUiRedirects` map + middleware in the Blazor branch (before `UseRouting`): GET/HEAD to `/` and 12 legacy Blazor routes with SPA equivalents 302 to `/app/...`, preserving query strings and `ETV_BASE_URL` path base (`Request.PathBase` re-applied — `UsePathBase` never rewrites Location headers). - 302 not 301 deliberately: the map grows as parity lands; permanent-redirect caching would make rollback painful. - Blazor-only functionality keeps serving Blazor (collections, media browse/search, trakt, filler, watermarks, ffmpeg profiles, blocks/decos/templates, playout detail editors, logs, troubleshooting, channel edit). Blazor home stays reachable at `/system/health`. Parity gaps: #140–#146 (+ escape-hatch follow-up #147). Phase (b) (Blazor/MudBlazor removal) is gated on those. - Docker smoke test now also asserts `/app/` serves the SPA (`ChicoryTV` title). **Known/accepted** - OIDC installs: the default landing page changes from "challenged Blazor page" to the SPA, which (like all GET `/api/*`) was already reachable unauthenticated — no new exposure, but SPA auth remains a phase (b) gap; OIDC-protected Blazor stays at `/system/health` and un-redirected routes. - During startup (search index migrating), Blazor's pre-existing not-ready gate 302s non-root pages to `/`, which now bounces on to `/app` — users see the SPA instead of the Blazor splash. Pre-existing behavior, verified not caused by this diff. **Verification** - `ErsatzTV.Tests`: 527 green (495 baseline + 32 new redirect tests). - Live-E2E on a fresh server: `/`→302→SPA, all 13 redirects verified (query strings, trailing slash, case-insensitivity), POST unaffected, `/system/health` + `/media/collections` still Blazor, `/iptv/*` + `/api/*` + `/docs` intact, SPA client-route fallback works. - Reviewed by 3 lenses (correctness fork, contract/tests, routing UX) + verification fork over the fix diff. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
timothy added 1 commit 2026-07-07 11:07:27 +02:00
feat(web): SPA cutover — root route + legacy redirects (#91)
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m11s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 4m31s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
439272b405
Make the ChicoryTV SPA the default UI: GET/HEAD requests to / and to
legacy Blazor routes with SPA equivalents (channels, schedules,
playouts, libraries, all settings pages, channel add) now 302 to their
/app counterparts, preserving query strings and the ETV_BASE_URL path
base. 302 not 301: the map will grow as parity lands and permanent-
redirect caching would make rollback painful.

Blazor-only functionality (collections, media browse/search, trakt,
filler presets, watermarks, ffmpeg profiles, blocks/decos/templates,
playout detail editors, logs, troubleshooting, channel edit) keeps
serving Blazor; the Blazor home stays reachable at /system/health.
Parity gaps are tracked in #140-#146; Blazor removal is phase (b).

Also adds an /app smoke assertion to the docker build workflow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
timothy merged commit d04769ccdb into main 2026-07-07 11:12:50 +02:00
Sign in to join this conversation.