177 lines
7.4 KiB
Markdown
177 lines
7.4 KiB
Markdown
# 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. Use
|
|
Tailwind CSS v4 and shadcn/ui as the reusable primitive layer for React
|
|
components, but do not vendor the full shadcn registry. Add only primitives
|
|
that map to the dashboard surface.
|
|
|
|
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.
|
|
- `src/lib/components/ui/*.tsx` contains shadcn/ui primitives used by the
|
|
dashboard component library.
|
|
- `components.json` records the shadcn configuration with Vite, Radix, the Nova
|
|
preset, and `$lib` import aliases.
|
|
|
|
## 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 keep the existing design tokens in `src/lib/ui/tokens.css`.
|
|
`src/app.css` imports Tailwind, shadcn CSS, font assets, and the existing
|
|
Dimension Lab token file. shadcn semantic variables must be mapped to the dark
|
|
console palette so generated primitives fit the dashboard instead of resetting
|
|
the app to a light generic theme. 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 `react`, `react-dom`, `@iconify/react`,
|
|
selected shadcn primitive dependencies, Tailwind merge helpers, and existing
|
|
non-Svelte libraries that still apply.
|
|
- Dev dependencies include `@vitejs/plugin-react`, `@tailwindcss/vite`,
|
|
`tailwindcss`, and the shadcn package needed by the generated CSS import.
|
|
- 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.
|
|
- shadcn is configured for Vite/Radix with `$lib` aliases and only selected
|
|
primitives, not the full registry.
|
|
- `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.
|