# Turbo Component Library Migration Design ## Context The current Dimension Lab website is a single Bun/Vite React package. It owns the browser app, Bun production server, dashboard model, persistence, datasource adapters, reusable UI components, Storybook, Playwright checks, and container deployment from one `package.json`. The UI components are already mostly generic and content-free under `src/lib/ui`, but they are not reusable by another project because they live inside the app package, depend on app path aliases, and share the app build, test, and Storybook configuration. One file in that area, `src/lib/ui/model-renderer.ts`, imports the Dimension Lab dashboard model and therefore is an app adapter, not reusable component-library code. The migration goal is to turn the repository into a Turborepo workspace where the Dimension Lab website consumes a separate reusable React component package. ## Target Repository Shape Use one application workspace and one component-library workspace: ```text . ├── apps/ │ └── web/ │ ├── src/ │ ├── tests/ │ ├── drizzle/ │ ├── Containerfile │ └── package.json ├── packages/ │ └── ui/ │ ├── src/ │ ├── .storybook/ │ ├── package.json │ └── tsconfig.json ├── package.json ├── turbo.json ├── tsconfig.base.json └── bun.lock ``` The root package is private and contains only workspace orchestration: workspaces, Turbo scripts, shared dev dependencies where useful, and the lock file. Runtime dependencies belong to the workspace that imports them. ## Package Ownership `packages/ui` is a compiled React library named `@dimensionlab/ui`. It owns: - Reusable React components currently under `src/lib/ui/components`. - UI CSS tokens and component styles. - Theme helpers currently under `src/lib/ui/theme.ts`. - Generic UI prop/data types currently under `src/lib/ui/types.ts`. - Generic formatting helpers currently under `src/lib/ui/format.ts`. - Generic Storybook stories and story fixtures. - UI render tests, boundary tests, and Storybook inventory tests. It must not import from the website app, the dashboard model, server modules, database modules, datasource modules, or deployment files. The library publishes explicit package exports: - `@dimensionlab/ui` for component and type exports. - `@dimensionlab/ui/styles.css` for the combined token/component CSS entry. - Optional explicit subpath exports for future direct imports where useful. The compiled output goes to `packages/ui/dist` and includes JavaScript, declaration files, and copied CSS. The package stays private for now but is structured so it can later be published or moved into another Dimension Lab repo without taking the website runtime with it. `apps/web` owns: - The Vite React browser app. - The Bun production server and API routes. - Dashboard model, fixtures, schema, validation, and model migrations. - Drizzle/SQLite persistence and checked-in SQL migrations. - Datasource adapters and runtime dashboard loading. - Agent dashboard configuration endpoint. - The `dashboardDocumentToUiDashboard` adapter that maps the app model to UI package props. - Playwright e2e tests and deployment container. ## Why A Compiled Package The component package should be compiled rather than a just-in-time source package. This is slightly more setup, but it better fits reuse outside the current app because consumers can import stable JavaScript and declarations instead of relying on their bundler to transpile this repo's TypeScript source. It also gives Turbo a cacheable `@dimensionlab/ui#build` task. ## Build And Task Graph Root scripts delegate through Turbo: - `bun run dev` runs the web dev server and any required dependency tasks. - `bun run build` runs package builds in dependency order. - `bun run check` runs TypeScript checks for all workspaces. - `bun run test:unit` runs Vitest unit tests for all workspaces. - `bun run build-storybook` builds Storybook from `packages/ui`. - `bun run test:e2e` runs the web app Playwright suite. - `bun run test:qa` is the full release gate. `turbo.json` defines `build`, `check`, `test:unit`, `build-storybook`, `test:e2e`, and `test:qa` tasks. Build outputs include `dist/**`, `storybook-static/**`, and `build/**` as appropriate. The web app depends on `@dimensionlab/ui` using Bun workspace syntax. The web Vite config aliases `$lib` to `apps/web/src/lib`; the UI package should not use that app alias. ## Storybook Storybook moves with the component package. It should load `@dimensionlab/ui/styles.css`, use React Vite Storybook, and keep the existing generic story inventory. Environment-specific Dimension Lab labels, hostnames, links, fallback values, and datasource names remain forbidden in package UI source and stories. The repository should no longer have a root Storybook tied to the web app. ## Deployment The deployed website remains the same service from the outside: - Production command remains `bun build/index.js` inside the runtime image. - The container still exposes port `3000` and mounts `/data`. - Runtime environment variables and database behavior remain unchanged. The `Containerfile` moves to `apps/web/Containerfile` or remains root with updated workspace-aware copy/build steps. The chosen layout must preserve the existing Podman service contract used by `dimensionlab-website.service`. ## Testing Strategy The migration must add or update tests that prove the new boundaries: - The root package is a Bun workspace with `apps/*` and `packages/*`. - The web app imports UI from `@dimensionlab/ui`, not from local copied component files. - `packages/ui` does not import from `apps/web`, `$lib/server`, `$lib/model`, or any website runtime module. - `dashboardDocumentToUiDashboard` lives in `apps/web` and is tested there. - Storybook inventory is evaluated against `packages/ui`. - The full QA gate still covers typecheck, unit tests, app build, Storybook build, and Playwright desktop/mobile checks. ## Completion Criteria The migration is complete only when current evidence proves all of these: - Root `package.json` is a private workspace root with Turbo scripts. - `turbo.json` exists and models the workspace task graph. - The web application lives under `apps/web`. - The reusable React component library lives under `packages/ui`. - `packages/ui/package.json` is named `@dimensionlab/ui` and has compiled exports for code, types, and CSS. - The web app depends on `@dimensionlab/ui` through the workspace. - Reusable components and Storybook have been removed from the web app package. - App-specific model/server/database/datasource code has not moved into `packages/ui`. - `dashboardDocumentToUiDashboard` is outside the UI package. - `bun run check` passes from the root. - `bun run test:unit` passes from the root. - `bun run build` passes from the root. - `bun run build-storybook` passes from the root. - `bun run test:e2e` passes from the root. - The production container can still be built and run with the same service contract. ## Migration Approach Implement this on branch `codex/turbo-component-library` in focused commits: 1. Add the workspace/Turbo scaffolding and boundary tests. 2. Move UI code and Storybook to `packages/ui`. 3. Move the app runtime into `apps/web` and wire it to `@dimensionlab/ui`. 4. Move the model-to-UI adapter into the web app. 5. Update build, test, Playwright, Storybook, README, and container paths. 6. Run the full QA gate, push a ready PR, perform independent review, resolve blockers, merge to `main`, and deploy only when checks and review are clean.