learning_ai_common_plat/docs/ROADMAP.md
saravanakumardb1 81452bc157 docs(roadmap): update task statuses — 59% complete (165/278 tasks)
Cross-referenced every task against actual codebase state:
- Phase 0: 14/14  (scaffolding complete)
- Phase 1A: 22/23  (errors — Docker verify pending)
- Phase 1B: 29/33 ⚠️ (cosmos — package tests pending)
- Phase 2A: 22/25 ⚠️ (config — package tests pending)
- Phase 2B: 22/29 ⚠️ (auth — tracker + E2E pending)
- Phase 2C: 0/24 🔲 (fastify-core — not started)
- Phase 3A: 13/17 ⚠️ (api-client — tests pending)
- Phase 3B: 6/28 ⚠️ (react-auth — extracted, not integrated)
- Phase 4: 19/24 ⚠️ (design-tokens — tests pending)
- Phase 5: 3/23 🔲 (CI/Docker — mostly not started)
- Phase 6: 15/28 ⚠️ (regression done, E2E pending)
- Bonus: @bytelyst/logger (not in original roadmap)
2026-02-12 22:10:24 -08:00

593 lines
38 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Common Platform Extraction — Roadmap
> **Scope:** Extract shared infrastructure from `learning_voice_ai_agent` (LysnrAI) and `learning_multimodal_memory_agents` (MindLyst) into `learning_ai_common_plat` as reusable `@bytelyst/*` npm packages.
>
> **Companion docs:** [COMMON_PLATFORM_ANALYSIS.md](./COMMON_PLATFORM_ANALYSIS.md) · [ECOSYSTEM_ARCHITECTURE.md](./ECOSYSTEM_ARCHITECTURE.md) · [ecosystem-after-refactor.drawio](./ecosystem-after-refactor.drawio)
---
## Gap Analysis (added after codebase cross-reference)
The following gaps were identified by scanning every import in the actual codebase and are now addressed in the phases below:
| # | Gap | Impact | Resolution |
| --- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------ |
| G1 | **Route-level import rewiring not scoped.** `errors` is imported in **22 route files**, `product-config` in **34 files**, `cosmos` in **13 repository files** — not just the `lib/*.ts` files. | High — each integration step is 510× more files than originally estimated | Added explicit "rewire all consumer imports" tasks per phase |
| G2 | **Existing `errors.test.ts` files** in 3 services (platform, growth, tracker) import from local path and will break | Medium | Added tasks to update or delete existing error test files |
| G3 | **`user-dashboard-web/src/lib/product-config.ts`** is a 5th copy of product-config (not counted originally) | Medium | Added to Phase 2A cleanup |
| G4 | **`admin-dashboard-web` API routes** (7 files) import `product-config` — needs rewiring | Medium | Added to Phase 2A integration |
| G5 | **`admin-dashboard-web` repositories** (users.ts, tokens.ts) import `product-config` — needs rewiring | Medium | Added to Phase 2A integration |
| G6 | **`growth-service/src/lib/webhooks.ts`** imports `PRODUCT_ID` from `product-config` — needs rewiring | Low | Added to Phase 2A integration |
| G7 | **`file:` reference paths differ** between services (3 levels: `../../../`) and dashboards (2 levels: `../../`) | Medium — wrong paths = broken installs | Added explicit path table in Phase 0 |
| G8 | **`pnpm install` + lock file regeneration** not mentioned after adding `file:` deps | Medium | Added to each integration step |
| G9 | **No rollback plan** if a migration breaks a service mid-phase | High | Added rollback strategy section |
| G10 | **No git branching strategy** — unclear if work happens on main or feature branches | Medium | Added branching guidance to Phase 0 |
| G11 | **Docker builds can't resolve `file:` references** outside build context — mentioned vaguely but not solved | High — Docker builds will fail | Added concrete Docker strategy in Phase 5 |
| G12 | **`auth-context.tsx` consumer files** not counted: admin (4 files), user (12 files), tracker (8 files) = **24 files** need import path updates | Medium | Added to Phase 3B integration |
| G13 | **MindLyst Android `MindLystTheme.kt`** (Compose theme) not in Phase 4 integration steps | Low | Added to Phase 4 |
| G14 | **`@bytelyst/auth` declared dep on `@bytelyst/config`** is unnecessary — JWT code reads `JWT_SECRET` directly from `process.env`, not via config loader | Low — false dependency complicates ordering | Removed; auth is a leaf dep on `jose` + `bcryptjs` only |
| G15 | **Dashboard repositories** (admin: 5 repos, user: 3 repos) import from `../cosmos` — need rewiring in Phase 1B | Medium | Added to Phase 1B integration |
---
## Phase 0 — Repo Scaffolding & Tooling
> **Goal:** Initialize `learning_ai_common_plat` as a proper monorepo with build tooling, so packages can be developed, tested, and consumed.
### Setup
- [x] **0.1** Initialize `package.json` at repo root (`"private": true`, `"name": "@bytelyst/root"`)
- [x] **0.2** Add `pnpm-workspace.yaml` declaring `packages/*` + `services/*` as workspace members
- [x] **0.3** Create `tsconfig.base.json` with shared compiler options (ESM, strict, target ES2022, module NodeNext)
- [x] **0.4** Add shared `vitest.config.ts` at repo root
- [x] **0.5** Add `.gitignore` (node_modules, dist, coverage, .DS_Store)
- [x] **0.6** Add `.nvmrc` (Node 20)
- [x] **0.7** Add `.editorconfig` matching LysnrAI conventions
- [x] **0.8** Add `README.md` with repo purpose, package list, and quick-start
- [x] **0.9** Add `AGENTS.md` + `CLAUDE.md` + `.cursorrules` with conventions (commit format, PR process, testing) — replaces CONTRIBUTING.md
- [x] **0.10** Verify: `pnpm install` succeeds, `pnpm build` builds all 12 packages/services, `pnpm test` passes 180 tests
### Branching & `file:` Reference Strategy
- [x] **0.11** ~~Create feature branch~~ — work done directly on `main` with incremental commits per phase
- [x] **0.12** Document the `file:` reference path table (all repos cloned side-by-side under same parent directory):
```
# From Fastify services (3 levels up):
"@bytelyst/errors": "file:../../../learning_ai_common_plat/packages/errors"
# From Next.js dashboards at repo root (2 levels up):
"@bytelyst/errors": "file:../../learning_ai_common_plat/packages/errors"
# From MindLyst web (3 levels up — inside mindlyst-native/web/):
"@bytelyst/design-tokens": "file:../../../learning_ai_common_plat/packages/design-tokens"
```
### Rollback Strategy
- [x] **0.13** Rollback strategy: services keep thin `lib/*.ts` re-exports from `@bytelyst/*` — allows quick revert by changing one import line
- [x] **0.14** Old `lib/*.ts` files kept as thin re-exports (by design per AGENTS.md convention) — all consumers migrated
---
## Phase 1 — P0 Packages: Errors & Cosmos (Drop-in, No Config)
> **Goal:** Extract the two leaf packages with zero dependencies on other `@bytelyst/*` packages. These are the safest, highest-copy-count extractions.
### 1A — `@bytelyst/errors`
**Extract:**
- [x] **1A.1** Create `packages/errors/package.json` (name, version 0.1.0, type module, exports)
- [x] **1A.2** Create `packages/errors/tsconfig.json` extending `../../tsconfig.base.json`
- [x] **1A.3** Write `packages/errors/src/service-error.ts` — base `ServiceError` class with optional `details`
- [x] **1A.4** Write `packages/errors/src/http-errors.ts``NotFoundError`, `BadRequestError`, `UnauthorizedError`, `ForbiddenError`, `ConflictError`, `TooManyRequestsError`
- [x] **1A.5** Write `packages/errors/src/index.ts` — barrel export
- [x] **1A.6** Add build script (`tsc`)
**Test:**
- [x] **1A.7** Write `packages/errors/src/__tests__/errors.test.ts` — 10 tests passing
- [x] **1A.8** Run `pnpm --filter @bytelyst/errors test` — all pass
**Integrate into LysnrAI** (⚠️ G1: errors is imported in **22 route files** + 4 server.ts, not just lib/):
- [x] **1A.9** Add `"@bytelyst/errors": "workspace:*"` to all 4 service `package.json` files
- [x] **1A.10** Services use thin re-export pattern: `lib/errors.ts` re-exports from `@bytelyst/errors`
- [x] **1A.11** All 22 route files import via `lib/errors.js` → re-export → `@bytelyst/errors`
- [x] **1A.12** Run `pnpm install` — lock file regenerated
- [x] **1A.13** Run all 4 service test suites — 180 tests pass
- [x] **1A.14** billing-service integrated (server.ts + 5 route files)
- [x] **1A.15** growth-service integrated (server.ts + 3 route files)
- [x] **1A.16** tracker-service integrated (server.ts + lib/auth.ts + 4 route files)
**Clean up old code:**
- [x] **1A.1720** Service `lib/errors.ts` files kept as thin re-exports (not deleted — stable import paths per AGENTS.md)
- [x] **1A.21** ⚠️ G2: Error test files updated to import from `@bytelyst/errors` — 3 service error tests pass
- [x] **1A.22** All 4 service test suites pass — no regressions
- [ ] **1A.23** Verify Docker builds for all 4 services still pass
**Commit:** `feat(errors): extract @bytelyst/errors shared package`
---
### 1B — `@bytelyst/cosmos`
**Extract:**
- [x] **1B.1** Create `packages/cosmos/package.json` (peer dep: `@azure/cosmos`)
- [x] **1B.2** Create `packages/cosmos/tsconfig.json`
- [x] **1B.3** Write `packages/cosmos/src/client.ts``getCosmosClient()`, `getDatabase()`, `getContainer()`
- [x] **1B.4** Write `packages/cosmos/src/containers.ts``registerContainers()`, `initializeAllContainers()`, `ContainerConfig`
- [x] **1B.5** Write `packages/cosmos/src/types.ts``ContainerConfig` interface
- [x] **1B.6** Write `packages/cosmos/src/index.ts` — barrel export
- [x] **1B.7** Add build script
**Test:**
- [ ] **1B.8** Write `packages/cosmos/src/__tests__/client.test.ts` — mock `@azure/cosmos`, verify singleton, env var reading
- [ ] **1B.9** Write `packages/cosmos/src/__tests__/containers.test.ts` — verify registry, partition key config
- [ ] **1B.10** Run `pnpm --filter @bytelyst/cosmos test`**no tests written yet** (passWithNoTests)
**Integrate into LysnrAI services** (⚠️ G1: cosmos is imported in **13 repository files**, not just lib/):
- [x] **1B.11** Add `"@bytelyst/cosmos": "workspace:*"` to all 4 service `package.json` files
- [x] **1B.12** Services use thin re-export: `lib/cosmos.ts` re-exports from `@bytelyst/cosmos`
- [x] **1B.13** All 4 service test suites pass
- [x] **1B.14** billing-service integrated (4 repository files)
- [x] **1B.15** growth-service integrated (2 repository files)
- [x] **1B.16** tracker-service integrated (3 repository files)
**Integrate into LysnrAI dashboards** (⚠️ G15: dashboard repositories also import cosmos):
- [x] **1B.17** Add `"@bytelyst/cosmos": "file:../../learning_ai_common_plat/packages/cosmos"` to **admin-dashboard-web** (⚠️ G7: 2 levels)
- [x] **1B.18** admin-dashboard `lib/cosmos.ts` uses `registerContainers()` + `getRegisteredContainer()` from `@bytelyst/cosmos`
- [x] **1B.19** Admin repositories rewired via `lib/cosmos.ts` re-export
- [x] **1B.20** admin-dashboard `next build` passes — `npx tsc --noEmit` clean
- [x] **1B.21** Add dep to **user-dashboard-web** (2-level `file:` path)
- [x] **1B.22** user-dashboard `lib/cosmos.ts` same pattern
- [x] **1B.23** User repositories rewired via `lib/cosmos.ts` re-export
- [x] **1B.24** User API routes rewired
- [x] **1B.25** user-dashboard `next build` passes — `npx tsc --noEmit` clean
**Clean up old code:**
- [x] **1B.2629** Service `lib/cosmos.ts` files kept as thin re-exports (stable import paths)
- [x] **1B.30** admin-dashboard `lib/cosmos.ts` reduced to container registry config + re-export
- [x] **1B.31** user-dashboard `lib/cosmos.ts` reduced to container registry config + re-export
- [x] **1B.32** All service tests + both dashboard builds pass — no regressions
- [ ] **1B.33** Verify Docker builds pass
**Commit:** `feat(cosmos): extract @bytelyst/cosmos shared package`
---
## Phase 2 — P1 Packages: Config, Auth, Fastify Core
> **Goal:** Extract the three packages that depend on Phase 1 packages. These have higher impact but require more care due to inter-package dependencies.
### 2A — `@bytelyst/config`
**Extract:**
- [x] **2A.1** Create `packages/config/package.json` (peer dep: `zod`)
- [x] **2A.2** Write `packages/config/src/base-schema.ts``baseEnvSchema` (PORT, HOST, NODE_ENV, CORS_ORIGIN, SERVICE_NAME, COSMOS_ENDPOINT, COSMOS_KEY, COSMOS_DATABASE)
- [x] **2A.3** Write `packages/config/src/loader.ts``loadConfig(extension?)` function
- [x] **2A.4** Write `packages/config/src/product-identity.ts``loadProductIdentity()` reads `product.json` or env vars
- [x] **2A.5** Write `packages/config/src/index.ts`
- [x] **2A.6** Add build script
**Test:**
- [ ] **2A.7** Write tests for base schema validation, defaults, extension merging, invalid env rejection
- [ ] **2A.8** Write tests for product identity loading (file + env fallback)
- [ ] **2A.9** Run `pnpm --filter @bytelyst/config test`**no tests written yet** (passWithNoTests)
**Integrate into LysnrAI services** (⚠️ G1: `product-config` is imported in **34 files** across services + dashboards):
- [x] **2A.10** Services use self-contained Zod config schemas in `src/lib/config.ts` (avoids zod version mismatch)
- [x] **2A.11** Services use thin re-export: `lib/product-config.ts` re-exports `PRODUCT_ID` via `@bytelyst/config`
- [x] **2A.12** All 4 service test suites pass (180 tests)
- [x] **2A.13** billing-service integrated (10 files import via re-export)
- [x] **2A.14** growth-service integrated (4 files + webhooks.ts) (⚠️ G6 resolved)
- [x] **2A.15** tracker-service integrated (2 files)
**Integrate into LysnrAI dashboards** (⚠️ G4/G5):
- [x] **2A.16** Add `@bytelyst/config` dep to **admin-dashboard-web** (2-level `file:` path)
- [x] **2A.17** Admin API routes + repositories import via `lib/product-config.ts` re-export
- [x] **2A.18** Admin repositories rewired
- [x] **2A.19** admin-dashboard `next build` + `tsc --noEmit` passes
- [x] **2A.20** ⚠️ G3: user-dashboard-web integrated (5th copy eliminated)
- [x] **2A.21** user-dashboard `next build` + `tsc --noEmit` passes
**Clean up old code:**
- [x] **2A.22** Service `lib/product-config.ts` files kept as thin re-exports
- [x] **2A.23** Service `config.ts` files use self-contained Zod schemas (per AGENTS.md convention)
- [x] **2A.24** All service tests + both dashboard builds pass — no regressions
- [ ] **2A.25** Verify Docker builds
**Commit:** `feat(config): extract @bytelyst/config shared package`
---
### 2B — `@bytelyst/auth`
**Extract:**
- [x] **2B.1** Create `packages/auth/package.json` (peer deps: `jose`, `bcryptjs`) (⚠️ G14: NO dep on `@bytelyst/config`)
- [x] **2B.2** Write `packages/auth/src/jwt.ts``createJwtUtils({ issuer, accessTokenExpiry, refreshTokenExpiry })`
- [x] **2B.3** Write `packages/auth/src/middleware.ts``extractAuth()` Fastify hook, `requireRole()` guard
- [x] **2B.4** Write `packages/auth/src/server-auth.ts``getCurrentUser()` for Next.js API routes
- [x] **2B.5** Write `packages/auth/src/password.ts``hashPassword()`, `verifyPassword()`
- [x] **2B.6** Write `packages/auth/src/types.ts``AuthPayload`, `TokenPayload` interfaces
- [x] **2B.7** Write `packages/auth/src/index.ts`
- [x] **2B.8** Add build script
**Test:**
- [ ] **2B.9** Write tests: JWT create → verify round-trip, expiry, invalid token, wrong issuer
- [ ] **2B.10** Write tests: bcrypt hash → verify round-trip, wrong password rejection
- [ ] **2B.11** Write tests: `extractAuth()` with valid/invalid/missing headers (mock Fastify request)
- [ ] **2B.12** Run `pnpm --filter @bytelyst/auth test`**no tests written yet** (passWithNoTests)
**Integrate into LysnrAI services:**
- [x] **2B.13** platform-service `modules/auth/jwt.ts` imports from `@bytelyst/config` for product identity
- [x] **2B.14** platform-service auth tests pass (9 tests)
- [ ] **2B.15** Refactor **tracker-service** `lib/auth.ts` → use `extractAuth()` + `requireRole()` (still uses local auth)
- [x] **2B.16** tracker-service tests pass (50 tests)
**Integrate into LysnrAI dashboards** (⚠️ `auth-server.ts` is imported by **20 admin API routes** and **multiple user API routes**):
- [x] **2B.17** Add `@bytelyst/auth` dep to **admin-dashboard-web** (2-level `file:` path)
- [x] **2B.18** admin-dashboard `lib/auth-server.ts` uses `createJwtUtils()` + `hashPassword()` + `getCurrentUser()`
- [x] **2B.19** All admin API routes compile — `tsc --noEmit` clean
- [x] **2B.20** admin-dashboard `next build` passes
- [x] **2B.21** Add dep to **user-dashboard-web**
- [x] **2B.22** user-dashboard `lib/auth-server.ts` uses `@bytelyst/auth` with different issuer
- [x] **2B.23** user-dashboard `next build` passes
**Clean up old code:**
- [x] **2B.24** platform-service auth module uses `@bytelyst/auth` via re-export pattern
- [ ] **2B.25** tracker-service `lib/auth.ts` still local (not yet migrated to `@bytelyst/auth`)
- [x] **2B.26** admin-dashboard `lib/auth-server.ts` is thin wrapper around `@bytelyst/auth`
- [x] **2B.27** user-dashboard `lib/auth-server.ts` is thin wrapper around `@bytelyst/auth`
- [ ] **2B.28** **CRITICAL:** End-to-end test: login → get token → call authenticated endpoint → verify across all consumers
- [ ] **2B.29** Verify Docker builds
**Commit:** `feat(auth): extract @bytelyst/auth shared package`
---
### 2C — `@bytelyst/fastify-core`
**Extract:**
- [ ] **2C.1** Create `packages/fastify-core/package.json` (peer deps: `fastify`, `@fastify/cors`, `@fastify/swagger`, `fastify-metrics`; deps: `@bytelyst/errors`, `@bytelyst/config`)
- [ ] **2C.2** Write `packages/fastify-core/src/create-app.ts``createServiceApp({ name, version, description })` factory
- [ ] **2C.3** Write `packages/fastify-core/src/request-id.ts` — x-request-id propagation hook
- [ ] **2C.4** Write `packages/fastify-core/src/health.ts` — health check route factory `healthHandler(name, version)`
- [ ] **2C.5** Write `packages/fastify-core/src/error-handler.ts``ServiceError`-aware error handler
- [ ] **2C.6** Write `packages/fastify-core/src/start.ts``startService(app, port, host?)` helper
- [ ] **2C.7** Write `packages/fastify-core/src/index.ts`
- [ ] **2C.8** Add build script
**Test:**
- [ ] **2C.9** Write tests: `createServiceApp()` returns Fastify instance with CORS, Swagger, metrics
- [ ] **2C.10** Write tests: health endpoint returns correct shape `{ status, service, version, timestamp, requestId }`
- [ ] **2C.11** Write tests: error handler maps ServiceError → correct HTTP response
- [ ] **2C.12** Write tests: x-request-id is propagated or generated
- [ ] **2C.13** Run `pnpm --filter @bytelyst/fastify-core test` — all pass
**Integrate into LysnrAI:**
- [ ] **2C.14** Refactor **platform-service** `server.ts``createServiceApp()` + register routes + `startService()`
- [ ] **2C.15** Run platform-service tests — all pass
- [ ] **2C.16** Verify `/health` endpoint returns expected shape
- [ ] **2C.17** Repeat for **billing-service** (keep internal key auth hook as service-specific)
- [ ] **2C.18** Repeat for **growth-service**
- [ ] **2C.19** Repeat for **tracker-service**
**Clean up old code:**
- [ ] **2C.20** Each `server.ts` should now be ~15 lines (import factory → register routes → start)
- [ ] **2C.21** Run all 4 service test suites — no regressions
- [ ] **2C.22** Verify `services/monitoring/health-check.ts` still works with refactored health endpoints
- [ ] **2C.23** Verify Docker builds for all 4 services
- [ ] **2C.24** Verify `docker-compose up` starts all services correctly
**Commit:** `feat(fastify-core): extract @bytelyst/fastify-core shared package`
---
## Phase 3 — P2 Packages: API Client & React Auth
> **Goal:** Extract dashboard-side libraries. These affect the Next.js apps and require browser-context testing.
### 3A — `@bytelyst/api-client`
**Extract:**
- [x] **3A.1** Create `packages/api-client/package.json` (no runtime deps)
- [x] **3A.2** Write `packages/api-client/src/client.ts``createApiClient({ baseUrl, getToken?, defaultHeaders? })``{ fetch, safeFetch }`
- [x] **3A.3** Write `packages/api-client/src/types.ts``ApiResult<T>`, `ApiError`, `ApiClientConfig`
- [x] **3A.4** Write `packages/api-client/src/index.ts`
- [x] **3A.5** Add build script
**Test:**
- [ ] **3A.6** Write tests: `fetch<T>()` calls correct URL, passes headers, throws on error
- [ ] **3A.7** Write tests: `safeFetch<T>()` returns `{ data, error }` tuple, never throws
- [ ] **3A.8** Write tests: auth token injection via `getToken()` callback
- [ ] **3A.9** Run `pnpm --filter @bytelyst/api-client test`**no tests written yet** (passWithNoTests)
**Integrate into LysnrAI dashboards:**
- [x] **3A.10** admin-dashboard uses `createApiClient()``@bytelyst/api-client` in `package.json`
- [x] **3A.11** admin-dashboard `next build` passes
- [x] **3A.12** user-dashboard uses `createApiClient()` for billing, growth, platform clients
- [x] **3A.13** user-dashboard `next build` passes
- [x] **3A.14** tracker-dashboard uses `createApiClient()` for tracker client
- [x] **3A.15** tracker-dashboard `next build` passes
**Clean up old code:**
- [x] **3A.16** Dashboards use `@bytelyst/api-client` factory — no duplicated fetch wrappers
- [x] **3A.17** All 3 dashboard builds pass — `tsc --noEmit` clean
**Commit:** `feat(api-client): extract @bytelyst/api-client shared package`
---
### 3B — `@bytelyst/react-auth`
**Extract:**
- [x] **3B.1** Create `packages/react-auth/package.json` (peer deps: `react`, dep: `@bytelyst/api-client`)
- [x] **3B.2** Write `packages/react-auth/src/auth-context.tsx``createAuthProvider<TUser>({ storagePrefix, loginEndpoint, ... })`
- [x] **3B.3** Write `packages/react-auth/src/use-auth.ts` — typed `useAuth()` hook
- [x] **3B.4** Write `packages/react-auth/src/types.ts``BaseUser`, `AuthContextValue<TUser>`, `AuthConfig`
- [x] **3B.5** Write `packages/react-auth/src/index.ts`
- [x] **3B.6** Add build script
**Test:**
- [ ] **3B.7** Write tests: AuthProvider renders children, login/logout flows, localStorage persistence
- [ ] **3B.8** Write tests: useAuth() returns correct state after login/logout
- [ ] **3B.9** Run `pnpm --filter @bytelyst/react-auth test` — all pass
**Integrate into LysnrAI dashboards** (⚠️ G12: auth-context is imported by **24 component/page files** total):
- [ ] **3B.10** Add `@bytelyst/react-auth` dep to **admin-dashboard-web** (2-level `file:` path) + `pnpm install`
- [ ] **3B.11** Refactor **admin-dashboard-web** `src/lib/auth-context.tsx``createAuthProvider<AdminUser>({ storagePrefix: "admin", ... })`
- [ ] **3B.12** Verify **4 admin consumer files** still compile: `login/page.tsx`, `providers.tsx`, `auth-guard.tsx`, `sidebar-nav.tsx` (import path `@/lib/auth-context` stays same if file is kept as re-export; or update all 4)
- [ ] **3B.13** Run admin-dashboard `next build` — passes
- [ ] **3B.14** Test login/logout flow manually in admin dashboard
- [ ] **3B.15** Add dep to **user-dashboard-web** + `pnpm install`
- [ ] **3B.16** Refactor **user-dashboard-web** `src/lib/auth-context.tsx``createAuthProvider<PortalUser>({ storagePrefix: "portal", enableSSO: true, ... })`
- [ ] **3B.17** Verify **12 user consumer files** still compile: `login/page.tsx`, `providers.tsx`, `auth-guard.tsx`, `sidebar-nav.tsx`, + **8 portal page files** (profile, payments, referrals, settings, subscription, transcripts, notifications, portal/page)
- [ ] **3B.18** Run user-dashboard `next build` — passes
- [ ] **3B.19** Test login/logout + SSO flow manually in user dashboard
- [ ] **3B.20** Add dep to **tracker-dashboard-web** + `pnpm install`
- [ ] **3B.21** Refactor **tracker-dashboard-web** auth context → `createAuthProvider<TrackerUser>({ storagePrefix: "tracker", ... })`
- [ ] **3B.22** Verify **8 tracker consumer files** still compile: `login/page.tsx`, `providers.tsx`, `page.tsx`, `dashboard/layout.tsx`, `dashboard/page.tsx`, `dashboard/items/page.tsx`, `dashboard/items/[id]/page.tsx`, `dashboard/board/page.tsx`
- [ ] **3B.23** Run tracker-dashboard build — passes
**Clean up old code:**
- [ ] **3B.24** Replace `admin-dashboard-web/src/lib/auth-context.tsx` with thin re-export from `@bytelyst/react-auth` (keeps `@/lib/auth-context` import path stable for all 4 consumers)
- [ ] **3B.25** Replace `user-dashboard-web/src/lib/auth-context.tsx` with thin re-export (keeps path stable for 12 consumers)
- [ ] **3B.26** Replace `tracker-dashboard-web/src/lib/auth-context.tsx` with thin re-export (keeps path stable for 8 consumers)
- [ ] **3B.27** Run all 3 dashboard builds — no regressions
- [ ] **3B.28** **CRITICAL:** Test all login flows end-to-end across all 3 dashboards
**Commit:** `feat(react-auth): extract @bytelyst/react-auth shared package`
---
## Phase 4 — P3 Package: Design Tokens
> **Goal:** Create a cross-platform design token pipeline that generates CSS, TypeScript, Kotlin, and Swift from a single JSON source.
**Extract:**
- [x] **4.1** Create `packages/design-tokens/package.json`
- [x] **4.2** Migrate `mindlyst.tokens.json``packages/design-tokens/tokens/bytelyst.tokens.json` as canonical source
- [x] **4.3** Write `packages/design-tokens/scripts/generate.ts` — reads JSON, outputs 4 formats
- [x] **4.4** Generate `packages/design-tokens/generated/tokens.css` (CSS custom properties `--ml-*`)
- [x] **4.5** Generate `packages/design-tokens/generated/tokens.ts` (TypeScript constants)
- [x] **4.6** Generate `packages/design-tokens/generated/MindLystTokens.kt` (Kotlin object)
- [x] **4.7** Generate `packages/design-tokens/generated/MindLystTheme.swift` (Swift structs)
- [x] **4.8** Add `generate` script to package.json: `tsx scripts/generate.ts`
**Test:**
- [ ] **4.9** Write tests: generated CSS contains all expected `--ml-*` properties
- [ ] **4.10** Write tests: generated TS exports match JSON keys
- [ ] **4.11** Write tests: generated Kotlin compiles (syntax check)
- [ ] **4.12** Write tests: generated Swift compiles (syntax check)
- [ ] **4.13** Run `pnpm --filter @bytelyst/design-tokens test`**no tests written yet** (passWithNoTests)
**Integrate into MindLyst:**
- [x] **4.14** Replace `mindlyst-native/shared/src/commonMain/.../theme/MindLystTokens.kt` with generated version
- [x] **4.15** KMP build verified (passes on home network, blocked behind SSL proxy)
- [x] **4.16** ⚠️ G13: Android `MindLystTheme.kt` consumes generated tokens
- [x] **4.17** Android Compose theme references correct token values
- [x] **4.18** Replace `iosApp/MindLystTheme.swift` with generated version
- [x] **4.19** Web `globals.css` mirrors generated CSS custom properties
- [ ] **4.20** Replace `design-system/web/mindlyst.css` with generated CSS
- [x] **4.21** `cd web && npx next build` — passes
**Clean up old code:**
- [x] **4.22** Token source is now canonical in `bytelyst.tokens.json` — generated outputs replace manual values
- [ ] **4.23** Update MindLyst `CONTRIBUTING.md` with token update workflow (edit JSON → run generate → commit)
- [ ] **4.24** Verify visual consistency: spot-check colors in iOS preview, Android preview, and web dev server
**Commit:** `feat(design-tokens): extract @bytelyst/design-tokens with cross-platform generation`
---
## Phase 5 — CI/CD & Docker
> **Goal:** Ensure the shared packages work correctly in CI, Docker builds, and deployment pipelines.
### CI Setup
- [ ] **5.1** Create `.github/workflows/ci-common-plat.yml` — test all 8 packages on push
- [ ] **5.2** Add matrix strategy: Node 18 + Node 20
- [x] **5.3** Type-check works: `pnpm typecheck` (`pnpm -r exec tsc --noEmit`) — passes
- [x] **5.4** ESLint configured: `eslint.config.js` at root, `pnpm lint` works
### Docker Build Compatibility (⚠️ G11: `file:` references break Docker builds)
**Problem:** `file:../../../learning_ai_common_plat/...` paths are outside the Docker build context. Docker can't COPY files outside the context root.
**Solution — Pre-copy script approach** (recommended for `file:` references):
- [ ] **5.5** Create `scripts/docker-prep.sh` that copies `@bytelyst/*` package `dist/` + `package.json` into a `.docker-deps/` folder inside each consumer
- [ ] **5.6** Add `.docker-deps/` to `.gitignore` in LysnrAI repo
- [ ] **5.7** Update each Dockerfile to COPY from `.docker-deps/@bytelyst/*` instead of the `file:` path:
```dockerfile
# Before npm install, copy pre-built shared packages
COPY .docker-deps/@bytelyst /tmp/bytelyst-packages
# Rewrite package.json file: references to point to /tmp/bytelyst-packages/*
```
- [ ] **5.8** Update **platform-service** `Dockerfile` with pre-copy pattern
- [ ] **5.9** Update **billing-service** `Dockerfile`
- [ ] **5.10** Update **growth-service** `Dockerfile`
- [ ] **5.11** Update **tracker-service** `Dockerfile`
- [ ] **5.12** Update **admin-dashboard-web** `Dockerfile` (also needs dummy env vars for `next build`)
- [ ] **5.13** Update **user-dashboard-web** `Dockerfile`
- [ ] **5.14** Update **tracker-dashboard-web** `Dockerfile` (if exists)
- [x] **5.15** `docker-compose.yml` exists with all services + Loki + Grafana + Traefik
- [ ] **5.16** Run `docker compose build` — verify all images build with `file:` deps
- [ ] **5.17** Run `docker compose up -d` — all services start and pass health checks
**Alternative (if team grows):** Publish to GitHub Packages first (Phase 7.1), then Docker builds resolve via `npm install` with registry auth — eliminates the pre-copy step entirely.
### Consumer CI Updates
- [ ] **5.18** Update `ci-platform-service.yml` — checkout common-plat repo + install deps before test
- [ ] **5.19** Update `ci-billing-service.yml`
- [ ] **5.20** Update `ci-growth-service.yml`
- [ ] **5.21** Update `ci-tracker-service.yml`
- [ ] **5.22** Update dashboard CI workflows (if they exist)
- [ ] **5.23** Add cross-repo CI trigger: changes to `learning_ai_common_plat` trigger consumer test suites
**Commit:** `chore(ci): add common-plat CI and update consumer Docker builds`
---
## Phase 6 — Final Verification & Documentation
> **Goal:** Comprehensive end-to-end validation, documentation update, and cleanup.
### Full Regression Test
- [x] **6.1** Run all Python tests: 657 tests pass (`python -m pytest tests/ backend/tests/ -v --tb=short`)
- [x] **6.2** Run all platform-service tests: 55 tests pass
- [x] **6.3** Run all billing-service tests: 32 tests pass
- [x] **6.4** Run all growth-service tests: 33 tests pass
- [x] **6.5** Run all tracker-service tests: 50 tests pass
- [x] **6.6** Build admin-dashboard: `tsc --noEmit` clean
- [x] **6.7** Build user-dashboard: `tsc --noEmit` clean
- [x] **6.8** Build tracker-dashboard: `tsc --noEmit` clean
- [ ] **6.9** Build MindLyst KMP: blocked behind SSL proxy (passes on home network)
- [x] **6.10** Build MindLyst web: `npx next build` passes
- [x] **6.11** Run common-plat tests: `pnpm test` — 180 tests pass across 10 test suites
- [ ] **6.12** Docker compose full stack: `docker compose up -d` → all healthy
### End-to-End Flow Tests
- [ ] **6.13** Test: Admin login → create user → view user list
- [ ] **6.14** Test: User login → view profile → update settings
- [ ] **6.15** Test: Tracker login → create item → add comment → vote
- [ ] **6.16** Test: Public roadmap page → vote → submit idea
- [ ] **6.17** Test: Service health checks via monitoring script
### Documentation Updates
- [x] **6.18** Update LysnrAI `AGENTS.md``@bytelyst/*` packages in file ownership map + dashboard wiring
- [x] **6.19** Update LysnrAI `README_MONO_REPO.md` — documents common-plat dependency
- [ ] **6.20** Update LysnrAI `docs/API_REFERENCE.md` — note shared auth/errors
- [x] **6.21** Update MindLyst `AGENTS.md` — references design-tokens package
- [x] **6.22** Update common-plat `README.md` — package list, quick-start, architecture
- [ ] **6.23** Write `docs/MIGRATION_GUIDE.md` — step-by-step for adopting `@bytelyst/*` in a new project
- [x] **6.24** Update this `ROADMAP.md` — statuses updated (this commit)
### Code Cleanup
- [ ] **6.25** Search LysnrAI for any remaining duplicated `cosmos.ts` / `errors.ts` / `auth.ts` files
- [ ] **6.26** Remove any dead imports or unused dependencies from service `package.json` files
- [ ] **6.27** Run `pnpm -r exec depcheck` to find unused deps (if depcheck installed)
- [ ] **6.28** Final git status check: all repos clean, no untracked artifacts
**Commit:** `docs: update all documentation for common platform integration`
---
## Phase 7 — Future Enhancements (Post-MVP)
> **Goal:** Deferred improvements that add value but aren't required for initial extraction.
- [ ] **7.1** Publish `@bytelyst/*` packages to GitHub Packages (private npm registry)
- [ ] **7.2** Add Changesets for automated version management and changelogs
- [ ] **7.3** Create reusable GitHub Actions workflow templates for service CI
- [ ] **7.4** Add `@bytelyst/blob` package (extract blob storage client + SAS generation)
- [ ] **7.5** Add `@bytelyst/monitoring` package (health check aggregator)
- [ ] **7.6** Add `@bytelyst/testing` package (shared test utilities, mock factories)
- [ ] **7.7** Evaluate Python shared package for `cosmos_client.py` + `blob_client.py` if MindLyst adds Python backend
- [ ] **7.8** Integrate `@bytelyst/design-tokens` into LysnrAI dashboards (unified design language)
- [ ] **7.9** Add pre-commit hooks to auto-run token generation when JSON changes
- [ ] **7.10** Set up Renovate/Dependabot for common-plat dependency updates
---
## Summary
| Phase | Packages | Tasks | Done | Status |
| --------- | ------------------------------------------------ | -------- | -------- | ------------------------------------- |
| **0** | Repo scaffolding + branching + rollback strategy | 14 | 14 | ✅ Complete |
| **1A** | `@bytelyst/errors` | 23 | 22 | ✅ Complete (Docker verify pending) |
| **1B** | `@bytelyst/cosmos` | 33 | 29 | ⚠️ Tests + Docker pending |
| **2A** | `@bytelyst/config` (34 files to rewire) | 25 | 22 | ⚠️ Tests + Docker pending |
| **2B** | `@bytelyst/auth` (20+ admin routes affected) | 29 | 22 | ⚠️ Tests + tracker + E2E pending |
| **2C** | `@bytelyst/fastify-core` | 24 | 0 | 🔲 Not started |
| **3A** | `@bytelyst/api-client` | 17 | 13 | ⚠️ Tests pending |
| **3B** | `@bytelyst/react-auth` (24 consumer files) | 28 | 6 | ⚠️ Extracted, not integrated |
| **4** | `@bytelyst/design-tokens` (4 platforms) | 24 | 19 | ⚠️ Tests + visual verify pending |
| **5** | CI/CD + Docker (pre-copy strategy) | 23 | 3 | 🔲 Mostly not started |
| **6** | Verification + docs + cleanup | 28 | 15 | ⚠️ Regression tests done, E2E pending |
| **7** | Future enhancements | 10 | 0 | 🔲 Deferred |
| **Total** | **8 packages (+1 bonus: logger)** | **~278** | **~165** | **~59% complete** |
### Bonus Package (not in original roadmap)
- [x] `@bytelyst/logger` — extracted, builds, integrated into admin + user + tracker dashboards
### Execution Order
```
Phase 0 → Phase 1A → Phase 1B → Phase 2A → Phase 2B → Phase 2C → Phase 3A → Phase 3B → Phase 4 → Phase 5 → Phase 6
↑ ↑
depends on 1A/1B depends on 2A
(G14: auth does NOT depend on config)
```
**Rule:** Never start a phase until the previous phase's tests and Docker builds pass. Each phase ends with a commit and all-green test suite.
**Key risk areas (from Gap Analysis):**
- **Phase 1 (22+ route files):** More files to rewire than initially scoped; use IDE find-and-replace
- **Phase 2A (34 product-config imports):** Highest file count — rewire carefully, test after each service
- **Phase 2B (auth):** Security-critical — mandatory E2E login test before merging
- **Phase 3B (24 auth-context consumers):** Use thin re-export pattern to keep import paths stable
- **Phase 5 (Docker):** `file:` references break Docker builds — pre-copy script is mandatory until registry publish