Files
nas-tools/specs/sprint-06-code-quality.md
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

4.7 KiB

Sprint 06 — Code Quality & Refactoring

Depends on: S05 (system must be stable before large refactors) Duration: ongoing (~12h total) Goal: Reorganize frontend/backend structure, add retry logic, clean up networks, consolidate CI, fix SSR safety, remove legacy code.


S06.1 — Reorganize frontend routes into subdirectories

  • Files: dashboard/frontend/src/routes/ (21 files), dashboard/frontend/src/App.svelte

  • Estimate: 3h

  • Done means: Routes grouped: routes/media/, routes/tools/, routes/admin/. App.svelte imports updated. No functional changes.

  • Verify by:

    1. npm run build succeeds
    2. Navigate to every page → all pages load
    3. Frontend tests pass
  • Risk: Update import paths in App.svelte and cross-route references. Do incrementally, one group at a time.

  • S06.1 — Reorganize frontend routes into subdirectories

S06.2 — Implement backend router auto-discovery

  • Files: dashboard/backend/main.py:9-50

  • Estimate: 2h

  • Done means: main.py uses auto-discovery to load routers from routers/ directory instead of 40+ individual imports.

  • Verify by:

    1. All 18 routers still registered (check /docs OpenAPI page)
    2. All integration tests pass
    3. Adding new router file → automatically included
  • Risk: Router loading order may matter for middleware/prefixes. Preserve existing order or make explicit via __init__.py manifest.

  • S06.2 — Implement backend router auto-discovery

S06.3 — Add retry/backoff to Docker container monitor

  • Files: dashboard/backend/routers/docker_router.py

  • Estimate: 2h

  • Done means: Docker API calls have exponential backoff (1s, 2s, 4s, max 30s) with 3 retries. Timeouts no longer crash the monitor.

  • Verify by:

    1. Temporarily pause docker-socket-proxy → Docker page shows "reconnecting..." not error
    2. Resume proxy → containers load automatically
    3. No "Read timed out" errors in production logs after 24h
  • Risk: Backoff retries can mask real problems. Log each retry at WARNING level.

  • S06.3 — Add retry/backoff to Docker container monitor

S06.4 — Clean up Docker networks

  • Files: dashboard/docker-compose.yml, dashboard/docker-compose.dev.yml

  • Estimate: 1.5h

  • Done means: Unused networks removed. Remaining networks documented. Network naming standardized.

  • Verify by:

    1. docker network ls on NAS → only in-use networks exist
    2. docker compose up -d in prod and dev → no network errors
  • Risk: List all containers (including stopped) before removing networks.

  • S06.4 — Clean up Docker networks

S06.5 — Consolidate CI workflows (DRY)

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

  • Estimate: 3h

  • Done means: Shared steps extracted. If Gitea Actions lacks composite actions, at minimum standardize patterns across all three files.

  • Verify by:

    1. All three workflows still run correctly
    2. Changing a shared step updates all workflows
    3. Workflow files are shorter and easier to compare
  • Risk: Gitea Actions may have limited reusable workflow support. Verify before investing time.

  • S06.5 — Consolidate CI workflows (DRY)

S06.6 — Guard window.isSecureContext in Login.svelte

  • Files: dashboard/frontend/src/routes/Login.svelte:11

  • Estimate: 0.5h

  • Done means: window.isSecureContext check inside onMount or guarded with typeof window !== 'undefined'. SSR-safe.

  • Verify by:

    1. Build with SSR enabled → no crash
    2. Normal SPA build → login page works as before
  • Risk: None. onMount only runs in browser.

  • S06.6 — Guard window.isSecureContext in Login.svelte

S06.7 — Remove legacy localStorage refresh token read

  • Files: dashboard/frontend/src/lib/api.js:27

  • Estimate: 0.5h

  • Done means: Legacy localStorage.getItem("refresh_token") removed or documented with explicit comment.

  • Verify by:

    1. Login → token refresh works via cookies only
    2. Clear cookies → redirect to login (no localStorage fallback)
    3. Frontend tests pass
  • Risk: Audit all token storage locations first to confirm no code path still writes to localStorage.

  • S06.7 — Remove legacy localStorage refresh token read


Exit criteria

  • Frontend routes organized in subdirectories
  • Backend uses router auto-discovery
  • Docker monitor retries with backoff (no crashes on timeout)
  • Only in-use Docker networks remain
  • CI workflows are DRY (or documented why they can't be)
  • Login.svelte is SSR-safe
  • No legacy localStorage refresh token logic (or clearly documented)
  • All backend tests pass
  • All frontend tests pass
  • npm run build succeeds