Wave 5 focuses on security hardening, observability, developer experience, and frontend polish — building on the foundation laid in Wave 4.
- Security: payload validation, input sanitisation, auth improvements
- Observability: time-series metrics, structured logging, alerting hooks
- Backend: missing endpoints, caching, reconciliation improvements
- Frontend: metrics visualisation, accessibility, error boundaries
- Testing: coverage gaps, integration tests, property-based tests
- Infra: rate limit tuning, deployment docs, CI coverage gates
| Area | Files Targeted |
|---|---|
| Backend Core | backend/src/index.ts, backend/src/apiErrors.ts |
| Backend Services | backend/src/services/metricsHistory.ts, backend/src/services/stats.ts |
| Backend Services | backend/src/services/cache.ts, backend/src/services/reconciliationJob.ts |
| Validation | backend/src/validation/schemas.ts |
| Frontend Hooks | frontend/src/hooks/useMetricsHistory.ts, frontend/src/hooks/useStats.ts |
| Frontend Components | frontend/src/components/StreamMetricsChart.tsx, frontend/src/components/StatsPanel.tsx |
| Frontend Components | frontend/src/components/ErrorBoundary.tsx, frontend/src/components/Toast.tsx |
| Infra | .github/workflows/backend-ci.yml, .github/workflows/frontend-ci.yml |
Issues are grouped by theme and tagged with labels: wave5, security, backend, frontend, testing, infra, observability.
- Request body size limit (
express.json({ limit: '32kb' })) with 413/400 error responses - Sanitise string inputs (strip null bytes, control characters) in Zod schemas
- Add
helmetmiddleware for security headers (CSP, HSTS, X-Frame-Options) - Enforce
Content-Type: application/jsonon all mutation endpoints - CORS origin allowlist via
ALLOWED_ORIGINSenv var (replace opencors()) - JWT
audandissclaim validation inauthMiddleware - Rotate JWT secret without downtime (dual-secret grace period)
- Admin endpoint authentication audit — ensure all
adminAuthroutes are tested
-
GET /api/metrics/history?days=N— daily aggregate time-series endpoint (max 90 days, 5-min TTL cache) - Wire
GET /api/statsroute togetStreamStats()fromstats.ts - Add
collectDefaultMetrics()to Prometheus registry inmetrics.ts - Structured JSON logging (replace
console.logwith a logger likepino) - Log request duration in
requestLoggermiddleware - Expose cache hit/miss counters as Prometheus metrics
- Alert threshold config for indexer lag (ledger sequence delta)
- Health endpoint extended: include DB status, indexer lag, cache connectivity
-
GET /api/streams/:id/progress— real-time vesting progress snapshot -
GET /api/streams/stats/summary— aggregate counts by status - Cursor-based pagination on
GET /api/events(replace offset for large datasets) - Configurable reconciliation interval via env var (already partially done)
- Reconciliation job: emit metrics on drift count and correction count
-
streamStore.ts: add index onstreams(sender)andstreams(recipient)for large datasets - Cache
listStreamsresults with short TTL (invalidate on mutation) - Graceful shutdown: drain in-flight requests before
process.exit -
POST /api/streams/:id/archive— explicit archive endpoint (vs. background job only) - Validate
ALLOWED_ASSETSenv var on startup (non-empty, valid asset codes)
- Connect
useMetricsHistoryhook to realGET /api/metrics/historyendpoint -
StreamMetricsChart: render dailyactiveStreamsandtotalVestedas dual-axis line chart -
StatsPanel: display live aggregate stats fromGET /api/stats - Global
ErrorBoundarycomponent wrapping the app root - Retry button in error states (streams list, metrics chart)
- Skeleton loaders for
StreamsTableandStatsPanelduring initial fetch - Accessible colour contrast audit (WCAG AA) on dark mode palette
- Keyboard navigation for
StreamsTablerow actions (cancel, pause, resume) -
aria-liveregion for toast notifications - Persist selected asset filter in URL query params (
?asset=USDC) - Export button: trigger CSV download from
GET /api/streams/export.csv - Stream detail page: show event history timeline using
GET /api/streams/:id/history
- Backend: integration test for 413 response on oversized JSON body
- Backend: integration test for 400 response on malformed JSON body
- Backend: unit tests for
getMetricsHistorywith mocked DB - Backend: unit tests for
getStreamStatscache invalidation - Backend: property-based tests for pagination (arbitrary page/limit combos)
- Frontend: test
useMetricsHistoryhook with MSW mock for/api/metrics/history - Frontend: test
StreamMetricsChartrenders correct number of data points - Frontend: test
ErrorBoundarycatches render errors and shows fallback UI - CI: enforce minimum 70% line coverage gate on backend (
--coverage.thresholds.lines=70) - CI: enforce minimum 60% line coverage gate on frontend
- Add
@vitest/coverage-v8coverage step tobackend-ci.yml - Add coverage step to
frontend-ci.yml - Upload coverage reports to Codecov (or equivalent) from CI
- Docker: add
HEALTHCHECKinstruction to backenddockerfile - Docker: non-root user in backend container
-
DEPLOYMENT.md: documentREDIS_URLenv var and cache behaviour -
DEPLOYMENT.md: documentMETRICS_AUTHenv var for Prometheus scrape auth - Dependabot config for automated dependency updates