OrangeTV/docs/vite-fastify-refactor-hando...

252 lines
8.0 KiB
Markdown

# Vite/Fastify Refactor Handoff
Last updated: 2026-06-04
## Current State
The repo has been refactored from a Next.js compatibility migration into a Vite React + TypeScript SPA served by a Fastify runtime.
The intended architecture is now:
- Client: Vite, React 19, TypeScript, React Router, Tailwind CSS 4.
- Server: Fastify on port `3000`, serving both API routes and the SPA on the same origin.
- Dev: Fastify starts the app and mounts Vite middleware for client assets/HMR.
- Production: `pnpm build` writes `dist/client` and `dist/server`, then `pnpm start` runs `dist/server/index.js`.
- Toolchain: Node `v24.14.1` and pnpm `10.14.0`.
- Docker: official `node:24-alpine` image family with pnpm activated through Corepack.
The repo is still dirty and not committed. Treat this as a handoff snapshot before creating the first refactor commit.
## What Is Good
- Next.js runtime/build dependencies have been removed from production code.
- Client Next imports have been replaced with app-native React/Vite equivalents:
- Router behavior uses `react-router-dom` wrappers.
- Image usage no longer depends on `next/image`.
- Theme behavior no longer depends on `next-themes`.
- API routes have been moved to Fastify route modules under `src/server/routes`.
- The generated Next route adapter path has been removed from the runtime direction.
- Fastify handles SPA serving, API registration, auth guards, cookies, static assets, and runtime config.
- React Compiler is configured through the Vite React plugin path using `@vitejs/plugin-react`, `@rolldown/plugin-babel`, and `babel-plugin-react-compiler`.
- Node tooling is now pinned consistently:
- `.nvmrc` is `v24.14.1`.
- `package.json` enforces `node >=24 <25` and `pnpm 10.14.0`.
- `.npmrc` has `engine-strict=true`.
- Docker uses `node:24-alpine`.
- Server bundling targets `node24`.
- Search SSE completion was fixed:
- Shortdrama is included as an invoked async source.
- Completion reaches the expected source count.
- The header text clarifies source progress instead of implying visible card count.
- Aggregated search can still show fewer cards than source count by design.
- Search result cover badges and search-history pill close button were adjusted visually.
- The exact player URL that previously failed was manually confirmed working during the session:
- `http://localhost:3000/play?title=%E6%9C%A8%E4%B9%83%E4%BC%8A&year=2026&stype=movie&source=maotaizy&id=129378`
## Verified
These checks were run with Node `v24.14.1` and pnpm `10.14.0` unless noted.
```bash
node -v
# v24.14.1
pnpm -v
# 10.14.0
```
```bash
pnpm typecheck
# passed
```
```bash
pnpm lint
# passed with warnings
# 0 errors, 287 warnings
```
```bash
pnpm test --runInBand
# passed
# 13 test suites, 30 tests
```
Important: with pnpm `10.14.0`, use `pnpm test --runInBand`. The older-looking form `pnpm test -- --runInBand` forwarded `--` into Jest and caused Jest to treat `--runInBand` as a test pattern.
```bash
pnpm build
# passed
```
```bash
rg "v20|node20|Node 20|node:20|apk add --no-cache nodejs" . \
--glob '!node_modules/**' \
--glob '!dist/**'
# no matches
```
```bash
docker build -t orangetv-refactor-smoke:local .
# passed
```
Docker build details:
- Pulled and used `node:24-alpine`.
- Activated `pnpm@10.14.0` in Docker stages.
- Installed dependencies with the lockfile.
- Ran in-container `pnpm build`.
- Exported image as `orangetv-refactor-smoke:local`.
## Verified Earlier In The Refactor
These checks were done before the final Node 24 pin and are still useful context:
- API route parity check found 63 old app API routes and 63 new Fastify route paths.
- No missing route paths were identified in that comparison.
- No method mismatches were identified in that comparison.
- Static Next production-reference scans found no remaining production `next/*` imports.
- Local dev with Redis was used during debugging.
- Search route and player route issues were reproduced and fixed against the running dev server.
## Known Warnings
`pnpm lint` currently passes but reports 287 warnings. The warning categories are mostly:
- import sorting
- `no-console`
- explicit `any`
- React hook dependency warnings
- unused imports/vars
- non-null assertions
`pnpm test --runInBand` passes but Jest prints an open-handle warning after completion:
- `Jest did not exit one second after the test run has completed.`
`pnpm build` and Docker build pass but include expected build warnings:
- `/runtime-config.js` script in `index.html` cannot be bundled without `type="module"`.
- `tailwind.config.ts` is reparsed as ESM because `package.json` does not declare `"type": "module"`.
- `artplayer-plugin-danmuku` uses CommonJS `module` inside an ESM bundle.
- Some chunks are larger than 500 kB.
- `hls.js` and `artplayer` dynamic imports are ineffective because they are also imported statically elsewhere.
- `@rolldown/plugin-babel` dominates build plugin time.
- Browserslist data is stale.
These warnings existed as non-blocking issues during verification. They should not block the first refactor commit unless release standards require warning cleanup.
## Remaining Gaps
These are the main gaps to address before calling the refactor fully production-ready.
1. Docker runtime smoke was not completed.
- The image builds.
- The container has not yet been run and checked via `/api/health`, login, player page, and admin page.
2. Production runtime smoke is still limited.
- `pnpm build` passes.
- A fresh `pnpm start` smoke with HTTP checks was not run after the final Node 24 pin.
3. Chat/WebSocket parity needs focused review.
- HTTP chat routes exist in the Fastify route tree.
- Full WebSocket behavior should be compared against the old deployment expectations before claiming chat parity.
4. Lint warning debt remains large.
- Lint exits successfully, but the warning count is high.
- A follow-up cleanup pass should decide which warnings are acceptable and which should become errors.
5. Jest open-handle warning remains.
- Tests pass, but async cleanup should be investigated before tightening CI.
6. Bundle-size and import-splitting warnings remain.
- Player-related libraries are large and currently defeat some dynamic imports.
- This is not a correctness blocker, but it is relevant for performance.
7. Browser smoke should be repeated after the final commit candidate.
- Prior manual checks were useful, but a final pass should cover search, detail, play, favorites, play records, admin config, and theme save/load.
8. Git hygiene needs review before commit.
- The worktree includes broad refactor changes plus Node 24 pinning.
- `docs/superpowers/specs/2026-04-09-orangetv-a2-design.md` was already modified outside this handoff task and should be reviewed before staging.
## Important Commands
Local dev:
```bash
pnpm dev
```
Local dev with Redis:
```bash
pnpm dev:redis
```
Production build:
```bash
pnpm build
```
Production start:
```bash
pnpm start
```
Full local verification set:
```bash
node -v
pnpm -v
pnpm typecheck
pnpm lint
pnpm test --runInBand
pnpm build
docker build -t orangetv-refactor-smoke:local .
```
Static checks worth keeping:
```bash
rg "next/|NextRequest|NextResponse|next-env|next.config|eslint-config-next|next-themes|next-pwa" . \
--glob '!node_modules/**' \
--glob '!dist/**'
rg "v20|node20|Node 20|node:20|apk add --no-cache nodejs" . \
--glob '!node_modules/**' \
--glob '!dist/**'
```
## Suggested Next Steps
1. Run the Docker image and smoke it:
```bash
docker run --rm -p 3000:3000 \
-e USERNAME=admin \
-e PASSWORD=orange \
-e VITE_STORAGE_TYPE=redis \
-e REDIS_URL=redis://host.docker.internal:6379 \
orangetv-refactor-smoke:local
```
Then check:
- `GET http://localhost:3000/api/health`
- login as `admin` / `orange` if those env vars are used
- `/search?q=%E6%AD%8C%E6%89%8B2026`
- the known player URL
- `/admin`
2. Run a final browser smoke on `pnpm dev:redis`.
3. Review chat/WebSocket behavior explicitly.
4. Decide whether to clean warnings now or track them as follow-up issues.
5. Stage only the intended refactor files, then create the first refactor commit.