NoteLett — Gap Analysis
Date: March 19, 2026
Auditor: Cascade (systematic code review)
Scope: Full repo audit — backend, web, mobile, MCP, tests, DevOps, docs
Current State Summary
| Surface |
Status |
Typecheck |
Tests |
Build |
| Backend |
7 modules + MCP (8 tools) + auth |
✅ pass |
✅ 24 tests (12 files) |
✅ tsc |
| Web |
6 pages + 10 components + 18 lib files |
✅ pass |
✅ 6 tests (5 files) |
✅ next build |
| Mobile |
4 tabs + note detail + auth + 5 stores |
✅ pass |
✅ 0 tests (passWithNoTests) |
n/a |
Commits tracked in ROADMAP.md: 30+ incremental commits with verification notes.
Gaps by Category
Category A — Bugs (code issues that will cause runtime failures or incorrect behavior)
A1. Module-scope API client instantiation (SSR crash risk)
- Files:
web/src/lib/extraction-client.ts:25-28, web/src/lib/blob-client.ts:11-15
- Issue:
const extractionApi = createApiClient(...) and const blobClient = createBlobClient(...) are instantiated at module scope. Both files have "use client" directives, but extraction-client.ts is imported by notes-client.ts (which has NO "use client" directive). If any server component ever imports notes-client.ts, the entire import chain crashes because createApiClient runs at import time. blob-client.ts is lower risk since only imported from ArtifactPanel.tsx (a client component).
- Severity: High (
extraction-client.ts), Medium (blob-client.ts)
- Fix: Apply the same lazy-init singleton pattern used in NomGap and other products. Also add
"use client" to notes-client.ts (see A6).
- Note:
telemetry.ts, kill-switch.ts, feature-flags.ts, diagnostics.ts also use module-scope instantiation but are lower risk — all have "use client" and are only imported from providers.tsx (also client-side).
A2. next.config.ts — missing output: "standalone" for Docker builds
- File:
web/next.config.ts:23
- Issue: No Dockerfile exists yet, but when one is added, the build will fail because
output: "standalone" is missing. The outputFileTracingRoot is already set (anticipating standalone), but output itself is not configured.
- Severity: Medium (not blocking today, blocks future Docker deployment)
- Fix: Add
output: "standalone" to nextConfig.
A3. notes-client.ts — getNoteDetail fetches ALL notes to find one
- File:
web/src/lib/notes-client.ts:291-301
- Issue:
getNoteDetail(noteId) calls GET /notes (fetches all notes) and then .find() by ID client-side. This is O(n) and will degrade as note count grows. The backend already has GET /notes/:id which should be used instead.
- Severity: Medium (performance — works but scales poorly)
- Fix: Call
GET /notes/:id?workspaceId=... directly. Requires knowing workspaceId upfront or adding a backend route that resolves by ID alone.
A4. notes-client.ts — listWorkspaceSummaries fetches ALL notes to count per-workspace
- File:
web/src/lib/notes-client.ts:209-217
- Issue: Every call to
listWorkspaceSummaries() fetches the entire notes list just to count notes per workspace. This is called frequently (dashboard, review queue, etc.).
- Severity: Medium (performance)
- Fix: Add a backend endpoint for workspace summaries with note counts, or add
noteCount to the workspace list response.
A5. Backend route tests are registration-only — no API behavior coverage
- Files: All 7
routes.test.ts files under backend/src/modules/
- Issue: Every module test only verifies that route handlers are registered (
expect(app.get).toHaveBeenCalledTimes(N)). No tests exercise actual request/response behavior, validation, error paths, or auth enforcement. (Note: auth.test.ts and the 3 MCP test files do have real behavior tests.)
- Severity: High (quality — bugs in route handlers won't be caught)
- Fix: Add integration-style tests using
buildTestApp() or Fastify .inject() to test real request flows.
A6. notes-client.ts missing "use client" directive
- File:
web/src/lib/notes-client.ts
- Issue: This file imports
extractSuggestedTasks from extraction-client.ts (which has a module-scope createApiClient call). notes-client.ts itself has no "use client" directive. All current consumers are client components, but the import chain is fragile — any future server component importing notes-client.ts would trigger an SSR crash.
- Severity: Medium (latent — works today, breaks if a server component imports it)
- Fix: Add
"use client"; directive to notes-client.ts, or refactor extraction-client.ts to lazy-init (preferred, see A1).
Category B — Missing Features (PRD requirements not yet implemented)
B1. No note restore endpoint
- PRD ref: §8.1 — "archive notes, restore notes"
- Current: Backend has
POST /notes/:id/archive but no restore endpoint. Web has no archive/restore UI. The PRD does not require hard delete.
- Fix: Add
POST /notes/:id/restore backend route (sets status: 'active') + web UI for archive/restore actions on note detail.
B2. No note create from web UI
- PRD ref: §8.1 — "create notes"
- Current: Web can edit existing notes and the dashboard links to note detail, but there is no "Create Note" button or flow on the web surface. Mobile has quick capture, but web does not.
- Fix: Add a create-note flow (modal or page) to the web dashboard or workspace view.
B3. No import/export
- PRD ref: §5.2 — "import/export", §8.5 — "import/export endpoints"
- Current: No import or export functionality exists anywhere.
- Fix: Add backend export endpoint (JSON/Markdown) + web download button. Import can follow in a later phase.
B4. No webhook/event hooks
- PRD ref: §8.5 — "webhook/event hooks where justified"
- Current: No webhook infrastructure exists.
- Fix: Deferred — implement after core flows are hardened. Low priority for V1.
B5. No note sharing within workspace
- PRD ref: §5.2 — "note sharing within authorized workspace scope"
- Current: Notes are scoped to userId. No mechanism for workspace-level shared access.
- Fix: Backend needs workspace-level read access rules. Web needs share UI.
- PRD ref: §5.2 — "AI summarization and enrichment", §8.1 — "generate summaries, generate structured metadata"
- Current: Only task extraction via
extraction-service is wired. No note summarization, metadata enrichment, or auto-tagging.
- Fix: Add extraction-service summarization task + web UI trigger.
B7. Mobile has zero tests
- PRD ref: §9.5 — "core capture/retrieval flows must be smoke-tested"
- Current:
vitest run --passWithNoTests — literally no test files.
- Fix: Add at least store tests, API client tests, and basic screen render tests.
B8. No note relationship creation from web UI
- PRD ref: §5.1 — "Relationship: note-to-note"
- Current: Backend supports note-relationships CRUD. Web displays linked notes on note detail (read-only). No UI to create/delete relationships.
- Fix: Add "Link Note" action on note detail page.
Category C — DevOps & Infrastructure Gaps
C1. No Dockerfiles
- Current: Neither
backend/Dockerfile nor web/Dockerfile exist.
- Fix: Add multi-stage Dockerfiles following the NomGap/ActionTrail pattern.
C2. No docker-compose.yml
- Current: No compose file for local full-stack development.
- Fix: Add docker-compose.yml with backend + web services.
C3. No GitHub Actions CI
- Current:
.github/ only contains copilot-instructions.md. No CI workflows.
- Fix: Add
.github/workflows/ci.yml for typecheck + test on push.
C4. No Playwright E2E tests
- Current: No
playwright.config.ts, no e2e/ directory.
- Fix: Add Playwright config + basic navigation and CRUD E2E tests.
C5. No scripts/docker-prep.sh
- Current: No script to pack
@bytelyst/* tarballs for Docker builds.
- Fix: Add docker-prep.sh following the existing ecosystem pattern.
Category D — Code Quality & Consistency Gaps
D1. Duplicate type definitions across web clients
- Files:
notes-client.ts, review-client.ts, extraction-client.ts
- Issue:
NoteAgentActionDoc, NoteDoc, etc. are duplicated across multiple client files instead of being shared from types.ts.
- Fix: Consolidate backend response types into
web/src/lib/types.ts and import from there.
D2. review-client.ts — listApprovalQueue fetches all workspaces then all actions per workspace (N+1)
- File:
web/src/lib/review-client.ts:94-104
- Issue: Calls
listWorkspaceSummaries() (which itself fetches all notes), then calls listAgentActionsForWorkspace() for each workspace. This is an N+1 query pattern that will degrade with scale.
- Fix: Add a backend endpoint that lists all pending agent actions across workspaces for the current user.
D3. web/src/lib/mock-data.ts is dead code (zero imports)
- File:
web/src/lib/mock-data.ts (228 lines)
- Issue: Legacy mock data file from scaffold era. Confirmed zero imports across the entire web codebase — completely unused.
- Fix: Delete the file.
D4. web/src/lib/review-data.ts is dead code (zero imports)
- File:
web/src/lib/review-data.ts (46 lines)
- Issue: Legacy mock timeline data, superseded by
review-client.ts which fetches real agent actions from the backend. Confirmed zero imports.
- Fix: Delete the file.
Category E — Documentation Gaps
E1. Roadmap phase checklist items are not checked off despite being implemented
- File:
docs/ROADMAP.md §4 (Phase 0, Phase 1, Phase 2, Phase 3)
- Issue: Many checklist items under Phases 0–3 remain unchecked (
[ ]) despite being implemented as evidenced by the progress notes (§8). For example, Phase 0 items like "product name finalized", "productId finalized", "backend port assigned" are all done (locked as NoteLett in commit e1fde25).
- Fix: Update roadmap checklist items to reflect actual implementation status.
E2. No WINDSURF_CONTEXT.md
- Issue: Other ByteLyst repos have a
WINDSURF_CONTEXT.md for agent onboarding. NoteLett does not.
- Fix: Low priority — AGENTS.md covers most of this.
Prioritized Implementation Plan
Sprint 1 — Bug Fixes & Quality (est. 2-3 hours)
| # |
Task |
Priority |
Files |
| 1 |
Fix extraction-client.ts + blob-client.ts SSR crash (lazy-init) |
High |
web/src/lib/extraction-client.ts, web/src/lib/blob-client.ts |
| 2 |
Add "use client" to notes-client.ts or refactor extraction-client lazy-init |
High |
web/src/lib/notes-client.ts |
| 3 |
Add output: "standalone" to next.config.ts |
Medium |
web/next.config.ts |
| 4 |
Consolidate duplicate types into types.ts |
Medium |
web/src/lib/types.ts, notes-client.ts, review-client.ts |
| 5 |
Delete dead code: mock-data.ts and review-data.ts |
Low |
web/src/lib/mock-data.ts, web/src/lib/review-data.ts |
Sprint 2 — Backend Test Depth (est. 3-4 hours)
| # |
Task |
Priority |
Files |
| 6 |
Add integration tests for notes routes (CRUD, search, archive) |
High |
backend/src/modules/notes/routes.test.ts |
| 7 |
Add integration tests for workspaces routes |
High |
backend/src/modules/workspaces/routes.test.ts |
| 8 |
Add integration tests for note-tasks, note-artifacts, note-relationships |
High |
3 test files |
| 9 |
Add integration tests for note-agent-actions (review, batch) |
High |
1 test file |
| 10 |
Add integration tests for saved-views |
Medium |
1 test file |
Sprint 3 — Web Feature Gaps (est. 3-4 hours)
| # |
Task |
Priority |
Files |
| 11 |
Add "Create Note" flow to web (modal or page) |
High |
New component + dashboard/workspace integration |
| 12 |
Add note archive/restore UI |
Medium |
Note detail page |
| 13 |
Add "Link Note" relationship creation UI |
Medium |
Note detail page |
| 14 |
Optimize getNoteDetail to use GET /notes/:id |
Medium |
web/src/lib/notes-client.ts |
| 15 |
Add backend cross-workspace pending actions endpoint |
Medium |
Backend + review-client.ts |
Sprint 4 — DevOps (est. 2-3 hours)
| # |
Task |
Priority |
Files |
| 16 |
Add backend Dockerfile |
High |
backend/Dockerfile |
| 17 |
Add web Dockerfile |
High |
web/Dockerfile |
| 18 |
Add docker-compose.yml |
High |
docker-compose.yml |
| 19 |
Add docker-prep.sh |
Medium |
scripts/docker-prep.sh |
| 20 |
Add GitHub Actions CI workflow |
Medium |
.github/workflows/ci.yml |
Sprint 5 — E2E & Mobile Tests (est. 3-4 hours)
| # |
Task |
Priority |
Files |
| 21 |
Add Playwright config + navigation E2E tests |
High |
web/playwright.config.ts, web/e2e/ |
| 22 |
Add Playwright CRUD flow E2E tests |
Medium |
web/e2e/ |
| 23 |
Add mobile store tests (notes-store, workspace-store, inbox-store) |
High |
mobile/src/store/*.test.ts |
| 24 |
Add mobile API client tests |
Medium |
mobile/src/api/*.test.ts |
Sprint 6 — AI Enrichment & Advanced Features (est. 4-5 hours)
| # |
Task |
Priority |
Files |
| 25 |
Add note summarization via extraction-service |
Medium |
Backend + web trigger |
| 26 |
Add note export (JSON/Markdown) |
Medium |
Backend endpoint + web download |
| 27 |
Add workspace-level note count to backend |
Low |
Backend workspaces module |
Sprint 7 — Docs Alignment (est. 1 hour)
| # |
Task |
Priority |
Files |
| 28 |
Update ROADMAP.md phase checklists to reflect actual status |
Medium |
docs/ROADMAP.md |
| 29 |
Update AGENTS.md with current test counts and any new endpoints |
Low |
AGENTS.md |
Verification Commands
# Backend
cd backend && npm run typecheck && npm test && npm run build
# Web
cd web && npm run typecheck && npm test && npm run build
# Mobile
cd mobile && npm run typecheck && npm test
Totals
| Metric |
Current |
After Sprint 1-5 (est.) |
| Backend tests |
24 |
~80+ |
| Web unit tests |
6 |
~15+ |
| Web E2E tests |
0 |
~20+ |
| Mobile tests |
0 |
~15+ |
| Dockerfiles |
0 |
2 |
| CI workflows |
0 |
1 |
| Known bugs |
6 |
0 |