learning_ai_common_plat/docs/UNIFIED_BYTELYST_PORTAL_ROADMAP.md
saravanakumardb1 edf8926d6d fix(docs): self-audit Portal PRD + roadmap — 15 findings corrected
Review Errata (15 findings):
- F1-F2: Product count 11→10 (ByteLyst Auth has no backend)
- F3: product.json count 4→3 missing (FlowMonk, ActionTrail, LocalMemGPT)
- F4: Architecture diagram spacing fixes
- F5: Remove portalLayout from GlobalPreferences (contradicted separate Cosmos container)
- F6-F7: Widget endpoint unified to /widgets/:widgetId/data + added layout CRUD endpoints
- F8: Verified all 10 feed source endpoints against actual backend route files
- F9: Added @bytelyst/datastore to BFF tech stack
- F10: Added Cosmos containers section (portal_widget_layouts)
- F11: Global prefs dependency Phase 2→Phase 5 blocker
- F12: Removed emojis from search example
- F13: Added quick-actions task to roadmap Phase 1
- F14: Added 4 missing scaffold tasks (errors, datastore, cosmos-init, vitest)
- F15: Corrected run-local-all-services.sh location
- Updated task totals: 124→129
2026-03-21 20:57:28 -07:00

30 KiB

Unified ByteLyst Portal — Roadmap & Task List

Date: 2026-03-21 · Companion to: UNIFIED_BYTELYST_PORTAL_PRD.md Estimated total: 8 phases · ~129 tasks · 6-8 weeks


Phase 0: Repo Scaffold & Foundations (2 days)

Goal: Repo exists, builds, deploys to dev. BFF starts and returns health check. Web renders shell.

# Task Type Est Notes
0.1 Create learning_ai_portal repo with standard structure infra 1h backend/, web/, shared/, docs/, AGENTS.md
0.2 Create shared/product.json (id: portal, port: 4020/3010) config 15m Follow existing product.json pattern
0.3 Create products/portal/product.json in common-plat config 15m Register portal in product registry
0.4 Scaffold BFF with @bytelyst/fastify-core (port 4020) backend 1h createServiceApp() + health endpoint
0.5 Add lib/config.ts -- Zod-validated env (JWT_SECRET, PLATFORM_URL, product backend URLs) backend 30m
0.6 Add lib/product-config.ts -- load from shared/product.json backend 15m
0.7 Add lib/auth.ts -- JWT extraction + portal scope validation backend 30m
0.8 Add lib/request-context.ts -- getUserId(req), getUserMemberships(req) backend 30m
0.9 Add lib/product-registry.ts -- load all product.json files, build registry backend 1h Read from ../../products/*/product.json or env-injected
0.10 Add lib/product-client.ts -- service-to-service HTTP client for product backends backend 1h Timeout, circuit breaker, x-user-id header
0.11 Add lib/errors.ts -- re-export from @bytelyst/errors backend 10m Standard pattern across all product backends
0.12 Add lib/datastore.ts -- @bytelyst/datastore provider (Cosmos or memory via DB_PROVIDER) backend 30m Required for widget layout persistence
0.13 Add lib/cosmos-init.ts -- register portal_widget_layouts container on startup backend 30m Partition: /userId
0.14 Add vitest.config.ts + test-helpers.ts -- Vitest config + buildTestApp() helper backend 30m Standard test scaffold
0.15 Scaffold web with Next.js 16 + @bytelyst/dashboard-shell (port 3010) web 1h App Router, TailwindCSS v4, --portal-* CSS props
0.16 Add web/src/lib/product-config.ts -- product identity + API URLs web 15m
0.17 Add web/src/lib/auth.ts -- @bytelyst/react-auth provider web 30m Cookie-based auth
0.18 Add web/src/lib/api.ts -- typed fetch client for BFF web 30m
0.19 Add web/src/app/layout.tsx + providers.tsx -- shell + auth + telemetry web 30m
0.20 Create AGENTS.md with project conventions docs 30m
0.21 Create .github/workflows/ci.yml -- typecheck + test for backend + web infra 30m
0.22 Verify: cd backend && npm test && npm run typecheck passes test 15m
0.23 Verify: cd web && npm run typecheck && npm run build passes test 15m

Phase 0 deliverable: Repo builds, BFF returns GET /health, web renders empty shell with sidebar. (23 tasks)


Phase 1: Product Launcher & Auth (3 days)

Goal: User can log in, see all their products, and launch any product dashboard.

# Task Type Est Notes
1.1 BFF: GET /api/portal/products -- fetch user memberships from platform-service /auth/me, enrich with product.json metadata backend 2h Returns { products: [{ id, name, icon, plan, role, dashboardUrl, lastActiveAt }] }
1.2 BFF: POST /api/portal/products/:id/switch -- re-issue JWT with new active productId backend 1h
1.3 BFF: service-to-service auth setup -- API key registration for portal-to-product-backend calls backend 2h Register portal as a service consumer in platform-service
1.4 Web: /login page -- email/password + OAuth buttons via @bytelyst/react-auth web 2h Redirect to / on success
1.5 Web: (app)/layout.tsx -- authenticated route group with DashboardShell web 1h Sidebar nav: Home, Products, Activity, Search, Billing, Settings, Security
1.6 Web: Sidebar.tsx -- portal sidebar with product icons + nav sections web 1h
1.7 Web: /products page -- product launcher grid web 3h Card per product: icon, name, plan badge, last active, "Open" button
1.8 Web: ProductCard.tsx component -- product card with theme colors from product.json web 1h
1.9 Web: / redirect to /products (temporary, until dashboard is built in Phase 3) web 15m
1.10 Web: product launch handler -- opens product dashboard in new tab with session context web 1h Deep link: https://{domain}/?portal=true
1.11 Web: show "Get Started" CTA for products user hasn't signed up for web 1h Links to product landing page
1.12 Test: BFF products endpoint returns correct memberships test 1h Vitest
1.13 BFF: GET /api/portal/quick-actions -- available quick actions per product from product registrations backend 1h Static config in product.json + optional dynamic from backends
1.14 Test: Login flow to product grid to launch works E2E test 1h Playwright

Phase 1 deliverable: User logs in, sees grid of their products with status, can open any product in a new tab.


Phase 2: Activity Feed & Notifications (3 days)

Goal: User sees a chronological feed of recent actions across all products.

# Task Type Est Notes
2.1 BFF: lib/feed-aggregator.ts -- parallel fan-out to product backends with timeout + circuit breaker backend 3h 3s timeout per product, fail-open
2.2 BFF: Define FeedEvent schema + product-specific event mappers backend 2h One mapper per product that normalizes response into FeedEvent
2.3 BFF: GET /api/portal/feed -- aggregated feed with pagination (?cursor=&limit=50) backend 2h Merge-sort by createdAt desc
2.4 BFF: In-memory cache (60s TTL per user) for feed data backend 1h
2.5 BFF: GET /api/portal/notifications -- aggregate from platform-service notifications backend 1h
2.6 Web: /activity page -- full-page activity timeline web 3h Filter by product, date range, event type
2.7 Web: FeedCard.tsx -- event card with product icon, title, timestamp, deep link web 1h
2.8 Web: FeedFilters.tsx -- product multi-select, date range picker web 1h
2.9 Web: Activity feed widget on / home page (compact view, last 10 items) web 1h
2.10 Web: Notification bell in top bar -- badge count + dropdown web 2h
2.11 Product backends: Verify each backend has a "recent items" list endpoint backend 2h Add missing endpoints where needed
2.12 Test: Feed aggregation with 3 products up, 2 down test 1h Circuit breaker test
2.13 Test: Feed pagination, sorting, filtering test 1h

Phase 2 deliverable: /activity page shows chronological feed from all products. Home page shows compact feed.


Phase 3: Widget Dashboard (4 days)

Goal: Home page is a customizable widget grid. Users can add/remove/resize widgets.

# Task Type Est Notes
3.1 BFF: modules/widgets/types.ts -- WidgetDefinition, WidgetLayout schemas backend 1h
3.2 BFF: modules/widgets/repository.ts -- CRUD for user widget layouts in Cosmos backend 2h Container: portal_widget_layouts, partition: /userId
3.3 BFF: modules/widgets/routes.ts -- GET/PUT layout, GET widget definitions backend 2h
3.4 BFF: GET /api/portal/widgets/:widgetId/data -- fetch widget data from product backend backend 2h Route to correct product backend based on widgetId prefix
3.5 BFF: Register 20+ widget definitions (from PRD section 5.4) backend 2h Static definitions loaded at startup
3.6 BFF: Cosmos container registration for portal_widget_layouts backend 30m
3.7 Web: / home page with widget grid layout (CSS Grid) web 3h Fixed grid for v1, drag-and-drop in Phase 8
3.8 Web: WidgetShell.tsx -- generic widget wrapper (header, loading, error, resize) web 2h
3.9 Web: WidgetPicker.tsx -- modal to add widgets from catalog web 2h Grouped by product
3.10 Web: Implement 5 priority widgets: ChronoMind next-timer, NomGap fast-progress, FlowMonk today-schedule, NoteLett recent-notes, Portal billing-summary web 4h ~45m each
3.11 Web: Implement 5 more widgets: LysnrAI recent-transcripts, MindLyst recent-captures, JarvisJr coaching-streak, ActionTrail recent-actions, PeakPulse weekly-stats web 4h
3.12 Web: Implement remaining 11 widgets web 5h
3.13 Web: useWidgetData(widgetId) hook -- fetch + cache + loading/error states web 1h
3.14 Web: Default widget layout for new users (6 widgets: feed + 5 most-active products) web 1h
3.15 Web: Save layout changes to BFF via PUT /api/portal/widgets/layout web 1h Debounced save
3.16 Test: Widget CRUD, layout persistence test 1h
3.17 Test: Widget data fetch with product backend down (graceful degradation) test 1h

Phase 3 deliverable: Home page has customizable widget grid. Each widget fetches live data.


Phase 4: Cross-Product Search (2 days)

Goal: Cmd+K opens a global search bar that searches across all products.

# Task Type Est Notes
4.1 BFF: lib/search-aggregator.ts -- parallel search fan-out to product backends backend 2h Same circuit-breaker pattern as feed
4.2 BFF: GET /api/portal/search?q=...&products=... -- cross-product search backend 2h Returns results grouped by product
4.3 BFF: Product search endpoint mapping -- which endpoint to call per product backend 1h e.g., NoteLett: GET /api/notes?search=, LocalMemGPT: GET /api/search?q=
4.4 Web: /search page -- full search results grouped by product web 3h Product sections, result cards with deep links
4.5 Web: SearchBar.tsx -- Cmd+K global search overlay web 2h Debounced input, recent searches, keyboard nav
4.6 Web: SearchResultCard.tsx -- generic result card with product badge web 1h
4.7 Web: Add use-keyboard-shortcuts.ts -- Cmd+K to open search web 30m
4.8 Product backends: Verify search/filter endpoints exist for each product backend 2h Add missing search endpoints
4.9 Test: Search across 3 products, results merge correctly test 1h
4.10 Test: Search with one product down, others still return test 30m

Phase 4 deliverable: Cmd+K opens cross-product search. Results grouped by product with deep links.


Phase 5: Billing & Settings (2 days)

Goal: User manages billing and global preferences from the portal.

# Task Type Est Notes
5.1 BFF: GET /api/portal/billing/summary -- aggregate from platform-service subscriptions + stripe backend 2h Combined monthly cost, per-product breakdown
5.2 BFF: GET /api/portal/billing/invoices -- all invoices across products backend 1h
5.3 BFF: GET /api/portal/preferences -- user global preferences backend 1h From UserDoc.globalPreferences
5.4 BFF: PATCH /api/portal/preferences -- update preferences backend 1h Validate with Zod, save to platform-service
5.5 Platform-service: Add globalPreferences field to UserDoc schema backend 1h Optional, backward-compatible
5.6 Platform-service: Add PATCH /auth/preferences endpoint backend 1h
5.7 Web: /billing page -- subscription cards per product, combined total, invoice list web 3h
5.8 Web: /settings page -- theme toggle, timezone picker, locale, notification prefs web 3h
5.9 Web: Theme toggle (dark/light/system) applies to portal immediately web 1h
5.10 Web: Notification preferences -- email/push/in-app toggles, digest frequency web 1h
5.11 Test: Billing aggregation with mixed plan types test 1h
5.12 Test: Preferences save and reload correctly test 1h

Phase 5 deliverable: /billing shows combined costs. /settings manages cross-product preferences.


Phase 6: Security & Profile (2 days)

Goal: Full SmartAuth security management from the portal.

# Task Type Est Notes
6.1 BFF: Proxy security endpoints to platform-service (MFA, passkeys, devices, login-events) backend 2h Same catch-all proxy pattern
6.2 Web: /security page -- MFA status, TOTP setup/disable, recovery codes web 3h Reuse patterns from admin-web security page
6.3 Web: /security -- passkey management (register, list, remove) web 2h WebAuthn browser API integration
6.4 Web: /security -- device list with trust levels, session revocation web 2h
6.5 Web: /security -- login history timeline web 1h
6.6 Web: /profile page -- name, email, avatar, connected OAuth accounts web 2h
6.7 Web: Connected accounts section -- link/unlink Google, Microsoft, Apple web 2h
6.8 Web: /support page -- create/track support tickets via platform-service support-cases web 2h
6.9 Test: MFA setup flow E2E test 1h
6.10 Test: Device revocation works from portal test 30m

Phase 6 deliverable: Full security management. Profile with OAuth link/unlink. Support ticket creation.


Phase 7: Telemetry, Polish & Launch (3 days)

Goal: Production-ready portal with telemetry, error handling, and polished UI.

# Task Type Est Notes
7.1 BFF: Telemetry event buffer -- portal-specific events (product_launched, search_executed, etc.) backend 1h
7.2 BFF: Feature flags integration -- @bytelyst/feature-flag-client backend 30m
7.3 BFF: Kill switch integration -- @bytelyst/kill-switch-client backend 30m
7.4 BFF: Rate limiting on search and feed endpoints backend 1h
7.5 BFF: Request logging with structured context backend 30m
7.6 Web: Telemetry client -- track portal events via @bytelyst/telemetry-client web 1h
7.7 Web: Error boundaries -- per-widget and per-page web 1h
7.8 Web: Loading skeletons for all pages web 2h
7.9 Web: Empty states for zero-product users (onboarding CTA) web 1h
7.10 Web: Responsive design -- mobile-friendly sidebar collapse web 2h
7.11 Web: PWA manifest + service worker for offline shell web 1h
7.12 Web: --portal-* design tokens from @bytelyst/design-tokens web 1h
7.13 Web: Keyboard shortcuts -- Cmd+K (search), Cmd+1-9 (product launch) web 1h
7.14 Docs: Update AGENTS.md with final architecture docs 1h
7.15 Docs: Write README.md with setup instructions docs 30m
7.16 Docker: Dockerfile for BFF + web infra 1h
7.17 Docker: Add to docker-compose.yml in common-plat infra 30m
7.18 CI: Playwright E2E test suite (10 core flows) test 3h
7.19 CI: Add portal to run-local-all-services.sh (in learning_voice_ai_agent repo) infra 15m
7.20 Final: Typecheck + test + build green across BFF + web test 1h

Phase 7 deliverable: Production-ready portal. All tests pass. Docker-deployable. Telemetry wired.


Phase 8: Post-Launch Enhancements (Ongoing)

Goal: Iterative improvements based on usage data.

# Task Type Est Notes
8.1 Drag-and-drop widget reordering (react-dnd or dnd-kit) web 3h
8.2 Embedded product views (iframe) with postMessage auth web 4h v2 of product launcher
8.3 SSE-based real-time feed updates backend 3h @bytelyst/fastify-sse
8.4 Cross-product quick actions (e.g., "Start Timer" from portal) web+bff 4h Product backends expose action endpoints
8.5 Mobile-responsive PWA optimization web 2h
8.6 Admin analytics -- portal engagement metrics in admin-web web 3h Cross-product adoption charts
8.7 Smart widget suggestions based on user activity patterns backend 2h "You use ChronoMind daily -- add the timer widget?"
8.8 Unified notification center with mark-read, filters web 3h
8.9 Product health badges -- show backend status in product cards bff 1h Poll health endpoints
8.10 Custom widget themes -- user sets accent color per widget web 1h

Summary

Phase Name Duration Tasks Key Deliverable
0 Repo Scaffold and Foundations 2 days 23 Repo builds, shell renders
1 Product Launcher and Auth 3 days 14 Login, product grid, launch
2 Activity Feed and Notifications 3 days 13 Cross-product activity timeline
3 Widget Dashboard 4 days 17 Customizable widget grid
4 Cross-Product Search 2 days 10 Cmd+K global search
5 Billing and Settings 2 days 12 Combined billing + global prefs
6 Security and Profile 2 days 10 Full SmartAuth security from portal
7 Polish and Launch 3 days 20 Production-ready, Docker, E2E
8 Post-Launch Ongoing 10 Drag-drop, SSE, quick actions
Total ~21 days 129

Dependency Graph

Phase 0 (scaffold)
  |
  v
Phase 1 (auth + products)
  |
  +---> Phase 2 (feed) ---> Phase 3 (widgets)
  |
  +---> Phase 4 (search)
  |
  +---> Phase 5 (billing + settings)
  |
  +---> Phase 6 (security + profile)
  |
  v
Phase 7 (polish + launch)  <-- all above complete
  |
  v
Phase 8 (post-launch enhancements)

Critical path: Phase 0 -> Phase 1 -> Phase 2 -> Phase 3 -> Phase 7

Phases 4, 5, 6 can be parallelized after Phase 1.


This roadmap should be reviewed after each phase. Estimates are in ideal developer-hours.