learning_ai_common_plat/docs/ROADMAP.md
saravanakumardb1 90b9cf93d8 fix(common): configure ESLint 9 and fix lint issues
- Added @eslint/js dependency
- Updated eslint.config.js for ESLint 9 compatibility
- Added required globals (crypto, localStorage, React, etc.)
- Fixed unused imports and variables
- Disabled sort-imports temporarily
- Formatted all files with Prettier
2026-02-12 16:37:30 -08:00

40 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


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

  • 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 .editorconfig matching LysnrAI conventions
  • 0.8 Add README.md with repo purpose, package list, and quick-start
  • 0.9 Add CONTRIBUTING.md with conventions (commit format, PR process, testing expectations)
  • 0.10 Verify: pnpm install succeeds, pnpm -r build succeeds (empty packages OK)

Branching & file: Reference Strategy

  • 0.11 Create feat/common-plat-extraction branch in all 3 repos — all migration work happens here, merge to main per-phase
  • 0.12 Document the file: reference path table (all repos must be cloned side-by-side under the 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 Establish rollback rule: each phase is done on a branch. If tests fail after integration, git stash consumer changes and revert to local lib/ imports. The shared package stays in common-plat for the next attempt.
  • 0.14 Never delete old lib/*.ts files until all consumers have been migrated and tested in the same phase

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 (⚠️ G1: errors is imported in 22 route files + 4 server.ts, not just lib/):

  • 1A.9 Add "@bytelyst/errors": "file:../../../learning_ai_common_plat/packages/errors" to services/platform-service/package.json
  • 1A.10 Replace from "./lib/errors.js"from "@bytelyst/errors" in server.ts
  • 1A.11 Replace from "../../lib/errors.js"from "@bytelyst/errors" in all 6 route files (auth, audit, blob, flags, notifications, ratelimit)
  • 1A.12 Run pnpm install in platform-service (regenerates lock file)
  • 1A.13 Run platform-service tests — all pass
  • 1A.14 Repeat for billing-serviceserver.ts + 5 route files (subscriptions, usage, plans, licenses, stripe)
  • 1A.15 Repeat for growth-serviceserver.ts + 3 route files (invitations, referrals, promos)
  • 1A.16 Repeat for tracker-serviceserver.ts + lib/auth.ts + 4 route files (items, comments, votes, public)

Clean up old code:

  • 1A.17 Delete services/platform-service/src/lib/errors.ts
  • 1A.18 Delete services/billing-service/src/lib/errors.ts
  • 1A.19 Delete services/growth-service/src/lib/errors.ts
  • 1A.20 Delete services/tracker-service/src/lib/errors.ts
  • 1A.21 ⚠️ G2: Update or delete existing error test files that import from local path:
    • services/platform-service/src/lib/errors.test.ts → update import to @bytelyst/errors or delete (tests now in shared package)
    • services/growth-service/src/lib/errors.test.ts → same
    • services/tracker-service/src/lib/errors.test.ts → same
  • 1A.22 Run all 4 service test suites — confirm 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.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 (⚠️ G1: cosmos is imported in 13 repository files, not just lib/):

  • 1B.11 Add "@bytelyst/cosmos": "file:../../../learning_ai_common_plat/packages/cosmos" to platform-service package.json + pnpm install
  • 1B.12 Replace from "../../lib/cosmos.js"from "@bytelyst/cosmos" in 4 repository files (auth, audit, flags, notifications)
  • 1B.13 Run platform-service tests — all pass
  • 1B.14 Repeat for billing-service4 repository files (subscriptions, usage, plans, licenses)
  • 1B.15 Repeat for growth-service2 repository files (invitations, referrals)
  • 1B.16 Repeat for tracker-service3 repository files (items, comments, votes)

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 package.json (⚠️ G7: 2 levels, not 3)
  • 1B.18 Refactor admin-dashboard-web/src/lib/cosmos.ts — keep container definitions as registerContainers() call using @bytelyst/cosmos
  • 1B.19 Rewire 5 admin repositories that import ../cosmos: users.ts, tokens.ts, audit.ts, usage.ts, theme.ts
  • 1B.20 Run pnpm install + next build for admin-dashboard — passes
  • 1B.21 Add dep to user-dashboard-web package.json (2 levels: file:../../...)
  • 1B.22 Refactor user-dashboard-web/src/lib/cosmos.ts — same pattern
  • 1B.23 Rewire 3 user repositories that import ../cosmos: users.ts, settings.ts, transcripts.ts
  • 1B.24 Rewire 2 user API routes that import cosmos: api/health/route.ts, api/seed/route.ts
  • 1B.25 Run pnpm install + next build for user-dashboard — passes

Clean up old code:

  • 1B.26 Delete services/platform-service/src/lib/cosmos.ts
  • 1B.27 Delete services/billing-service/src/lib/cosmos.ts
  • 1B.28 Delete services/growth-service/src/lib/cosmos.ts
  • 1B.29 Delete services/tracker-service/src/lib/cosmos.ts
  • 1B.30 Reduce admin-dashboard-web/src/lib/cosmos.ts to just container registry config (no client code)
  • 1B.31 Reduce user-dashboard-web/src/lib/cosmos.ts to just container registry config (no client code)
  • 1B.32 Run all service tests + next build for both dashboards — 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.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 services (⚠️ G1: product-config is imported in 34 files across services + dashboards):

  • 2A.10 Refactor platform-service config.ts → import loadConfig() + extend with service-specific fields only
  • 2A.11 Replace from "../../lib/product-config.js"from "@bytelyst/config" in 7 files (auth routes, audit routes, flags routes, notifications routes, ratelimit routes, auth repository, auth jwt.ts)
  • 2A.12 Run pnpm install + platform-service tests — all pass
  • 2A.13 Repeat for billing-service — extend config with STRIPE**, BILLING**; rewire 10 files (5 routes + 5 repositories) that import product-config
  • 2A.14 Repeat for growth-service — extend config with STRIPE**, WEBHOOK**; rewire 4 files (3 routes + lib/webhooks.ts) (⚠️ G6)
  • 2A.15 Repeat for tracker-service — extend config with JWT_SECRET, DEFAULT_PRODUCT_ID; rewire 2 files (items routes, public routes)

Integrate into LysnrAI dashboards (⚠️ G4/G5):

  • 2A.16 Add @bytelyst/config dep to admin-dashboard-web (2-level file: path)
  • 2A.17 Rewire 7 admin API route files that import product-config: seed, users, tokens, kill-switch, analytics/retention, invitations, referrals (they use PRODUCT_ID)
  • 2A.18 Rewire 2 admin repository files that import product-config: users.ts, tokens.ts
  • 2A.19 Run pnpm install + next build for admin-dashboard — passes
  • 2A.20 ⚠️ G3: Add dep to user-dashboard-web — this is the 5th copy of product-config.ts (15 lines)
  • 2A.21 Run pnpm install + next build for user-dashboard — passes

Clean up old code:

  • 2A.22 Delete 5× product-config.ts (4 services + user-dashboard)
  • 2A.23 Reduce 4× service config.ts to thin extension schemas (~5 lines each)
  • 2A.24 Run all service tests + both dashboard builds — 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 — JWT reads JWT_SECRET directly from process.env)
  • 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 (⚠️ auth-server.ts is imported by 20 admin API routes and multiple user API routes):

  • 2B.17 Add @bytelyst/auth dep to admin-dashboard-web (2-level file: path) + pnpm install
  • 2B.18 Refactor admin-dashboard-web lib/auth-server.ts → use createJwtUtils() + hashPassword() + getCurrentUser()
  • 2B.19 Verify all 20 admin API route files that import { ... } from "@/lib/auth-server" still compile (import path stays same, only internals change)
  • 2B.20 Run admin-dashboard next build — passes
  • 2B.21 Add dep to user-dashboard-web + pnpm install
  • 2B.22 Refactor user-dashboard-web lib/auth-server.ts → same as above with different issuer
  • 2B.23 Run user-dashboard next build — passes

Clean up old code:

  • 2B.24 Delete/reduce platform-service/src/modules/auth/jwt.ts (keep only route handlers, not JWT logic)
  • 2B.25 Delete tracker-service/src/lib/auth.ts
  • 2B.26 Reduce admin-dashboard-web/src/lib/auth-server.ts to thin wrapper calling @bytelyst/auth
  • 2B.27 Reduce user-dashboard-web/src/lib/auth-server.ts to thin wrapper calling @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.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 (⚠️ 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.tsxcreateAuthProvider<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.tsxcreateAuthProvider<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:

  • 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/src/commonMain/.../theme/MindLystTokens.kt with generated version
  • 4.15 Verify KMP build: ./gradlew :shared:compileKotlinIosSimulatorArm64
  • 4.16 ⚠️ G13: Update androidApp/src/main/java/.../ui/theme/MindLystTheme.kt (Compose theme) to consume generated tokens — this file was missing from original plan
  • 4.17 Verify Android Compose theme still references correct token values (color names may change)
  • 4.18 Replace iosApp/MindLystTheme.swift with generated version
  • 4.19 Replace web/src/styles/globals.css token section with import of generated CSS
  • 4.20 Replace design-system/web/mindlyst.css with generated CSS
  • 4.21 Run cd web && npx next build — passes

Clean up old code:

  • 4.22 Remove manually-maintained token values from MindLyst (now auto-generated)
  • 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
  • 5.3 Add type-check step (pnpm -r exec tsc --noEmit)
  • 5.4 Add lint step (if eslint/biome is added)

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:
    # 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)
  • 5.15 Update docker-compose.yml — add scripts/docker-prep.sh as a pre-build step or use a Makefile target
  • 5.16 Run docker compose build — all images build successfully
  • 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

  • 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 Tasks Est. Effort Risk Level
0 Repo scaffolding + branching + rollback strategy 14 23 hours None
1A @bytelyst/errors 23 34 hours Low
1B @bytelyst/cosmos 33 45 hours Low
2A @bytelyst/config (34 files to rewire) 25 45 hours Medium
2B @bytelyst/auth (20+ admin routes affected) 29 46 hours Medium-High
2C @bytelyst/fastify-core 24 34 hours Medium
3A @bytelyst/api-client 17 23 hours Low
3B @bytelyst/react-auth (24 consumer files) 28 45 hours Medium
4 @bytelyst/design-tokens (4 platforms) 24 46 hours Low
5 CI/CD + Docker (pre-copy strategy) 23 46 hours Medium-High
6 Verification + docs + cleanup 28 34 hours Low
7 Future enhancements 10 Ongoing
Total 8 packages ~278 ~3751 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
                                                     (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