learning_ai_common_plat/docs/ROADMAP.md
saravanakumardb1 69f18f2588 docs: add detailed phased roadmap with task checklists
- 7 phases (0-6 + future): scaffolding, P0 packages, P1 packages, P2 packages, design tokens, CI/CD, verification
- ~150 checkboxed tasks covering extract, test, integrate, cleanup, Docker, and docs
- Dependency-ordered execution: errors → cosmos → config → auth → fastify-core → api-client → react-auth → design-tokens
- Estimated ~28-41 hours total effort
2026-02-12 10:48:38 -08:00

25 KiB
Raw Blame History

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 · ECOSYSTEM_ARCHITECTURE.md · ecosystem-after-refactor.drawio


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.

  • 0.1 Initialize package.json at repo root ("private": true, "name": "@bytelyst/root")
  • 0.2 Add pnpm-workspace.yaml declaring packages/* as workspace members
  • 0.3 Create tsconfig.base.json with shared compiler options (ESM, strict, target ES2022, module NodeNext)
  • 0.4 Add shared vitest.config.ts at repo root
  • 0.5 Add .gitignore (node_modules, dist, coverage, .DS_Store)
  • 0.6 Add .nvmrc matching LysnrAI's Node version
  • 0.7 Add README.md with repo purpose, package list, and quick-start
  • 0.8 Add CONTRIBUTING.md with conventions (commit format, PR process, testing expectations)
  • 0.9 Verify: pnpm install succeeds, pnpm -r build succeeds (empty packages OK)

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.json extending ../../tsconfig.base.json
  • 1A.3 Write packages/errors/src/service-error.ts — base ServiceError class with optional details
  • 1A.4 Write packages/errors/src/http-errors.tsNotFoundError, 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 — verify statusCode, message, instanceof, details field
  • 1A.8 Run pnpm --filter @bytelyst/errors test — all pass

Integrate into LysnrAI:

  • 1A.9 Add "@bytelyst/errors": "file:../../../learning_ai_common_plat/packages/errors" to services/platform-service/package.json
  • 1A.10 Replace import { ServiceError, ... } from "./lib/errors.js"from "@bytelyst/errors" in platform-service
  • 1A.11 Run platform-service tests — all pass
  • 1A.12 Repeat 1A.91A.11 for billing-service
  • 1A.13 Repeat 1A.91A.11 for growth-service
  • 1A.14 Repeat 1A.91A.11 for tracker-service

Clean up old code:

  • 1A.15 Delete services/platform-service/src/lib/errors.ts
  • 1A.16 Delete services/billing-service/src/lib/errors.ts
  • 1A.17 Delete services/growth-service/src/lib/errors.ts
  • 1A.18 Delete services/tracker-service/src/lib/errors.ts
  • 1A.19 Run all 4 service test suites — confirm no regressions
  • 1A.20 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.tsgetCosmosClient(), getDatabase(), getContainer()
  • 1B.4 Write packages/cosmos/src/containers.tsregisterContainers(), initializeAllContainers(), ContainerConfig
  • 1B.5 Write packages/cosmos/src/types.tsContainerConfig interface
  • 1B.6 Write packages/cosmos/src/index.ts — barrel export
  • 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 — all pass

Integrate into LysnrAI services (simple client):

  • 1B.11 Add dep + replace imports in platform-service src/lib/cosmos.ts
  • 1B.12 Run platform-service tests — all pass
  • 1B.13 Repeat for billing-service
  • 1B.14 Repeat for growth-service
  • 1B.15 Repeat for tracker-service

Integrate into LysnrAI dashboards (client + registry):

  • 1B.16 Add dep + replace imports in admin-dashboard-web src/lib/cosmos.ts — keep container definitions as registerContainers() call
  • 1B.17 Run next build for admin-dashboard — passes
  • 1B.18 Add dep + replace imports in user-dashboard-web src/lib/cosmos.ts
  • 1B.19 Run next build for user-dashboard — passes

Clean up old code:

  • 1B.20 Delete services/platform-service/src/lib/cosmos.ts
  • 1B.21 Delete services/billing-service/src/lib/cosmos.ts
  • 1B.22 Delete services/growth-service/src/lib/cosmos.ts
  • 1B.23 Delete services/tracker-service/src/lib/cosmos.ts
  • 1B.24 Reduce admin-dashboard-web/src/lib/cosmos.ts to just container config + registerContainers() call
  • 1B.25 Reduce user-dashboard-web/src/lib/cosmos.ts to just container config + registerContainers() call
  • 1B.26 Run all service tests + next build for both dashboards — no regressions
  • 1B.27 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.tsbaseEnvSchema (PORT, HOST, NODE_ENV, CORS_ORIGIN, SERVICE_NAME, COSMOS_ENDPOINT, COSMOS_KEY, COSMOS_DATABASE)
  • 2A.3 Write packages/config/src/loader.tsloadConfig(extension?) function
  • 2A.4 Write packages/config/src/product-identity.tsloadProductIdentity() reads product.json or 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 (file + env fallback)
  • 2A.9 Run pnpm --filter @bytelyst/config test — all pass

Integrate into LysnrAI:

  • 2A.10 Refactor platform-service config.ts → import loadConfig() + extend with service-specific fields only
  • 2A.11 Replace product-config.ts imports with loadProductIdentity() in platform-service
  • 2A.12 Run platform-service tests — all pass
  • 2A.13 Repeat for billing-service (extend with STRIPE_, BILLING_)
  • 2A.14 Repeat for growth-service (extend with STRIPE_, WEBHOOK_)
  • 2A.15 Repeat for tracker-service (extend with JWT_SECRET, DEFAULT_PRODUCT_ID)

Clean up old code:

  • 2A.16 Delete 4× config.ts (service-specific parts stay as extension schemas)
  • 2A.17 Delete 4× product-config.ts
  • 2A.18 Run all service tests — no regressions
  • 2A.19 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, dep: @bytelyst/config)
  • 2B.2 Write packages/auth/src/jwt.tscreateJwtUtils({ issuer, accessTokenExpiry, refreshTokenExpiry })
  • 2B.3 Write packages/auth/src/middleware.tsextractAuth() Fastify hook, requireRole() guard
  • 2B.4 Write packages/auth/src/server-auth.tsgetCurrentUser() for Next.js API routes
  • 2B.5 Write packages/auth/src/password.tshashPassword(), verifyPassword()
  • 2B.6 Write packages/auth/src/types.tsAuthPayload, TokenPayload interfaces
  • 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
  • 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 — all pass

Integrate into LysnrAI services:

  • 2B.13 Refactor platform-service modules/auth/jwt.ts → use createJwtUtils({ issuer: "lysnrai" })
  • 2B.14 Run platform-service auth tests — all pass
  • 2B.15 Refactor tracker-service lib/auth.ts → use extractAuth() + requireRole()
  • 2B.16 Run tracker-service tests — all pass

Integrate into LysnrAI dashboards:

  • 2B.17 Refactor admin-dashboard-web lib/auth-server.ts → use createJwtUtils() + hashPassword() + getCurrentUser()
  • 2B.18 Run admin-dashboard next build — passes
  • 2B.19 Refactor user-dashboard-web lib/auth-server.ts → same as above with different issuer
  • 2B.20 Run user-dashboard next build — passes

Clean up old code:

  • 2B.21 Delete/reduce platform-service/src/modules/auth/jwt.ts (keep only route handlers, not JWT logic)
  • 2B.22 Delete tracker-service/src/lib/auth.ts
  • 2B.23 Reduce admin-dashboard-web/src/lib/auth-server.ts to thin wrapper calling @bytelyst/auth
  • 2B.24 Reduce user-dashboard-web/src/lib/auth-server.ts to thin wrapper calling @bytelyst/auth
  • 2B.25 CRITICAL: End-to-end test: login → get token → call authenticated endpoint → verify across all consumers
  • 2B.26 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.tscreateServiceApp({ 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.tsServiceError-aware error handler
  • 2C.6 Write packages/fastify-core/src/start.tsstartService(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.tscreateServiceApp() + 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:

  • 3A.1 Create packages/api-client/package.json (no runtime deps)
  • 3A.2 Write packages/api-client/src/client.tscreateApiClient({ baseUrl, getToken?, defaultHeaders? }){ fetch, safeFetch }
  • 3A.3 Write packages/api-client/src/types.tsApiResult<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 — all pass

Integrate into LysnrAI dashboards:

  • 3A.10 Refactor admin-dashboard-web src/lib/api.ts — use createApiClient(), keep domain methods (apiLogin, apiListUsers, etc.)
  • 3A.11 Run admin-dashboard next build — passes
  • 3A.12 Refactor user-dashboard-web client files (platform-client.ts, billing-client.ts, growth-client.ts)
  • 3A.13 Run user-dashboard next build — passes
  • 3A.14 Refactor tracker-dashboard-web src/lib/tracker-client.ts
  • 3A.15 Run tracker-dashboard next build — passes

Clean up old code:

  • 3A.16 Remove duplicated apiFetch / request base functions from each dashboard (domain methods stay)
  • 3A.17 Run all 3 dashboard builds — no regressions

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.tsxcreateAuthProvider<TUser>({ storagePrefix, loginEndpoint, ... })
  • 3B.3 Write packages/react-auth/src/use-auth.ts — typed useAuth() hook
  • 3B.4 Write packages/react-auth/src/types.tsBaseUser, 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
  • 3B.9 Run pnpm --filter @bytelyst/react-auth test — all pass

Integrate into LysnrAI dashboards:

  • 3B.10 Refactor admin-dashboard-web src/lib/auth-context.tsxcreateAuthProvider<AdminUser>({ storagePrefix: "admin", ... })
  • 3B.11 Run admin-dashboard next build — passes
  • 3B.12 Test login/logout flow manually in admin dashboard
  • 3B.13 Refactor user-dashboard-web src/lib/auth-context.tsxcreateAuthProvider<PortalUser>({ storagePrefix: "portal", enableSSO: true, ... })
  • 3B.14 Run user-dashboard next build — passes
  • 3B.15 Test login/logout + SSO flow manually in user dashboard
  • 3B.16 Refactor tracker-dashboard-web auth context → createAuthProvider<TrackerUser>({ storagePrefix: "tracker", ... })
  • 3B.17 Run tracker-dashboard build — passes

Clean up old code:

  • 3B.18 Delete admin-dashboard-web/src/lib/auth-context.tsx (replaced by imported provider)
  • 3B.19 Delete user-dashboard-web/src/lib/auth-context.tsx
  • 3B.20 Reduce tracker-dashboard auth context to thin config file
  • 3B.21 Run all 3 dashboard builds — no regressions
  • 3B.22 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:

  • 4.1 Create packages/design-tokens/package.json
  • 4.2 Migrate mindlyst.tokens.jsonpackages/design-tokens/tokens/bytelyst.tokens.json as 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 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 — all pass

Integrate into MindLyst:

  • 4.14 Replace mindlyst-native/shared/.../theme/MindLystTokens.kt with generated version
  • 4.15 Verify KMP build: ./gradlew :shared:compileKotlinIosSimulatorArm64
  • 4.16 Replace iosApp/MindLystTheme.swift with generated version
  • 4.17 Replace web/src/styles/globals.css token section with import of generated CSS
  • 4.18 Replace design-system/web/mindlyst.css with generated CSS
  • 4.19 Run cd web && npx next build — passes

Clean up old code:

  • 4.20 Remove manually-maintained token values from MindLyst (now auto-generated)
  • 4.21 Update MindLyst CONTRIBUTING.md with token update workflow (edit JSON → run generate → commit)
  • 4.22 Verify visual consistency: spot-check colors in iOS 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
  • 5.3 Add type-check step (pnpm -r exec tsc --noEmit)
  • 5.4 Add lint step (if eslint/biome is added)

Docker Build Compatibility

  • 5.5 Update platform-service Dockerfile to copy common-plat packages into build context
  • 5.6 Update billing-service Dockerfile
  • 5.7 Update growth-service Dockerfile
  • 5.8 Update tracker-service Dockerfile
  • 5.9 Update admin-dashboard-web Dockerfile
  • 5.10 Update user-dashboard-web Dockerfile
  • 5.11 Update tracker-dashboard-web Dockerfile (if exists)
  • 5.12 Update docker-compose.yml build contexts if needed (may need to widen to parent dir)
  • 5.13 Run docker compose build — all images build successfully
  • 5.14 Run docker compose up -d — all services start and pass health checks

Consumer CI Updates

  • 5.15 Update ci-platform-service.yml — install common-plat deps before test
  • 5.16 Update ci-billing-service.yml
  • 5.17 Update ci-growth-service.yml
  • 5.18 Update ci-tracker-service.yml
  • 5.19 Update dashboard CI workflows (if they exist)

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: python -m pytest tests/ backend/tests/ -v --tb=short
  • 6.2 Run all platform-service tests: cd services/platform-service && npm test
  • 6.3 Run all billing-service tests: cd services/billing-service && npm test
  • 6.4 Run all growth-service tests: cd services/growth-service && npm test
  • 6.5 Run all tracker-service tests: cd services/tracker-service && npm test
  • 6.6 Build admin-dashboard: cd admin-dashboard-web && npx next build
  • 6.7 Build user-dashboard: cd user-dashboard-web && npx next build
  • 6.8 Build tracker-dashboard: cd tracker-dashboard-web && npx next build
  • 6.9 Build MindLyst KMP: ./gradlew :shared:compileKotlinIosSimulatorArm64
  • 6.10 Build MindLyst web: cd web && npx next build
  • 6.11 Run common-plat tests: pnpm -r test
  • 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 — add @bytelyst/* packages to file ownership map
  • 6.19 Update LysnrAI README_MONO_REPO.md — document common-plat dependency
  • 6.20 Update LysnrAI docs/API_REFERENCE.md — note shared auth/errors
  • 6.21 Update MindLyst AGENTS.md — reference design-tokens package
  • 6.22 Update common-plat README.md — package API reference, usage examples
  • 6.23 Write docs/MIGRATION_GUIDE.md — step-by-step for adopting @bytelyst/* in a new project
  • 6.24 Update this ROADMAP.md — mark all tasks as complete

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 Est. Effort Risk Level
0 Repo scaffolding 12 hours None
1 errors + cosmos 46 hours Low
2 config + auth + fastify-core 812 hours Medium
3 api-client + react-auth 57 hours Medium
4 design-tokens 46 hours Low
5 CI/CD + Docker 34 hours Medium
6 Verification + docs 34 hours Low
7 Future enhancements Ongoing
Total 8 packages ~2841 hours

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

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.