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.
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)
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 main2026-07-07 11:12:50 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Phase (a) of #91: the ChicoryTV SPA becomes the default UI.
What
LegacyUiRedirectsmap + middleware in the Blazor branch (beforeUseRouting): GET/HEAD to/and 12 legacy Blazor routes with SPA equivalents 302 to/app/..., preserving query strings andETV_BASE_URLpath base (Request.PathBasere-applied —UsePathBasenever rewrites Location headers)./system/health. Parity gaps: #140–#146 (+ escape-hatch follow-up #147). Phase (b) (Blazor/MudBlazor removal) is gated on those./app/serves the SPA (ChicoryTVtitle).Known/accepted
/api/*) was already reachable unauthenticated — no new exposure, but SPA auth remains a phase (b) gap; OIDC-protected Blazor stays at/system/healthand un-redirected routes./, 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)./→302→SPA, all 13 redirects verified (query strings, trailing slash, case-insensitivity), POST unaffected,/system/health+/media/collectionsstill Blazor,/iptv/*+/api/*+/docsintact, SPA client-route fallback works.🤖 Generated with Claude Code