Files
nas-tools/specs/sprint-01-production-stability.md
T
Gan, Jimmy ddaf3c6cee security: Sprint 00 — critical security fixes (OPC WS auth, Transmission creds, SECRET_KEY, passkey rate limit)
- Add JWT token auth to OPC WebSocket (unauthenticated → 403, per-user tracking)
- Externalize Transmission RPC credentials to TRANSMISSION_USER/PASS env vars
- Remove hardcoded SECRET_KEY fallback from dev compose
- Rate-limit passkey register options endpoint at 5/minute
- Add PDD (docs/improvement-plan.md) and sprint specs (specs/)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-03 13:31:25 +08:00

3.9 KiB

Sprint 01 — Production Stability

Depends on: S00 (critical security fixes) Duration: ~6h Goal: Restore dev deployment, add test gates, fix broken UI states and inaccurate system data.


S01.1 — Fix dev deploy runner label

  • Files: .gitea/workflows/deploy-dev.yml:15

  • Estimate: 0.5h

  • Done means: runs-on: nas instead of runs-on: ubuntu-latest. CI deploy to dev succeeds.

  • Verify by: Push a trivial change to dev → workflow runs on nas runner → deploy succeeds → curl http://nas:4001/api/health returns 200

  • Risk: None — this is the same runner used by deploy.yml and deploy-claude-dev-dev.yml.

  • S01.1 — Fix dev deploy runner label

S01.2 — Add test gate to dev deploy

  • Files: .gitea/workflows/deploy-dev.yml

  • Estimate: 2h

  • Done means: deploy-dev.yml has backend-tests and frontend-tests jobs that must pass before the deploy job runs (via needs). Same test pattern as deploy.yml.

  • Verify by:

    1. Push code with failing test → tests fail → deploy job skipped
    2. Push code with passing tests → tests pass → deploy proceeds
    3. Workflow summary in Gitea UI shows test→deploy dependency clearly
  • Risk: Adds 2-3 minutes to dev deploy cycle. Acceptable trade-off for safety.

  • S01.2 — Add test gate to dev deploy

S01.3 — Add error handling to Docker.svelte

  • Files: dashboard/frontend/src/routes/Docker.svelte:12-15

  • Estimate: 1h

  • Done means: API errors in load() are caught. UI shows error state with message and retry button instead of blank page or crash. Same pattern applied to action() and showLogs().

  • Verify by:

    1. Stop docker-socket-proxy → navigate to Docker page → see error message "Docker API unavailable" + retry button
    2. Start docker-socket-proxy → click retry → containers load
    3. During normal operation → no regression (page works as before)
  • Risk: Low. Add let error = $state("") and an {#if error} block in the template. Keep existing loading state.

  • S01.3 — Add error handling to Docker.svelte

S01.4 — Fix cpu_percent always returning 0

  • Files: dashboard/backend/routers/system.py:53

  • Estimate: 0.5h

  • Done means: First call to /api/system/stats returns accurate CPU percentage (non-zero under load).

  • Verify by:

    1. Restart dashboard backend
    2. Run stress --cpu 1 on the NAS
    3. Call /api/system/statscpu_percent > 0
    4. Stop stress → next call shows lower value
  • Risk: psutil.cpu_percent(interval=0.1) blocks the request for 100ms. This is acceptable for a system stats endpoint. Alternative: call cpu_percent() once at startup (in lifespan) to prime the counter, then use interval=0 in the endpoint.

  • S01.4 — Fix cpu_percent always returning 0

S01.5 — Verify production docker-socket-proxy

  • Files: dashboard/docker-compose.yml

  • Estimate: 2h

  • Done means: Production docker-socket-proxy container is running and healthy. Docker API calls from dashboard succeed without timeouts.

  • Verify by:

    1. ssh nas "cd /volume1/docker/nas-dashboard && docker compose ps" → docker-socket-proxy shows "Up" and "healthy"
    2. Navigate to Docker page in production dashboard → containers load within 5 seconds
    3. Monitor /api/docker/containers response time → < 2 seconds
  • Risk: If docker-socket-proxy needs to be created from scratch, ensure the compose file defines it correctly.

  • S01.5 — Verify production docker-socket-proxy


Exit criteria

  • Push to dev → CI deploys successfully on nas runner
  • Failing test blocks dev deploy
  • Docker page shows error state when API unavailable (not blank/crash)
  • /api/system/stats reports non-zero CPU under load
  • Production Docker page loads containers within 5 seconds
  • All backend tests pass
  • All frontend tests pass