103 lines
5.1 KiB
Markdown
103 lines
5.1 KiB
Markdown
# 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.
|