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>
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user