Files
ersatztv/docs/superpowers/plans/2026-07-02-chicorytv-spa-scaffold-build-integration.md
T
2026-07-02 07:37:00 +02:00

64 lines
3.2 KiB
Markdown

# ChicoryTV SPA Scaffold Build Integration Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Build issue #78: a Vite React TypeScript SPA in `web/`, mounted at `/app`, included in ASP.NET publish output, Docker image builds, and Gitea CI.
**Architecture:** Keep the existing Blazor UI as the root fallback and mount the new SPA under a dedicated `/app` branch. Build `web/` to `ErsatzTV/wwwroot/app` so ASP.NET static file serving and Docker publish both carry the compiled SPA without changing `/iptv/*` or existing API routes.
**Tech Stack:** .NET 10 ASP.NET Core, Vite, React, TypeScript, npm, NUnit static integration tests.
---
### Task 1: Lock the Hosting Contract
**Files:**
- Create: `ErsatzTV.Tests/StartupSpaHostingTests.cs`
- Modify: `ErsatzTV/Startup.cs`
- [ ] Add tests that assert `Startup.cs` has a dedicated `/app` branch, serves `ErsatzTV/wwwroot/app`, falls back to `index.html`, and excludes `/app` from the Blazor branch.
- [ ] Run `dotnet test ErsatzTV.Tests/ErsatzTV.Tests.csproj --filter FullyQualifiedName~StartupSpaHostingTests -v minimal` and confirm the tests fail because the branch is missing.
- [ ] Add the `/app` static file branch before the non-IPTV Blazor branch.
- [ ] Re-run the targeted test and confirm it passes.
### Task 2: Scaffold the SPA
**Files:**
- Create: `web/package.json`
- Create: `web/package-lock.json`
- Create: `web/tsconfig.json`
- Create: `web/tsconfig.node.json`
- Create: `web/vite.config.ts`
- Create: `web/index.html`
- Create: `web/src/main.tsx`
- Create: `web/src/App.tsx`
- Create: `web/src/App.test.tsx`
- Create: `web/src/setupTests.ts`
- Create: `web/src/vite-env.d.ts`
- [ ] Add a React Testing Library test that expects the ChicoryTV placeholder shell to render and the design-system stylesheet to be imported.
- [ ] Run `npm test -- --run` in `web/` and confirm it fails before the app exists.
- [ ] Add the Vite React TypeScript app with `base: "/app/"`, dev proxy entries for `/api`, `/iptv`, and `/artwork`, and output directory `../ErsatzTV/wwwroot/app`.
- [ ] Import `../../design-system/styles.css` from the SPA entrypoint and render a compact placeholder shell.
- [ ] Run `npm ci`, `npm test -- --run`, `npm run lint`, `npm run typecheck`, and `npm run build`.
### Task 3: Wire Build and CI
**Files:**
- Modify: `.gitea/workflows/docker-build.yml`
- Modify: `docker/Dockerfile`
- Modify: `.gitignore`
- [ ] Add CI Node setup and `npm ci`, `npm run lint`, `npm run typecheck`, `npm run build` before the .NET build.
- [ ] Add Docker Node build layers that copy `web/` and `design-system/`, install npm dependencies, and build the SPA before `dotnet publish`.
- [ ] Ignore generated `ErsatzTV/wwwroot/app/` and `web/dist/` while keeping source and lockfiles tracked.
- [ ] Run the targeted .NET test, the web checks, and `dotnet build ErsatzTV/ErsatzTV.csproj --no-restore`.
### Task 4: Finish Issue #78
**Files:**
- Modify as needed based on verification.
- [ ] Run `git status --short` and review the diff.
- [ ] Use the `done` skill for issue #78 before claiming completion.