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

8.0 KiB

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.

node -v
# v24.14.1

pnpm -v
# 10.14.0
pnpm typecheck
# passed
pnpm lint
# passed with warnings
# 0 errors, 287 warnings
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.

pnpm build
# passed
rg "v20|node20|Node 20|node:20|apk add --no-cache nodejs" . \
  --glob '!node_modules/**' \
  --glob '!dist/**'
# no matches
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:

pnpm dev

Local dev with Redis:

pnpm dev:redis

Production build:

pnpm build

Production start:

pnpm start

Full local verification set:

node -v
pnpm -v
pnpm typecheck
pnpm lint
pnpm test --runInBand
pnpm build
docker build -t orangetv-refactor-smoke:local .

Static checks worth keeping:

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:
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
  1. Run a final browser smoke on pnpm dev:redis.

  2. Review chat/WebSocket behavior explicitly.

  3. Decide whether to clean warnings now or track them as follow-up issues.

  4. Stage only the intended refactor files, then create the first refactor commit.