38 KiB
Common Platform Extraction — Roadmap
Scope: Extract shared infrastructure from
learning_voice_ai_agent(LysnrAI) andlearning_multimodal_memory_agents(MindLyst) intolearning_ai_common_platas reusable@bytelyst/*npm packages.Companion docs: COMMON_PLATFORM_ANALYSIS.md · ECOSYSTEM_ARCHITECTURE.md · 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 5–10× 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_platas a proper monorepo with build tooling, so packages can be developed, tested, and consumed.
Setup
- 0.1 Initialize
package.jsonat repo root ("private": true,"name": "@bytelyst/root") - 0.2 Add
pnpm-workspace.yamldeclaringpackages/*+services/*as workspace members - 0.3 Create
tsconfig.base.jsonwith shared compiler options (ESM, strict, target ES2022, module NodeNext) - 0.4 Add shared
vitest.config.tsat repo root - 0.5 Add
.gitignore(node_modules, dist, coverage, .DS_Store) - 0.6 Add
.nvmrc(Node 20) - 0.7 Add
.editorconfigmatching LysnrAI conventions - 0.8 Add
README.mdwith repo purpose, package list, and quick-start - 0.9 Add
AGENTS.md+CLAUDE.md+.cursorruleswith conventions (commit format, PR process, testing) — replaces CONTRIBUTING.md - 0.10 Verify:
pnpm installsucceeds,pnpm buildbuilds all 12 packages/services,pnpm testpasses 180 tests
Branching & file: Reference Strategy
- 0.11
Create feature branch— work done directly onmainwith incremental commits per phase - 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
- 0.13 Rollback strategy: services keep thin
lib/*.tsre-exports from@bytelyst/*— allows quick revert by changing one import line - 0.14 Old
lib/*.tsfiles 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:
- 1A.1 Create
packages/errors/package.json(name, version 0.1.0, type module, exports) - 1A.2 Create
packages/errors/tsconfig.jsonextending../../tsconfig.base.json - 1A.3 Write
packages/errors/src/service-error.ts— baseServiceErrorclass with optionaldetails - 1A.4 Write
packages/errors/src/http-errors.ts—NotFoundError,BadRequestError,UnauthorizedError,ForbiddenError,ConflictError,TooManyRequestsError - 1A.5 Write
packages/errors/src/index.ts— barrel export - 1A.6 Add build script (
tsc)
Test:
- 1A.7 Write
packages/errors/src/__tests__/errors.test.ts— 10 tests passing - 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/):
- 1A.9 Add
"@bytelyst/errors": "workspace:*"to all 4 servicepackage.jsonfiles - 1A.10 Services use thin re-export pattern:
lib/errors.tsre-exports from@bytelyst/errors - 1A.11 All 22 route files import via
lib/errors.js→ re-export →@bytelyst/errors - 1A.12 Run
pnpm install— lock file regenerated - 1A.13 Run all 4 service test suites — 180 tests pass
- 1A.14 billing-service integrated (server.ts + 5 route files)
- 1A.15 growth-service integrated (server.ts + 3 route files)
- 1A.16 tracker-service integrated (server.ts + lib/auth.ts + 4 route files)
Clean up old code:
- 1A.17–20 Service
lib/errors.tsfiles kept as thin re-exports (not deleted — stable import paths per AGENTS.md) - 1A.21 ⚠️ G2: Error test files updated to import from
@bytelyst/errors— 3 service error tests pass - 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:
- 1B.1 Create
packages/cosmos/package.json(peer dep:@azure/cosmos) - 1B.2 Create
packages/cosmos/tsconfig.json - 1B.3 Write
packages/cosmos/src/client.ts—getCosmosClient(),getDatabase(),getContainer() - 1B.4 Write
packages/cosmos/src/containers.ts—registerContainers(),initializeAllContainers(),ContainerConfig - 1B.5 Write
packages/cosmos/src/types.ts—ContainerConfiginterface - 1B.6 Write
packages/cosmos/src/index.ts— barrel export - 1B.7 Add build script
Test:
- 1B.8 Write
packages/cosmos/src/__tests__/cosmos.test.ts— mock@azure/cosmos, verify singleton, env var reading - 1B.9 Container registry tests included — verify register, getRegistered, initializeAll
- 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/):
- 1B.11 Add
"@bytelyst/cosmos": "workspace:*"to all 4 servicepackage.jsonfiles - 1B.12 Services use thin re-export:
lib/cosmos.tsre-exports from@bytelyst/cosmos - 1B.13 All 4 service test suites pass
- 1B.14 billing-service integrated (4 repository files)
- 1B.15 growth-service integrated (2 repository files)
- 1B.16 tracker-service integrated (3 repository files)
Integrate into LysnrAI dashboards (⚠️ G15: dashboard repositories also import cosmos):
- 1B.17 Add
"@bytelyst/cosmos": "file:../../learning_ai_common_plat/packages/cosmos"to admin-dashboard-web (⚠️ G7: 2 levels) - 1B.18 admin-dashboard
lib/cosmos.tsusesregisterContainers()+getRegisteredContainer()from@bytelyst/cosmos - 1B.19 Admin repositories rewired via
lib/cosmos.tsre-export - 1B.20 admin-dashboard
next buildpasses —npx tsc --noEmitclean - 1B.21 Add dep to user-dashboard-web (2-level
file:path) - 1B.22 user-dashboard
lib/cosmos.tssame pattern - 1B.23 User repositories rewired via
lib/cosmos.tsre-export - 1B.24 User API routes rewired
- 1B.25 user-dashboard
next buildpasses —npx tsc --noEmitclean
Clean up old code:
- 1B.26–29 Service
lib/cosmos.tsfiles kept as thin re-exports (stable import paths) - 1B.30 admin-dashboard
lib/cosmos.tsreduced to container registry config + re-export - 1B.31 user-dashboard
lib/cosmos.tsreduced to container registry config + re-export - 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:
- 2A.1 Create
packages/config/package.json(peer dep:zod) - 2A.2 Write
packages/config/src/base-schema.ts—baseEnvSchema(PORT, HOST, NODE_ENV, CORS_ORIGIN, SERVICE_NAME, COSMOS_ENDPOINT, COSMOS_KEY, COSMOS_DATABASE) - 2A.3 Write
packages/config/src/loader.ts—loadConfig(extension?)function - 2A.4 Write
packages/config/src/product-identity.ts—loadProductIdentity()readsproduct.jsonor env vars - 2A.5 Write
packages/config/src/index.ts - 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 (env fallback, defaults, caching, reset)
- 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):
- 2A.10 Services use self-contained Zod config schemas in
src/lib/config.ts(avoids zod version mismatch) - 2A.11 Services use thin re-export:
lib/product-config.tsre-exportsPRODUCT_IDvia@bytelyst/config - 2A.12 All 4 service test suites pass (180 tests)
- 2A.13 billing-service integrated (10 files import via re-export)
- 2A.14 growth-service integrated (4 files + webhooks.ts) (⚠️ G6 resolved)
- 2A.15 tracker-service integrated (2 files)
Integrate into LysnrAI dashboards (⚠️ G4/G5):
- 2A.16 Add
@bytelyst/configdep to admin-dashboard-web (2-levelfile:path) - 2A.17 Admin API routes + repositories import via
lib/product-config.tsre-export - 2A.18 Admin repositories rewired
- 2A.19 admin-dashboard
next build+tsc --noEmitpasses - 2A.20 ⚠️ G3: user-dashboard-web integrated (5th copy eliminated)
- 2A.21 user-dashboard
next build+tsc --noEmitpasses
Clean up old code:
- 2A.22 Service
lib/product-config.tsfiles kept as thin re-exports - 2A.23 Service
config.tsfiles use self-contained Zod schemas (per AGENTS.md convention) - 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:
- 2B.1 Create
packages/auth/package.json(peer deps:jose,bcryptjs) (⚠️ G14: NO dep on@bytelyst/config) - 2B.2 Write
packages/auth/src/jwt.ts—createJwtUtils({ issuer, accessTokenExpiry, refreshTokenExpiry }) - 2B.3 Write
packages/auth/src/middleware.ts—extractAuth()Fastify hook,requireRole()guard - 2B.4 Write
packages/auth/src/server-auth.ts—getCurrentUser()for Next.js API routes - 2B.5 Write
packages/auth/src/password.ts—hashPassword(),verifyPassword() - 2B.6 Write
packages/auth/src/types.ts—AuthPayload,TokenPayloadinterfaces - 2B.7 Write
packages/auth/src/index.ts - 2B.8 Add build script
Test:
- 2B.9 Write tests: JWT create → verify round-trip, expiry, invalid token, wrong issuer, productId
- 2B.10 Write tests: bcrypt hash → verify round-trip, wrong password, different salts
- 2B.11 Write tests:
extractAuth()+requireRole()with valid/invalid/missing headers — 11 tests - 2B.12 Run
pnpm --filter @bytelyst/auth test— 25 tests pass (10 JWT + 3 password + 11 middleware + 4 E2E)
Integrate into LysnrAI services:
- 2B.13 platform-service
modules/auth/jwt.tsimports from@bytelyst/configfor product identity - 2B.14 platform-service auth tests pass (9 tests)
- 2B.15 Refactor tracker-service
lib/auth.ts→ 1-line re-export from@bytelyst/auth(was 48 lines) - 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):
- 2B.17 Add
@bytelyst/authdep to admin-dashboard-web (2-levelfile:path) - 2B.18 admin-dashboard
lib/auth-server.tsusescreateJwtUtils()+hashPassword()+getCurrentUser() - 2B.19 All admin API routes compile —
tsc --noEmitclean - 2B.20 admin-dashboard
next buildpasses - 2B.21 Add dep to user-dashboard-web
- 2B.22 user-dashboard
lib/auth-server.tsuses@bytelyst/authwith different issuer - 2B.23 user-dashboard
next buildpasses
Clean up old code:
- 2B.24 platform-service auth module uses
@bytelyst/authvia re-export pattern - 2B.25 tracker-service
lib/auth.tsis now a re-export from@bytelyst/auth - 2B.26 admin-dashboard
lib/auth-server.tsis thin wrapper around@bytelyst/auth - 2B.27 user-dashboard
lib/auth-server.tsis thin wrapper around@bytelyst/auth - 2B.28 E2E test: password verify → JWT issue → extractAuth → requireRole → role rejection (4 tests)
- 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:
- 2C.1 Create
packages/fastify-core/package.json(peer deps:fastify,@fastify/cors; dep:@bytelyst/errors) - 2C.2 Write
packages/fastify-core/src/create-app.ts—createServiceApp({ name, version, description })factory - 2C.3 x-request-id propagation built into
createServiceApp()(not separate file) - 2C.4 Health check route built into
createServiceApp()(not separate file) - 2C.5 ServiceError-aware error handler built into
createServiceApp() - 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 - 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 (404, 400 with details, 500)
- 2C.12 Write tests: x-request-id propagated when provided, generated as UUID when not
- 2C.13 Run
pnpm --filter @bytelyst/fastify-core test— 8 tests pass
Integrate into LysnrAI:
- 2C.14 Refactor platform-service
server.ts→createServiceApp()(91 → 39 lines) - 2C.15 Run platform-service tests — 55 tests pass
- 2C.16 Health endpoint verified via fastify-core tests
- 2C.17 Refactor billing-service (105 → 51 lines, keeps internal key auth hook)
- 2C.18 Refactor growth-service (83 → 33 lines)
- 2C.19 Refactor tracker-service (88 → 36 lines)
Clean up old code:
- 2C.20 Each
server.tsnow 33-51 lines (factory + routes + start) - 2C.21 All 4 service test suites pass — 170 service tests, 0 regressions
- 2C.22 Verify
services/monitoring/health-check.tsstill works with refactored health endpoints — confirmed working - 2C.23 Verify Docker builds for all 4 services
- 2C.24 Verify
docker-compose upstarts 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:
- 3A.1 Create
packages/api-client/package.json(no runtime deps) - 3A.2 Write
packages/api-client/src/client.ts—createApiClient({ baseUrl, getToken?, defaultHeaders? })→{ fetch, safeFetch } - 3A.3 Write
packages/api-client/src/types.ts—ApiResult<T>,ApiError,ApiClientConfig - 3A.4 Write
packages/api-client/src/index.ts - 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— 10 tests pass
Integrate into LysnrAI dashboards:
- 3A.10 admin-dashboard uses
createApiClient()—@bytelyst/api-clientinpackage.json - 3A.11 admin-dashboard
next buildpasses - 3A.12 user-dashboard uses
createApiClient()for billing, growth, platform clients - 3A.13 user-dashboard
next buildpasses - 3A.14 tracker-dashboard uses
createApiClient()for tracker client - 3A.15 tracker-dashboard
next buildpasses
Clean up old code:
- 3A.16 Dashboards use
@bytelyst/api-clientfactory — no duplicated fetch wrappers - 3A.17 All 3 dashboard builds pass —
tsc --noEmitclean
Commit: feat(api-client): extract @bytelyst/api-client shared package
3B — @bytelyst/react-auth
Extract:
- 3B.1 Create
packages/react-auth/package.json(peer deps:react, dep:@bytelyst/api-client) - 3B.2 Write
packages/react-auth/src/auth-context.tsx—createAuthProvider<TUser>({ storagePrefix, loginEndpoint, ... }) - 3B.3 Write
packages/react-auth/src/use-auth.ts— typeduseAuth()hook - 3B.4 Write
packages/react-auth/src/types.ts—BaseUser,AuthContextValue<TUser>,AuthConfig - 3B.5 Write
packages/react-auth/src/index.ts - 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, onLoginFallback, custom prefix
- 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):
- 3B.10 Add
@bytelyst/react-authdep to admin-dashboard-web (2-levelfile:path) - 3B.11 Refactor admin-dashboard-web
src/lib/auth-context.tsx→createAuthProvider<AdminUser>({ storagePrefix: "admin", onLoginFallback })(121 → 72 lines) - 3B.12 All admin consumer files compile —
tsc --noEmitclean (import path@/lib/auth-contextunchanged) - 3B.13 Admin dashboard type-checks clean
- 3B.14 Test login/logout flow manually in admin dashboard (requires running services)
- 3B.15 Add dep to user-dashboard-web —
tsc --noEmitclean - 3B.16 user-dashboard auth-context evaluated — keep custom (SSO cookies + register + updateUser too specialized)
- 3B.17 user-dashboard type-checks clean
- 3B.18 Run user-dashboard
next build— passes - 3B.19 Test login/logout + SSO flow manually in user dashboard (requires running services)
- 3B.20 Add dep to tracker-dashboard-web —
tsc --noEmitclean - 3B.21 tracker-dashboard auth-context evaluated — keep custom (token +
/api/auth/mesession restore too specialized) - 3B.22 tracker-dashboard type-checks clean
- 3B.23 Run tracker-dashboard build — passes (requires
--webpackflag, already in build script)
Clean up old code:
- 3B.24 admin-dashboard
auth-context.tsxusescreateAuthProvider()from@bytelyst/react-auth(withonLoginFallbackfor mock credentials) - 3B.25 user-dashboard
auth-context.tsx— keep custom; removed unused@bytelyst/react-authdep - 3B.26 tracker-dashboard
auth-context.tsx— keep custom; removed unused@bytelyst/react-authdep - 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:
- 4.1 Create
packages/design-tokens/package.json - 4.2 Migrate
mindlyst.tokens.json→packages/design-tokens/tokens/bytelyst.tokens.jsonas canonical source - 4.3 Write
packages/design-tokens/scripts/generate.ts— reads JSON, outputs 4 formats - 4.4 Generate
packages/design-tokens/generated/tokens.css(CSS custom properties--ml-*) - 4.5 Generate
packages/design-tokens/generated/tokens.ts(TypeScript constants) - 4.6 Generate
packages/design-tokens/generated/MindLystTokens.kt(Kotlin object) - 4.7 Generate
packages/design-tokens/generated/MindLystTheme.swift(Swift structs) - 4.8 Add
generatescript to package.json:tsx scripts/generate.ts
Test:
- 4.9 Write tests: generated CSS contains
--ml-*properties - 4.10 Write tests: generated TS exports token values
- 4.11 Write tests: generated Kotlin contains
object MindLystTokens - 4.12 Write tests: generated Swift contains MindLyst struct
- 4.13 Run
pnpm --filter @bytelyst/design-tokens test— 11 tests pass
Integrate into MindLyst:
- 4.14 Replace
mindlyst-native/shared/src/commonMain/.../theme/MindLystTokens.ktwith generated version - 4.15 KMP build verified (passes on home network, blocked behind SSL proxy)
- 4.16 ⚠️ G13: Android
MindLystTheme.ktconsumes generated tokens - 4.17 Android Compose theme references correct token values
- 4.18 Replace
iosApp/MindLystTheme.swiftwith generated version - 4.19 Web
globals.cssmirrors generated CSS custom properties - 4.20 Replace
design-system/web/mindlyst.csswith generated CSS — file has "Auto-generated from bytelyst.tokens.json" header - 4.21
cd web && npx next build— passes
Clean up old code:
- 4.22 Token source is now canonical in
bytelyst.tokens.json— generated outputs replace manual values - 4.23 Update MindLyst
CONTRIBUTING.mdwith 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.yml— build + test + typecheck + lint on push/PR to main (currentlyci.yml.disabled— billing paused) - 5.2 Add matrix strategy: 9 package tests + 4 service tests (parallel jobs, Node 20)
- 5.3 Type-check works:
pnpm typecheck(pnpm -r exec tsc --noEmit) — passes - 5.4 ESLint configured:
eslint.config.jsat root,pnpm lintworks
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(common plat) +scripts/docker-prep-dashboards.sh(LysnrAI) - 5.6 Add
.docker-deps/to.gitignorein LysnrAI repo - 5.7 Service Dockerfiles rewritten for pnpm monorepo (root context +
pnpm deploy) - 5.8 Update platform-service
Dockerfile— pnpm multi-stage build - 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(pre-copy + dummy env vars) - 5.13 Update user-dashboard-web
Dockerfile(pre-copy + dummy env vars) - 5.14 Update tracker-dashboard-web
Dockerfile(pre-copy) - 5.15
docker-compose.ymlupdated withcontext: .+dockerfile:paths - 5.16 Run
docker compose build— verified on home network - 5.17 Run
docker compose up -d— verified on home network
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–5.21 Service CI lives in common-plat (already has
ci.yml.disabledwith matrix strategy) — N/A for cross-repo checkout - 5.22 Dashboard CI workflows created with cross-repo checkout:
ci-admin-dashboard.yml.disabled,ci-user-dashboard.yml.disabled,ci-tracker-dashboard.yml.disabledupdated - 5.23 Cross-repo CI trigger:
trigger-consumers.yml.disableddispatchescommon-platform-updatedevent to LysnrAI + MindLyst repos (requiresCROSS_REPO_PATsecret)
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
- 6.1 Run all Python tests: 652 pass, 5 pre-existing Pydantic failures (
python3 -m pytest tests/ backend/tests/ -v --tb=short) - 6.2 Run all platform-service tests: 55 tests pass
- 6.3 Run all billing-service tests: 32 tests pass
- 6.4 Run all growth-service tests: 33 tests pass
- 6.5 Run all tracker-service tests: 50 tests pass
- 6.6 Build admin-dashboard:
tsc --noEmitclean - 6.7 Build user-dashboard:
tsc --noEmitclean - 6.8 Build tracker-dashboard:
tsc --noEmitclean - 6.9 Build MindLyst KMP: blocked behind SSL proxy (passes on home network)
- 6.10 Build MindLyst web:
npx next buildpasses - 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
- 6.18 Update LysnrAI
AGENTS.md—@bytelyst/*packages in file ownership map + dashboard wiring - 6.19 Update LysnrAI
README_MONO_REPO.md— documents common-plat dependency - 6.20 Update LysnrAI
docs/API_REFERENCE.md— added shared platform services section + dashboard→service client wiring - 6.21 Update MindLyst
AGENTS.md— references design-tokens package - 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 - 6.24 Update this
ROADMAP.md— statuses updated (this commit)
Code Cleanup
- 6.25 Search LysnrAI for duplicated files — all
cosmos.ts/auth.tsuse@bytelyst/*, no raw error classes - 6.26 Removed unused
@bytelyst/react-authdep from user-dashboard + tracker-dashboardpackage.json - 6.27 Run depcheck across all packages + dashboards — unused deps removed (react-auth from user/tracker, date-fns/stripe from admin, etc.)
- 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/blobpackage (extract blob storage client + SAS generation) - 7.5 Add
@bytelyst/monitoringpackage (health check aggregator) - 7.6 Add
@bytelyst/testingpackage (shared test utilities, mock factories) — created with 10 tests - 7.7 Evaluate Python shared package for
cosmos_client.py+blob_client.pyif MindLyst adds Python backend - 7.8 Integrate
@bytelyst/design-tokensinto LysnrAI dashboards (unified design language) - 7.9 Add pre-commit hooks to auto-run token generation when JSON changes — lint-staged rule on
bytelyst.tokens.json - 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 | 23 | ✅ CSS synced to MindLyst; CONTRIBUTING updated; visual verify pending |
| 5 | CI/CD + Docker (pre-copy strategy) | 23 | 23 | ✅ Docker build + compose up verified on home network |
| 6 | Verification + docs + cleanup | 28 | 25 | ⚠️ Remaining E2E: admin + user portal flows |
| 7 | Future enhancements (+testing pkg) | 10 | 3 | 🔲 @bytelyst/testing (10 tests) + token pre-commit hook + AGENTS updated |
| Total | 10 packages (+1 bonus: logger) | 278 | 257 | ~92% complete |
Bonus Package (not in original roadmap)
@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