- productId: notelett - displayName: NoteLett - domain: notelett.app - iOS bundle: com.bytelyst.notelett - Android bundle: com.notelett.app - backend port: 4016 - token namespace: --nl-* (CSS), NoteLettTheme (native) Rippled through: - shared/product.json (canonical source) - backend package.json, config, cosmos-init, all 10 test files - web package.json, landing page, notes-client test - mobile app.json, package.json, auth screen - docs: PRD, ROADMAP, architecture review, foundations, web/mobile roadmaps - registered in learning_ai_common_plat/products/notelett/ Verification: backend typecheck + 18 tests, web typecheck + 6 tests, mobile typecheck — all pass.
28 KiB
NoteLett — Architecture Review, Gap Analysis, and Reuse-First Action Plan
Version: 1.0
Date: March 10, 2026
Status: Draft
Scope: learning_ai_notes
Primary references:
docs/PRD.mddocs/ROADMAP.md../learning_ai_common_plat/docs/WORKSPACE_INVENTORY.md- shared product manifest:
shared/product.json
0. How To Use This Document
Use this document as the architecture correction plan for learning_ai_notes.
It is intentionally different from the feature-delivery roadmaps under docs/roadmaps/:
- the feature roadmaps track product delivery progress
- this document tracks reuse, boundary, DRY, and platform-alignment corrections
When making implementation decisions, prefer this ordering:
- preserve product-specific ownership for notes domain logic
- remove duplication where a shared package or shared service already exists
- do not move product-specific code into
learning_ai_common_platprematurely - only introduce new shared abstractions when at least two product repos can benefit
0.1 Architecture Scorecard
- Repo structure alignment: Good
- Backend boundary alignment: Good
- Web reuse alignment: Partial
- Mobile reuse alignment: Weak
- Identity/config consistency: Weak
- Shared service adoption: Partial
- DRY discipline: Partial
- Readiness for multi-agent parallel work: Moderate, but currently too dependent on scaffolds
0.2 What This Document Does Not Claim
This document does not claim that:
- web and mobile are already fully integrated with the product backend
- shared services are already production-verified for this repo
- DTO contracts are already unified across all surfaces
- the current roadmap set is a substitute for implementation verification
It is a corrective architecture review and execution guide, not a claim of completion.
1. Executive Summary
This repo is on the right architectural path, but it is not yet fully aligned with the original plan or the ByteLyst workspace best practices.
The good news:
- the repo already follows the correct high-level product-repo shape with
web/,mobile/,backend/,docs/, andshared/ - the backend is already using the right shared package pattern from
learning_ai_common_plat - the web app is already consuming several correct
@bytelyst/*packages - the mobile app is already attempting to consume the React Native acceleration path via shared packages
- product-specific backend modules are correctly local to this repo instead of leaking into
platform-service
The main gaps:
- product identity is inconsistent across surfaces
- some repo-local wrappers are placeholders or duplicated configuration glue rather than stable shared-platform usage
- web and mobile still rely on mock, fallback, or local-only behavior in places where the plan expects real product-backend integration
- mobile is not yet following a true shared SDK pattern even though the PRD explicitly calls for reuse-first mobile delivery
- web is not yet leveraging shared dashboard-style primitives strongly enough
- repo-local code still contains temporary duplication in config, platform wiring, and fallback data definitions
The core architectural correction is straightforward:
- keep only notes-specific domain behavior in this repo
- keep only notes-specific UX in this repo
- move all reusable platform/client wiring to shared
@bytelyst/*packages or shared services - standardize all surfaces on one product identity source of truth
- remove placeholder wrappers once shared packages or SDK entrypoints are available
The implementation priority should be:
- Priority 1
- unify product identity and config
- Priority 2
- remove fake or no-op local wrappers
- Priority 3
- replace mock/fallback runtime paths with real backend integration
- Priority 4
- complete shared platform-service / extraction / blob / diagnostics wiring
- Priority 5
- harden DTO reuse and UI primitive reuse without over-centralizing notes-specific code
2. Review Criteria
This review evaluates the repo against five standards.
2.1 Original Product Plan
From the PRD and roadmap, this repo is expected to:
- be a ByteLyst product repo, not a standalone architecture fork
- consume shared platform capabilities from
learning_ai_common_plat - keep product-specific notes logic in this repo's
backend/ - avoid rebuilding auth, telemetry, diagnostics, offline queue, extraction, blob, and admin infrastructure locally
- maximize reuse across web and mobile
2.2 Workspace Best Practices
From the workspace inventory and common platform standards:
- product repos consume shared packages via local
file:references during development - product-specific backends live in the product repo
- platform-agnostic concerns live in
learning_ai_common_plat - shared services are the default integration layer for auth, diagnostics, telemetry, extraction, blob, and orchestration
2.3 DRY / Reuse-First Rule
Every concern should be classified as one of:
- product-specific and should stay local
- shared and should come from a common package
- shared and should come from a common service
- temporary scaffold that should be removed once real shared integration lands
2.4 Product-Backend Boundary Rule
The local backend/ should only own product-specific notes APIs and domain persistence, such as:
- notes
- workspaces
- note relationships
- note tasks
- note artifacts
- note agent actions
It should not reimplement platform-service concerns.
2.5 Cross-Surface Consistency Rule
web/, mobile/, and backend/ should use:
- the same product identity
- the same service URL strategy
- the same shared package stack where possible
- compatible DTO shapes and integration patterns
3. Current-State Assessment
3.1 Repo Structure
Current repo structure is fundamentally correct:
backend/— product-specific API surfaceweb/— primary authoring/operator UImobile/— React Native / Expo MVP pathshared/— product manifestdocs/— planning and execution documents
Assessment:
- Structure alignment: Good
- Execution maturity: Partial
- Architectural cleanliness: Mixed
3.2 Product Identity Consistency
This is the single most important drift area.
Shared manifest
shared/product.json defines:
productId:bytelyst-notesdisplayName:ByteLyst Agentic Notes
Backend
backend/src/lib/product-config.ts correctly loads identity from shared/product.json using @bytelyst/config.
Mobile
mobile/src/api/config.ts hardcodes:
productId: 'bytelyst-notes'
This matches the manifest, but duplicates it.
Web
web/src/lib/product-config.ts defaults to:
PRODUCT_ID = 'agentic-notes'
This does not match the manifest or backend/mobile defaults.
Assessment:
- Severity: High
- Impact: auth storage keys, telemetry product tagging, diagnostics identity, API headers, and platform-service consistency can drift immediately
Required direction:
- the repo must standardize on
shared/product.jsonas the canonical source - all surface-level product config should derive from that identity rather than duplicating constants
4. What Is Correctly Product-Specific Today
These areas are correctly local to this repo and should remain here.
4.1 Backend Domain Modules
The following are product-specific and belong in backend/:
notesworkspacesnote-relationshipsnote-tasksnote-artifactsnote-agent-actions
This matches the PRD and the workspace product-backend model.
4.2 Notes-Specific UI
These should remain local to the product web/mobile surfaces:
- note editor UX
- note detail composition
- workspace navigation for notes
- linked-context panels
- review/approval surfaces that are product-local rather than platform-admin-global
- mobile capture, note detail, approvals, and retrieval flows tailored to notes
4.3 Notes-Specific Data Contracts
These may begin local, then potentially graduate into shared packages only if another product genuinely shares the same abstractions:
- note detail DTOs
- relationship DTOs
- task extraction review DTOs
- agent-action note review DTOs
5. What Is Already Reused Well
5.1 Backend Shared Package Reuse
The backend is already using the right reuse-first pattern.
From backend/package.json:
@bytelyst/auth@bytelyst/config@bytelyst/cosmos@bytelyst/datastore@bytelyst/errors@bytelyst/fastify-core@bytelyst/logger@bytelyst/testing
This is good and should remain the template.
5.2 Backend Bootstrap Alignment
backend/src/server.ts correctly uses:
createServiceAppregisterOptionalJwtContextstartServicejwtVerifywith issuerbytelyst-platform
This is aligned with the established product-backend standard.
5.3 Backend Identity Reuse
backend/src/lib/product-config.ts correctly pulls product identity from shared/product.json using loadProductIdentity().
This is the best pattern currently in the repo.
5.4 Web Shared Package Reuse
From web/package.json, the app already consumes:
@bytelyst/api-client@bytelyst/auth-client@bytelyst/design-tokens@bytelyst/diagnostics-client@bytelyst/platform-client@bytelyst/react-auth@bytelyst/telemetry-client
This is directionally correct.
5.5 Mobile Shared Package Reuse
From mobile/package.json, the app already consumes:
@bytelyst/api-client@bytelyst/auth-client@bytelyst/design-tokens@bytelyst/offline-queue@bytelyst/platform-client@bytelyst/react-native-platform-sdk
This is also directionally correct, even if the current runtime adoption is incomplete.
6. Gap Analysis — Duplication, Drift, and Under-Reuse
6.1 High-Priority Gap: Inconsistent Product Identity and Config
Evidence
shared/product.json→bytelyst-notesbackend/src/lib/product-config.ts→ derived from shared manifestmobile/src/api/config.ts→ hardcodedbytelyst-notesweb/src/lib/product-config.ts→ defaults toagentic-notes
Why this violates the plan
The PRD explicitly calls for early product manifest definition and consistent product identity across all surfaces.
Why this violates DRY
The same identity information is duplicated and partially inconsistent.
Required fix
Introduce a single repo-local product identity adapter per surface, all deriving from shared/product.json or a build-generated equivalent.
Recommendation
- Keep local: tiny product-config adapters if each runtime requires different env access semantics
- Do not keep local: duplicated raw
productIdliterals and display-name defaults scattered across files
6.2 High-Priority Gap: Web Still Uses Mock Auth and Mock Data as a Core Runtime Path
Evidence
web/src/lib/auth.tsuses demo user fallback and demo access tokensweb/src/lib/mock-data.tsdefines core app dataweb/src/lib/review-data.tsdefines mock approval queue and timeline- route files consume those mock data sources directly
Why this violates the plan
The roadmap allows scaffold phases, but the PRD expects web to become the strongest end-to-end authoring and operator surface.
Why this matters for DRY
Mock datasets are currently acting like a parallel local service layer. That risks duplicate DTOs and duplicate business assumptions.
Required fix
- replace route-level mock usage with real product-backend clients
- keep mocks only in tests or isolated prototyping fixtures
Recommendation
- Keep local: notes-specific page composition and page components
- Move to shared or remove: auth fallback/demo token behavior, route-runtime mock datasets, duplicated DTO assumptions that should instead come from API contracts
6.3 High-Priority Gap: Mobile Contains Placeholder Local Wrappers Instead of Real Shared SDK Usage
Evidence
mobile/src/lib/platform.tsreturnsfalseinisReactNativePlatformSdkReady()mobile/src/lib/telemetry.tsis a no-op stubmobile/src/api/config.tshardcodes platform/product URLs and identitymobile/src/api/workspaces.tsreturns inline mock workspacesmobile/src/api/notes.tsfalls back to local notesmobile/src/store/notes-store.tsperforms local-only draft/update behavior
Why this violates the plan
The PRD explicitly says the React Native path should reuse the existing shared SDK/package baseline and avoid rebuilding infrastructure locally.
Why this matters for DRY
The repo is beginning to grow a product-local mobile integration layer that duplicates concerns already meant to come from @bytelyst/* packages.
Required fix
- use shared auth + API + platform primitives directly
- delete placeholder wrappers that do not add product-specific value
- add only the minimum notes-specific composition layer above shared clients
Recommendation
- Keep local: notes-specific mobile stores and screens
- Replace/remove: no-op telemetry wrapper, fake SDK readiness helper, inline mock workspace APIs, duplicated hardcoded config
6.4 High-Priority Gap: Product Identity and Storage Prefixes Are Not Unified
Evidence
- mobile auth storage prefix:
bytelyst-notes - web auth storage prefix:
PRODUCT_IDdefaulting toagentic-notes - web local storage token reads are tied to that inconsistent ID
Impact
This can create broken token reuse, diagnostics drift, telemetry mis-tagging, and subtle environment bugs.
Required fix
Standardize token storage prefixes, telemetry identity, diagnostics identity, and API headers on the same canonical product ID.
6.5 Medium-Priority Gap: Web Is Not Yet Leveraging Shared Dashboard/UI Packages Strongly Enough
Evidence
The PRD explicitly expects reuse of dashboard/UI primitives where possible, but the current web app largely defines product-local layout and view primitives.
Assessment
This is not automatically wrong. Some product-local UI is expected. The issue is that the repo has not yet clearly separated:
- reusable table/list/filter/operator building blocks that should come from
@bytelyst/dashboard-components - truly notes-specific UX composition that should stay local
Required fix
Audit the current web components and classify each as:
- shared candidate
- product-specific component
- temporary scaffold
6.6 Medium-Priority Gap: Shared Service Usage Is Incomplete
Expected shared services from PRD
platform-serviceextraction-servicemcp-server
Current reality
- backend is correctly shaped for product-local APIs
- MCP work has started and is product-appropriate
- extraction is not yet truly wired
- telemetry/diagnostics are only partial
- blob support is not yet properly integrated for artifacts
- web/mobile are not yet using platform-service as a truly integrated dependency boundary
Required fix
Treat shared services as first-class runtime dependencies rather than future placeholders.
6.7 Medium-Priority Gap: Backend Still Has Some Infra That Could Eventually Be Standardized More
Evidence
backend/src/lib/config.tsdefines a local Zod env schemabackend/src/lib/cosmos-init.tsdefines repo-local container registrationbackend/src/lib/datastore.tsdefines local datastore bootstrapping
Assessment
This is mostly acceptable.
Why it is acceptable:
- product backends commonly retain self-contained config schemas
- container definitions are product-specific
- datastore choice and bootstrap can reasonably remain local if the shared package does not yet expose a higher-level product-backend bootstrap helper
Recommendation
Do not move this blindly into common-plat unless a shared abstraction proves reusable across several product backends.
6.8 Medium-Priority Gap: DTO Definitions Are Drifting Across Surfaces
Evidence
- web defines local interfaces in
web/src/lib/types.ts - mobile defines local API types in
mobile/src/api/notes.tsandmobile/src/api/workspaces.ts - backend owns canonical persistence and route contracts
Risk
Web/mobile may diverge from backend contracts over time.
Required fix
Create a small shared repo-local shared/contracts/ or packages/contracts/ layer for notes-product DTOs if cross-surface duplication starts growing.
Important nuance:
- this should remain repo-local unless the contracts become useful to other products
- this does not belong in
learning_ai_common_platunless it becomes product-agnostic
7. Detailed DRY Classification Matrix
7.1 Should Stay Product-Local
- notes domain modules and repositories
- note/workspace/task/relationship/artifact/agent-action route shapes
- notes-specific editor, note detail, workspace detail, search UX
- notes-specific mobile capture and retrieval UX
- product-specific MCP tool definitions for notes
- product-specific container list and partitioning strategy
7.2 Should Come From Shared Packages
- auth client creation primitives
- API client primitives
- platform-service client primitives
- telemetry client primitives
- diagnostics client primitives
- offline queue primitives
- design token source and generated outputs
- testing helpers
- error utilities
- config loading helpers
7.3 Should Come From Shared Services
- auth and identity flows from
platform-service - telemetry ingestion from
platform-service - diagnostics ingestion from shared diagnostics infrastructure
- blob upload/download from shared blob APIs
- extraction and enrichment from
extraction-service - MCP registration/orchestration through
mcp-server
7.4 Should Be Removed After Integration Lands
- web demo auth fallback
- web demo access token defaults
- web route-runtime mock datasets used as primary data source
- mobile no-op telemetry wrapper
- mobile fake SDK readiness helper
- mobile inline fallback workspaces
- mobile fallback notes as a long-term runtime path
8. Per-Surface Findings and Recommendations
8.1 Backend
Verdict
Backend is the most aligned part of the repo.
Strengths
- correct ownership boundary
- correct Fastify product-backend pattern
- correct shared package usage
- correct identity loading pattern
- correct product-local module placement
Gaps
- test depth is still shallow in several route modules
- some infra logging still uses direct stdout/stderr in
cosmos-init.ts - product-specific client contracts for web/mobile are not formalized enough
Action
- keep backend architecture mostly intact
- improve tests and contract discipline rather than rewriting structure
8.2 Web
Verdict
Web is structurally aligned but operationally still scaffold-heavy.
Strengths
- correct framework
- correct shared package direction
- correct use of shared tokens
- strong route shell progress
Gaps
- mock-backed runtime
- inconsistent product identity
- weak shared dashboard primitive reuse
- auth fallback behavior acting as a scaffold crutch
Action
- unify config/identity first
- replace mock data route by route with backend-backed clients
- classify components into shared-worthy vs notes-specific
8.3 Mobile
Verdict
Mobile is the least aligned surface from a reuse-first perspective.
Strengths
- correct Expo/RN acceleration path decision for MVP
- correct dependency direction in
package.json - correct use of
@bytelyst/auth-client,@bytelyst/api-client,@bytelyst/offline-queue
Gaps
- no-op local wrappers
- hardcoded config
- inline fallback services
- incomplete real usage of shared RN platform capabilities
- partial duplication of integration logic that should be centralized
Action
- remove fake wrappers
- directly adopt shared clients/SDK modules where available
- keep only notes-specific state composition and UI locally
8.4 Docs and Planning
Verdict
The PRD is architecturally strong. Implementation is only partially aligned.
Strengths
- correct ownership boundaries
- correct reuse-first philosophy
- correct service/package expectations
Gaps
- some Phase 0 decisions remain unresolved even though scaffolding has progressed
- implementation drift occurred before identity/config standardization
- no dedicated architecture review doc existed before this one
9. Action Plan Roadmap
Sequencing Rule
The phases below should be executed in order because later cleanup depends on earlier identity and integration decisions:
- Phase A before Phase B
- Phase B before Phase C
- Phase C before most of Phase D
- Phase E can run in parallel with late Phase C / Phase D once contracts stabilize
- Phase F should harden the final architecture rather than leading it
Cross-Workstream Dependency Rule
To avoid duplicate work or rework:
- backend contract decisions should precede broad web/mobile contract cleanup
- identity/config cleanup should precede auth, telemetry, diagnostics, and storage work
- shared-service wiring decisions should precede large UI polish efforts that depend on those services
- any proposal to move code into
learning_ai_common_platshould include evidence that at least one other product repo can reuse it
Phase A — Identity and Config Consolidation
Goal
Make shared/product.json the real source of truth across all surfaces.
Tasks
- unify
productIdacross web/mobile/backend - align web default
PRODUCT_IDtobytelyst-notes - create one product-config strategy per surface derived from the same identity inputs
- standardize storage prefixes, telemetry product IDs, diagnostics product IDs, and API headers
- eliminate conflicting raw literals from web/mobile code
Exit Criteria
- no conflicting product IDs in repo code
- auth storage prefixes are consistent
- telemetry/diagnostics identify the same product everywhere
Checkpoint
- Completed in
b73d5e9
Phase B — Remove Placeholder Local Platform Wrappers
Goal
Delete local wrappers that do not add product-specific value.
Tasks
- remove or replace
mobile/src/lib/platform.ts - remove or replace
mobile/src/lib/telemetry.ts - audit all local wrapper files for no-op behavior
- keep only thin composition helpers that are necessary for runtime/platform adaptation
Exit Criteria
- no fake readiness helpers
- no no-op telemetry wrapper
- all remaining wrapper files have clear product-specific justification
Checkpoint
- mobile placeholder-wrapper cleanup completed in
86e2da8
Phase C — Real Backend Integration for Web and Mobile
Goal
Stop using local mock/fallback data as a primary runtime path.
Tasks
- replace web mock note/workspace/search/review runtime data with backend-backed clients
- move mock data to test-only or prototype-only locations
- replace mobile fallback notes and inline workspaces with real API calls
- wire mobile note detail update persistence to the backend
- align web/mobile DTOs with backend response contracts
Exit Criteria
- web note list/detail/search use real APIs
- mobile note list/detail/workspaces use real APIs
- fallback data is no longer the normal runtime path
Checkpoint
- mobile runtime-alignment slice completed in
8580ad3 - web runtime-alignment slice completed in
8340b1d - web review-runtime slice completed in
8bf0bb5
Phase D — Shared Platform Service Completion
Goal
Use the common services the way the PRD intended.
Tasks
- wire telemetry end-to-end through shared telemetry ingestion
- wire diagnostics end-to-end through shared diagnostics transport
- wire artifact upload/download via shared blob flows
- wire extraction-backed note enrichment and task extraction through
extraction-service - connect product MCP tools cleanly into shared
mcp-serveroperational patterns
Exit Criteria
- telemetry/diagnostics are real, not scaffolded
- artifacts use shared blob infrastructure
- extraction is best-effort but real
- MCP integration is aligned with shared orchestration patterns
Checkpoint
- shared diagnostics/telemetry config alignment completed in
2fac1ba - shared artifact-view blob alignment completed in
be3b439 - shared best-effort extraction note-detail alignment completed in
a7c362a - integrated web runtime verification completed in
5f3b32b
Phase E — Shared UI / Contract Hygiene
Goal
Reduce unnecessary duplication across surfaces.
Tasks
- classify web components into product-specific vs reusable
- adopt
@bytelyst/dashboard-componentswhere appropriate - introduce a repo-local shared contracts module if DTO duplication expands further
- eliminate repeated type definitions that describe the same backend objects differently
Exit Criteria
- common UI primitives are reused where sensible
- product-specific UX remains local
- DTO duplication is controlled and intentional
Phase F — Backend Hardening Without Over-Abstracting
Goal
Improve backend quality while preserving the correct ownership model.
Tasks
- add route behavior tests using
inject() - add repository behavior tests
- add cross-entity tests
- replace raw stdout/stderr startup logging with shared logger patterns if practical
- only upstream common abstractions into
learning_ai_common_platif at least two product repos genuinely need them
Exit Criteria
- backend is product-specific, well-tested, and not over-engineered into premature shared abstractions
10. Concrete File-Level Recommendations
10.1 Change Soon
web/src/lib/product-config.ts- align to canonical identity
web/src/lib/auth.ts- remove demo-first runtime path after real auth wiring lands
web/src/lib/mock-data.ts- move toward test/prototype usage only
web/src/lib/review-data.ts- move toward test/prototype usage only
mobile/src/api/config.ts- stop hardcoding identity and URLs long term
mobile/src/lib/platform.ts- delete or replace with real SDK wiring
mobile/src/lib/telemetry.ts- replace with shared telemetry client integration
mobile/src/api/workspaces.ts- replace inline return values with real API integration
mobile/src/api/notes.ts- remove long-term fallback behavior from the primary runtime path
10.2 Keep Local
backend/src/modules/**backend/src/lib/cosmos-init.tsbackend/src/lib/datastore.ts- notes-specific page/screen components
- notes-specific MCP tool definitions
10.3 Consider Later if Duplication Grows
- repo-local shared contracts package for notes DTOs
- repo-local shared product-config helper consumed by web/mobile build pipelines
- shared notes client package inside this repo only if multiple local surfaces need one canonical TS client
11. Recommended Guardrails Going Forward
- every new local wrapper file must justify why a shared package or service is insufficient
- every new config literal must be checked against
shared/product.json - every new web/mobile integration should prefer shared
@bytelyst/*clients first - every new backend abstraction should be asked: is this truly product-specific, or should it live in common-plat?
- no mock/fallback runtime path should be marked complete in roadmap docs unless the real integration exists
- avoid moving product contracts into common-plat unless they are truly product-agnostic
12. Final Verdict
learning_ai_notes is architecturally promising but only partially aligned with the original reuse-first plan.
The backend is already closest to the ByteLyst standard. The web app is structurally correct but still too scaffold-driven. The mobile app has the largest reuse gap because it contains temporary local wrappers and fallback services instead of a true shared-platform integration path.
The repo does not need a major rewrite. It needs a disciplined cleanup and consolidation pass:
- unify identity
- remove placeholder wrappers
- replace runtime mocks/fallbacks with real integrations
- keep notes-specific code local
- keep platform/shared concerns in
learning_ai_common_plat
That path will bring the repo back into alignment with the PRD, roadmap, DRY principles, and the established workspace architecture.
13. Companion Execution Docs
Use these checkbox-based execution docs to operationalize this review by workstream:
docs/roadmaps/08_ARCHITECTURE_REUSE_MASTER_ROADMAP.mddocs/roadmaps/09_BACKEND_REUSE_ALIGNMENT_ROADMAP.mddocs/roadmaps/10_WEB_REUSE_ALIGNMENT_ROADMAP.mddocs/roadmaps/11_MOBILE_REUSE_ALIGNMENT_ROADMAP.mddocs/roadmaps/12_PLATFORM_SHARED_SERVICES_ALIGNMENT_ROADMAP.md