feat(dashboard): align contracts and production build
This commit is contained in:
1 parent
69d560d5c5
commit
d6d29badcd
9 files changed
+189
-48
No files matched your search
@@ -0,0 +1,102 @@
|
||||
# React Dashboard Migration
|
||||
|
||||
## Outcome
|
||||
|
||||
Replace the inline dashboard in `public/index.html` with a typed, accessible React
|
||||
application without disrupting the bot worker or its Express API. Express remains
|
||||
the authenticated API, SSE, private-media, and static-asset host.
|
||||
|
||||
The migration is complete only when the legacy dashboard can be removed without
|
||||
losing a documented capability and the full test, type-check, production-build,
|
||||
browser-acceptance, authentication, private-media, and reconnect gates pass.
|
||||
|
||||
## Architecture
|
||||
|
||||
- `apps/dashboard`: React, TypeScript, Vite, React Router, and TanStack Query.
|
||||
- `packages/api-contracts`: shared Zod schemas for HTTP and realtime transport.
|
||||
- `src/web`: existing Express host, gradually adapted to the shared contracts.
|
||||
- Backend service and database types stay private to the backend. Transport
|
||||
contracts must not expose database rows as an accidental public API.
|
||||
- Server state lives in TanStack Query. Route, filter, and selection state lives
|
||||
in URLs. Local component state is reserved for ephemeral presentation state.
|
||||
- Do not add a global client-state library until a demonstrated cross-feature
|
||||
state requirement cannot be met by those boundaries.
|
||||
|
||||
## Navigation
|
||||
|
||||
The application shell provides a responsive sidebar or drawer with these routes:
|
||||
|
||||
| Route | Responsibility |
|
||||
| --- | --- |
|
||||
| `/` | Health, metrics, timers, limits, and important recent activity |
|
||||
| `/conversations` | Searchable conversation inbox |
|
||||
| `/conversations/:id` | Conversation history, context, suggestions, and sending |
|
||||
| `/media` | Private blurred-by-default gallery and sync controls |
|
||||
| `/performance` | Trends, strategies, subreddits, and successful examples |
|
||||
| `/operations` | Domain activity, background jobs, and diagnostics |
|
||||
| `/operations/logs` | Filterable bounded realtime technical console |
|
||||
| `/settings/*` | Monitoring, limits, behaviour, AI, and access settings |
|
||||
|
||||
The shell always surfaces bot state, dry-run state, Reddit session state,
|
||||
realtime connection state, cooldowns, active sync progress, notifications, and
|
||||
the guarded start/stop control.
|
||||
|
||||
## Realtime model
|
||||
|
||||
HTTP snapshots are authoritative. A typed SSE event stream updates or invalidates
|
||||
the relevant query cache. Every event has an ID, type, occurrence timestamp, and
|
||||
validated payload. The stream supports bounded replay and `Last-Event-ID` resume.
|
||||
After reconnection the client refetches authoritative snapshots to repair gaps.
|
||||
|
||||
Required event families are bot status, message sent or failed, conversation
|
||||
updated, reply received, sync lifecycle and progress, rate-limit state, Reddit
|
||||
session state, and technical logs.
|
||||
|
||||
Important domain events appear in a readable activity timeline. Raw logs remain
|
||||
in Operations. Toasts are reserved for user-triggered outcomes requiring timely
|
||||
feedback. Realtime disconnection never blanks cached content; it marks it stale
|
||||
and falls back to visibility-aware polling where necessary.
|
||||
|
||||
## Feature slices
|
||||
|
||||
1. Capture and validate existing HTTP contracts and critical legacy journeys.
|
||||
2. Add the frontend build, application shell, authentication handling, routing,
|
||||
error boundaries, design tokens, query client, and test harness.
|
||||
3. Deliver Overview as the first production vertical slice.
|
||||
4. Add the typed realtime event core, SSE transport, reconnection, and query
|
||||
invalidation.
|
||||
5. Migrate Conversations, including explicit suggestion and send mutations.
|
||||
6. Migrate Media, preserving authentication and blur-by-default privacy.
|
||||
7. Migrate Performance with sample sizes and low-confidence warnings.
|
||||
8. Migrate Operations, access/login, and route-backed validated Settings.
|
||||
9. Run feature parity and security audits, switch Express to the Vite output,
|
||||
remove the legacy HTML, and update operator and deployment documentation.
|
||||
|
||||
Each slice must be usable independently and must not require a flag-day rewrite.
|
||||
The legacy dashboard remains available until replacement behavior is proven.
|
||||
|
||||
## Engineering gates
|
||||
|
||||
- New behavior follows red-green-refactor with Vitest.
|
||||
- Component tests use Testing Library and test observable behavior.
|
||||
- HTTP tests use a controlled boundary such as MSW rather than mocking `fetch`
|
||||
throughout feature tests.
|
||||
- Contract tests prove representative current responses parse and malformed
|
||||
payloads fail.
|
||||
- Realtime tests cover ordering, replay, duplicate handling, reconnection, and
|
||||
cache repair.
|
||||
- Browser tests cover authentication, start/stop, conversation inspection,
|
||||
sending confirmation, sync, settings persistence, and private media.
|
||||
- Interactive controls are keyboard accessible and restore focus after dialogs.
|
||||
- No production frontend or backend code uses `any` or `console.log`.
|
||||
- Mutations display the confirmed server outcome and do not rely on optimistic
|
||||
success for operational controls.
|
||||
- Production builds are deterministic and the Docker image serves only generated
|
||||
frontend assets plus authenticated private content.
|
||||
|
||||
## Cutover evidence
|
||||
|
||||
Before deleting `public/index.html`, record evidence for every legacy capability,
|
||||
all API and SSE authentication paths, private media access, container restart and
|
||||
SSE recovery, responsive navigation, frontend type-check/build, backend build,
|
||||
the complete Vitest suite, and the critical Playwright journeys.
|
||||
Reference in new issue
Block a user