learning_ai_common_plat/docs/ROADMAP.md
saravanakumardb1 60f0703049 docs(roadmap): audit and correct all task statuses and test counts
- Check 5 items that were actually done: 4.20 (CSS synced), 2C.22 (health-check), 6.27 (depcheck), 6.28 (git clean), 7.6 (testing pkg)
- Fix test counts: 6.1 → 652 (5 pre-existing Pydantic failures), 6.11 → 281
- Fix summary table: 2A 25→24, 2C 21→22, 6 23→21
- Total: 244/278 = 88% (was incorrectly 248/278 = 89%)
2026-02-13 01:00:58 -08:00

588 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:**
- [x] **1B.8** Write `packages/cosmos/src/__tests__/cosmos.test.ts` — mock `@azure/cosmos`, verify singleton, env var reading
- [x] **1B.9** Container registry tests included — verify register, getRegistered, initializeAll
- [x] **1B.10** Run `pnpm --filter @bytelyst/cosmos test`**12 tests pass**
**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:**
- [x] **2A.7** Write tests for base schema validation, defaults, extension merging, invalid env rejection
- [x] **2A.8** Write tests for product identity loading (env fallback, defaults, caching, reset)
- [x] **2A.9** Run `pnpm --filter @bytelyst/config test`**15 tests pass**
**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:**
- [x] **2B.9** Write tests: JWT create → verify round-trip, expiry, invalid token, wrong issuer, productId
- [x] **2B.10** Write tests: bcrypt hash → verify round-trip, wrong password, different salts
- [x] **2B.11** Write tests: `extractAuth()` + `requireRole()` with valid/invalid/missing headers — **11 tests**
- [x] **2B.12** Run `pnpm --filter @bytelyst/auth test`**25 tests pass** (10 JWT + 3 password + 11 middleware + 4 E2E)
**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)
- [x] **2B.15** Refactor **tracker-service** `lib/auth.ts` → 1-line re-export from `@bytelyst/auth` (was 48 lines)
- [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
- [x] **2B.25** tracker-service `lib/auth.ts` is now a re-export from `@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`
- [x] **2B.28** E2E test: password verify → JWT issue → extractAuth → requireRole → role rejection (4 tests)
- [x] **2B.29** Dockerfiles rewritten for pnpm monorepo (build blocked by corporate proxy SSL)
**Commit:** `feat(auth): extract @bytelyst/auth shared package`
---
### 2C — `@bytelyst/fastify-core`
**Extract:**
- [x] **2C.1** Create `packages/fastify-core/package.json` (peer deps: `fastify`, `@fastify/cors`; dep: `@bytelyst/errors`)
- [x] **2C.2** Write `packages/fastify-core/src/create-app.ts``createServiceApp({ name, version, description })` factory
- [x] **2C.3** x-request-id propagation built into `createServiceApp()` (not separate file)
- [x] **2C.4** Health check route built into `createServiceApp()` (not separate file)
- [x] **2C.5** ServiceError-aware error handler built into `createServiceApp()`
- [x] **2C.6** Write `packages/fastify-core/src/start.ts``startService(app, { port, host? })` helper
- [x] **2C.7** Write `packages/fastify-core/src/index.ts`
- [x] **2C.8** Add build script
**Test:**
- [x] **2C.9** Write tests: `createServiceApp()` returns Fastify instance with CORS
- [x] **2C.10** Write tests: health endpoint returns correct shape `{ status, service, version, timestamp, requestId }`
- [x] **2C.11** Write tests: error handler maps ServiceError → correct HTTP response (404, 400 with details, 500)
- [x] **2C.12** Write tests: x-request-id propagated when provided, generated as UUID when not
- [x] **2C.13** Run `pnpm --filter @bytelyst/fastify-core test`**8 tests pass**
**Integrate into LysnrAI:**
- [x] **2C.14** Refactor **platform-service** `server.ts``createServiceApp()` (91 → 39 lines)
- [x] **2C.15** Run platform-service tests — 55 tests pass
- [x] **2C.16** Health endpoint verified via fastify-core tests
- [x] **2C.17** Refactor **billing-service** (105 → 51 lines, keeps internal key auth hook)
- [x] **2C.18** Refactor **growth-service** (83 → 33 lines)
- [x] **2C.19** Refactor **tracker-service** (88 → 36 lines)
**Clean up old code:**
- [x] **2C.20** Each `server.ts` now 33-51 lines (factory + routes + start)
- [x] **2C.21** All 4 service test suites pass — 170 service tests, 0 regressions
- [x] **2C.22** Verify `services/monitoring/health-check.ts` still works with refactored health endpoints — confirmed working
- [ ] **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:**
- [x] **3A.6** Write tests: `fetch<T>()` calls correct URL, passes headers, throws on error
- [x] **3A.7** Write tests: `safeFetch<T>()` returns `{ data, error }` tuple, never throws
- [x] **3A.8** Write tests: auth token injection via `getToken()` callback
- [x] **3A.9** Run `pnpm --filter @bytelyst/api-client test`**10 tests pass**
**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:**
- [x] **3B.7** Write tests: AuthProvider renders children, login/logout flows, localStorage persistence
- [x] **3B.8** Write tests: useAuth() returns correct state after login/logout, onLoginFallback, custom prefix
- [x] **3B.9** Run `pnpm --filter @bytelyst/react-auth test`**10 tests pass** (jsdom + React Testing Library)
**Integrate into LysnrAI dashboards** (⚠️ G12: auth-context is imported by **24 component/page files** total):
- [x] **3B.10** Add `@bytelyst/react-auth` dep to **admin-dashboard-web** (2-level `file:` path)
- [x] **3B.11** Refactor **admin-dashboard-web** `src/lib/auth-context.tsx``createAuthProvider<AdminUser>({ storagePrefix: "admin", onLoginFallback })` (121 → 72 lines)
- [x] **3B.12** All admin consumer files compile — `tsc --noEmit` clean (import path `@/lib/auth-context` unchanged)
- [x] **3B.13** Admin dashboard type-checks clean
- [ ] **3B.14** Test login/logout flow manually in admin dashboard (requires running services)
- [x] **3B.15** Add dep to **user-dashboard-web**`tsc --noEmit` clean
- [x] **3B.16** user-dashboard auth-context evaluated — **keep custom** (SSO cookies + register + updateUser too specialized)
- [x] **3B.17** user-dashboard type-checks clean
- [x] **3B.18** Run user-dashboard `next build` — passes
- [ ] **3B.19** Test login/logout + SSO flow manually in user dashboard (requires running services)
- [x] **3B.20** Add dep to **tracker-dashboard-web**`tsc --noEmit` clean
- [x] **3B.21** tracker-dashboard auth-context evaluated — **keep custom** (token + `/api/auth/me` session restore too specialized)
- [x] **3B.22** tracker-dashboard type-checks clean
- [x] **3B.23** Run tracker-dashboard build — passes (requires `--webpack` flag, already in build script)
**Clean up old code:**
- [x] **3B.24** admin-dashboard `auth-context.tsx` uses `createAuthProvider()` from `@bytelyst/react-auth` (with `onLoginFallback` for mock credentials)
- [x] **3B.25** user-dashboard `auth-context.tsx` — keep custom; removed unused `@bytelyst/react-auth` dep
- [x] **3B.26** tracker-dashboard `auth-context.tsx` — keep custom; removed unused `@bytelyst/react-auth` dep
- [x] **3B.27** Run all 3 dashboard builds — admin (`next build`), user (`next build`), tracker (`next build --webpack`) all pass
- [ ] **3B.28** Test all login flows end-to-end across all 3 dashboards (requires running services)
**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:**
- [x] **4.9** Write tests: generated CSS contains `--ml-*` properties
- [x] **4.10** Write tests: generated TS exports token values
- [x] **4.11** Write tests: generated Kotlin contains `object MindLystTokens`
- [x] **4.12** Write tests: generated Swift contains MindLyst struct
- [x] **4.13** Run `pnpm --filter @bytelyst/design-tokens test`**11 tests pass**
**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
- [x] **4.20** Replace `design-system/web/mindlyst.css` with generated CSS — file has "Auto-generated from bytelyst.tokens.json" header
- [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
- [x] **5.1** Create `.github/workflows/ci.yml` — build + test + typecheck + lint on push/PR to main (currently `ci.yml.disabled` — billing paused)
- [x] **5.2** Add matrix strategy: 9 package tests + 4 service tests (parallel jobs, 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):
- [x] **5.5** Create `scripts/docker-prep.sh` (common plat) + `scripts/docker-prep-dashboards.sh` (LysnrAI)
- [x] **5.6** Add `.docker-deps/` to `.gitignore` in LysnrAI repo
- [x] **5.7** Service Dockerfiles rewritten for pnpm monorepo (root context + `pnpm deploy`)
- [x] **5.8** Update **platform-service** `Dockerfile` — pnpm multi-stage build
- [x] **5.9** Update **billing-service** `Dockerfile`
- [x] **5.10** Update **growth-service** `Dockerfile`
- [x] **5.11** Update **tracker-service** `Dockerfile`
- [x] **5.12** Update **admin-dashboard-web** `Dockerfile` (pre-copy + dummy env vars)
- [x] **5.13** Update **user-dashboard-web** `Dockerfile` (pre-copy + dummy env vars)
- [x] **5.14** Update **tracker-dashboard-web** `Dockerfile` (pre-copy)
- [x] **5.15** `docker-compose.yml` updated with `context: .` + `dockerfile:` paths
- [ ] **5.16** Run `docker compose build` — blocked by corporate proxy SSL (not a code issue)
- [ ] **5.17** Run `docker compose up -d` — blocked (requires 5.16)
**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: 652 pass, 5 pre-existing Pydantic failures (`python3 -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`**281 tests pass** across 13 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
- [x] **6.20** Update LysnrAI `docs/API_REFERENCE.md` — added shared platform services section + dashboard→service client wiring
- [x] **6.21** Update MindLyst `AGENTS.md` — references design-tokens package
- [x] **6.22** Update common-plat `README.md` — package list, quick-start, architecture
- [x] **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
- [x] **6.25** Search LysnrAI for duplicated files — all `cosmos.ts`/`auth.ts` use `@bytelyst/*`, no raw error classes
- [x] **6.26** Removed unused `@bytelyst/react-auth` dep from user-dashboard + tracker-dashboard `package.json`
- [x] **6.27** Run depcheck across all packages + dashboards — unused deps removed (react-auth from user/tracker, date-fns/stripe from admin, etc.)
- [x] **6.28** Final git status check: all 3 repos clean, no untracked artifacts — confirmed
**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)
- [x] **7.6** Add `@bytelyst/testing` package (shared test utilities, mock factories) — created with 10 tests
- [ ] **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 | 32 | ✅ Complete (Docker verify pending) |
| **2A** | `@bytelyst/config` (34 files to rewire) | 25 | 24 | ✅ Complete (Docker verify pending) |
| **2B** | `@bytelyst/auth` (20+ admin routes affected) | 29 | 29 | ✅ Complete (25 tests, tracker migrated) |
| **2C** | `@bytelyst/fastify-core` | 24 | 22 | ✅ Services refactored, health-check verified (Docker pending) |
| **3A** | `@bytelyst/api-client` | 17 | 17 | ✅ Complete |
| **3B** | `@bytelyst/react-auth` (24 consumer files) | 28 | 25 | ✅ Admin uses factory; user/tracker keep custom |
| **4** | `@bytelyst/design-tokens` (4 platforms) | 24 | 22 | ✅ CSS synced to MindLyst; visual verify pending |
| **5** | CI/CD + Docker (pre-copy strategy) | 23 | 15 | ⚠️ All Dockerfiles rewritten, build blocked by proxy |
| **6** | Verification + docs + cleanup | 28 | 21 | ✅ Docs updated, depcheck done, git clean; E2E needs services |
| **7** | Future enhancements (+testing pkg) | 10 | 1 | 🔲 @bytelyst/testing created (10 tests) |
| **Total** | **10 packages (+1 bonus: logger)** | **278** | **244** | **~88% 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