docs: define react runtime migration

This commit is contained in:
vince 2026-06-19 23:21:09 +02:00
parent e0a34f7f2f
commit ef9715c5a6

View file

@ -0,0 +1,163 @@
# React Runtime Migration Design
## Context
The current Dimension Lab website is a SvelteKit application. It uses Bun,
Vite, Svelte 5, SvelteKit server routes, Svelte Storybook stories, and
Svelte SSR component tests. The app has one dashboard route, one agent
configuration API route, reusable Svelte UI components, typed dashboard model
data, Drizzle-backed SQLite persistence, datasource resolution, Playwright
desktop/mobile checks, and a Bun-based container runtime.
The migration goal is to make the project React-based so dashboard UI
components can be reused outside the current app. A partial React island inside
SvelteKit would leave the app split across two component systems, so the target
state is a React runtime and React component library.
## Target Architecture
Use Vite React for the browser app and a small Bun HTTP server for production
runtime. This keeps the existing Bun SQLite persistence model and avoids adding
a heavier React framework where the current route/API surface is small.
The migrated app will have these boundaries:
- `src/main.tsx` mounts the React application in the browser.
- `src/App.tsx` owns dashboard loading, refresh timing, document-to-UI mapping,
and non-ready dashboard states.
- `src/server/index.ts` serves the Vite build output in production and exposes
JSON API routes.
- `src/server/routes/dashboard.ts` loads the dashboard runtime and resolves live
datasources unless `DISABLE_LIVE_DATASOURCES=1`.
- `src/server/routes/agent-dashboard.ts` delegates POST requests to the existing
`handleAgentDashboardRequest` function.
- `src/lib/model/**`, `src/lib/server/db/**`, `src/lib/server/dashboard.ts`,
`src/lib/server/datasources/**`, and `src/lib/server/agent-config/**` remain
TypeScript business logic with minimal import-path updates.
- `src/lib/ui/components/*.tsx` contains the reusable React component library.
- `src/lib/ui/stories/*.stories.tsx` contains React Storybook stories.
## Component Migration
Every current Svelte UI component will be ported to React with typed props:
- Badge
- Button
- CornerBracketFrame
- DashboardFrame
- DashboardHeader
- DiagonalStripeField
- FooterCell
- FooterStatusCell
- GridFrame
- IconButton
- IconGlyph
- LineChart
- ModuleCard
- Panel
- ProgressMeter
- ScanlineField
- Separator
- ServiceGroupPanel
- ServicePanel
- ServiceRow
- SignalTrace
- Sparkline
- StatusBadge
- StatusStrip
- SystemState
- TelemetryCard
- TelemetryGrid
- TelemetryStrip
- WeatherModule
The visual design, CSS custom property tokens, accessibility attributes,
data-model identifiers, severity attributes, focusable links, reduced-motion
behavior, and screenshot-tested dashboard layout must stay equivalent to the
current Svelte implementation.
CSS will remain in `src/lib/ui/tokens.css` and component-specific CSS files.
React components should import their own CSS modules or regular CSS files in a
consistent local pattern. Shared UI types and `dashboardDocumentToUiDashboard`
remain framework-agnostic TypeScript.
## Runtime And API Behavior
The React app will fetch `GET /api/dashboard` on page load. When the runtime
state is ready, the response includes the dashboard document and metadata. When
the runtime state is empty, loading, or invalid, the React app renders the same
state shell that the Svelte page currently renders.
Ready dashboard documents use `metadata.refreshIntervalSeconds` to schedule a
refresh. The React implementation will clear old timers when the dashboard
state changes and on unmount.
The existing agent configuration endpoint remains available at
`POST /api/agent/dashboard`. The request validation, token authorization,
preview, publish, rollback, JSON patch behavior, and persistence behavior remain
owned by `src/lib/server/agent-config/index.ts`.
## Build, Storybook, And Deployment
`package.json` will move from Svelte/SvelteKit dependencies to React tooling:
- Runtime dependencies include `@vitejs/plugin-react`, `react`, `react-dom`,
`@iconify/react`, and existing non-Svelte libraries that still apply.
- Storybook moves from `@storybook/sveltekit` and Svelte CSF to
`@storybook/react-vite`.
- `svelte.config.js`, `src/app.html`, `src/routes/**`, and `.svelte` files are
removed after equivalent React/server files exist.
The production build still creates `build/index.js` as the Bun server entry so
the current container command remains:
```sh
DATABASE_URL=file:/data/dimensionlab.sqlite HOST=0.0.0.0 PORT=3000 bun build/index.js
```
The `Containerfile` continues to install with Bun, build with Bun, copy the
client/server build output plus `drizzle/`, and run the Bun server.
## Testing Strategy
The migration is verified with equivalent or stronger tests:
- TypeScript check covers React TSX, server modules, and shared model code.
- Current model, validation, database, datasource, and agent-config unit tests
remain in place.
- Svelte SSR component tests become React `react-dom/server` tests.
- Page rendering tests become React app/server response tests.
- Storybook boundary tests are updated to require React story files and continue
preventing Dimension Lab-specific content in reusable presentation stories.
- Playwright desktop/mobile tests continue to run against the production Bun
server and the built React app.
- The full QA gate remains `bun run test:qa`.
## Completion Criteria
The migration is complete only when current evidence proves all of these:
- There are no `.svelte` app, component, route, or story files left.
- `package.json` has no Svelte, SvelteKit, or Svelte Storybook dependencies.
- `bun run check` passes.
- `bun run test:unit` passes.
- `bun run build` produces the React client build and Bun server entry.
- `bun run build-storybook` passes with React stories.
- `bun run test:e2e` passes on desktop and mobile.
- The dashboard renders from the same validated dashboard model data.
- `POST /api/agent/dashboard` still exercises the existing agent config logic.
- The production container still runs with `bun build/index.js`.
## Migration Approach
The work should be implemented in focused commits on `codex/react-migration`:
1. Establish React/Vite/Bun server scaffolding and tests while keeping the
current Svelte code available for reference.
2. Port reusable UI components to React and update render tests.
3. Port the dashboard app route and refresh behavior to React.
4. Port Storybook stories and presentation boundary tests to React.
5. Remove SvelteKit runtime files and dependencies.
6. Update build, e2e, README, and container behavior.
7. Run the full QA gate, push the branch, open a ready PR, perform independent
review, fix blockers, and merge only after checks and review pass.