docs(ui): add platform core migration roadmap

This commit is contained in:
Saravana Achu Mac 2026-05-06 11:06:30 -07:00
parent 1da310f2ec
commit 5009a22675
3 changed files with 247 additions and 3 deletions

View File

@ -2,7 +2,7 @@
> **For:** Claude Code, OpenAI Codex, Cursor, GitHub Copilot, Windsurf Cascade, and any AI coding agent. > **For:** Claude Code, OpenAI Codex, Cursor, GitHub Copilot, Windsurf Cascade, and any AI coding agent.
> **Repo:** `learning_ai_notes` — NoteLett structured notes platform for humans and AI agents. > **Repo:** `learning_ai_notes` — NoteLett structured notes platform for humans and AI agents.
> **See also:** [`docs/PRD.md`](docs/PRD.md) for full product spec, [`docs/ROADMAP.md`](docs/ROADMAP.md) for implementation status, and [`docs/PRODUCTION_READINESS_HANDOFF_ROADMAP.md`](docs/PRODUCTION_READINESS_HANDOFF_ROADMAP.md) for the active production-readiness checklist. > **See also:** [`docs/PRD.md`](docs/PRD.md) for full product spec, [`docs/ROADMAP.md`](docs/ROADMAP.md) for implementation status, [`docs/PRODUCTION_READINESS_HANDOFF_ROADMAP.md`](docs/PRODUCTION_READINESS_HANDOFF_ROADMAP.md) for the production-readiness checklist, and [`docs/UI_UX_PLATFORM_CORE_ROADMAP.md`](docs/UI_UX_PLATFORM_CORE_ROADMAP.md) for UI/UX platform-core migration.
--- ---
@ -205,7 +205,7 @@ learning_ai_notes/
| **Extraction** | extraction-service (port 4005) for AI-powered task extraction | | **Extraction** | extraction-service (port 4005) for AI-powered task extraction |
| **Database** | Azure Cosmos DB via `@bytelyst/datastore``productId: "notelett"` | | **Database** | Azure Cosmos DB via `@bytelyst/datastore``productId: "notelett"` |
| **LLM** | `@bytelyst/llm` (mock/openai/azure providers), retry + timeout hardening | | **LLM** | `@bytelyst/llm` (mock/openai/azure providers), retry + timeout hardening |
| **Tests present** | Vitest/Playwright — 42 backend test files, 15 web unit/component test files, 10 mobile test files, and 9 Playwright E2E specs. May 5 baseline currently fails before all tests can pass; see `docs/PRODUCTION_READINESS_HANDOFF_ROADMAP.md` P0.5. | | **Tests present** | Vitest/Playwright — backend, web, mobile, and Playwright E2E coverage. The May 5 production-readiness handoff passed local verify/lint/E2E gates with explicit Docker/shared-service environment deferrals recorded in `docs/PRODUCTION_READINESS_HANDOFF_ROADMAP.md`. |
## 4. Coding Conventions ## 4. Coding Conventions
@ -220,6 +220,7 @@ learning_ai_notes/
- Theme tokens use `--nl-*` CSS custom properties (web) or `NoteLettTheme` (native) - Theme tokens use `--nl-*` CSS custom properties (web) or `NoteLettTheme` (native)
- Commit messages: `type(scope): description` — types: `feat`, `fix`, `docs`, `refactor`, `test`, `chore` - Commit messages: `type(scope): description` — types: `feat`, `fix`, `docs`, `refactor`, `test`, `chore`
- Use `@bytelyst/ui` components (Button, Card, Badge, Toast, etc.) — never build custom equivalents - Use `@bytelyst/ui` components (Button, Card, Badge, Toast, etc.) — never build custom equivalents
- For UI/UX migration work, follow `docs/UI_UX_PLATFORM_CORE_ROADMAP.md`: common-platform core UI first, thin NoteLett adapter second, product-local domain components only when behavior is NoteLett-specific
- All colors via `--nl-*` CSS custom properties from `@bytelyst/design-tokens` — never hardcode hex values - All colors via `--nl-*` CSS custom properties from `@bytelyst/design-tokens` — never hardcode hex values
- Every interactive element must have `aria-label` or visible text label - Every interactive element must have `aria-label` or visible text label
@ -326,7 +327,7 @@ pnpm --filter @notelett/mobile run lint # mobile ESLint
pnpm run verify pnpm run verify
``` ```
May 5, 2026 baseline note: `pnpm install --frozen-lockfile` passes after the workspace was aligned to `../learning_ai/learning_ai_common_plat/packages/*`. `pnpm run typecheck`, `pnpm run test`, `pnpm run build`, and targeted lint currently have known baseline failures recorded in `docs/PRODUCTION_READINESS_HANDOFF_ROADMAP.md` P0.5. Do not hide those by weakening tests or lint rules; fix the underlying implementation/configuration in the owning roadmap tasks. May 5, 2026 production-readiness note: local verify, lint, web E2E, and release-guard audits pass. Docker compose and live shared-service smoke checks are explicit environment deferrals on this host; see `docs/PRODUCTION_READINESS_HANDOFF_ROADMAP.md` Phase P10 for exact commands and commit hashes.
## 7. Backend API Endpoints ## 7. Backend API Endpoints

View File

@ -154,3 +154,4 @@ See `docs/PRODUCTION_READINESS_HANDOFF_ROADMAP.md` Phase P10 for exact commands,
- [`docs/DATA_MIGRATION_AND_BACKFILL_PLAN.md`](docs/DATA_MIGRATION_AND_BACKFILL_PLAN.md) — Encrypted-field, schema-change, and backfill migration plan - [`docs/DATA_MIGRATION_AND_BACKFILL_PLAN.md`](docs/DATA_MIGRATION_AND_BACKFILL_PLAN.md) — Encrypted-field, schema-change, and backfill migration plan
- [`docs/TELEMETRY_AND_DIAGNOSTICS_TAXONOMY.md`](docs/TELEMETRY_AND_DIAGNOSTICS_TAXONOMY.md) — Event taxonomy and diagnostic breadcrumb contract - [`docs/TELEMETRY_AND_DIAGNOSTICS_TAXONOMY.md`](docs/TELEMETRY_AND_DIAGNOSTICS_TAXONOMY.md) — Event taxonomy and diagnostic breadcrumb contract
- [`docs/OPERATOR_RUNBOOK.md`](docs/OPERATOR_RUNBOOK.md) — Incident triage and recovery steps for dependencies, scheduler/webhooks, blob, LLM/extraction, reviews, and MCP - [`docs/OPERATOR_RUNBOOK.md`](docs/OPERATOR_RUNBOOK.md) — Incident triage and recovery steps for dependencies, scheduler/webhooks, blob, LLM/extraction, reviews, and MCP
- [`docs/UI_UX_PLATFORM_CORE_ROADMAP.md`](docs/UI_UX_PLATFORM_CORE_ROADMAP.md) — UI/UX migration plan for moving reusable components into common-platform core UI while keeping a thin NoteLett adapter

View File

@ -0,0 +1,242 @@
# NoteLett UI/UX Platform-Core Migration Roadmap
Status: active implementation plan
Date: May 6, 2026
Repos: `learning_ai_notes`, `../learning_ai/learning_ai_common_plat`
## Goal
Move reusable UI building blocks into common-platform core UI and make NoteLett consume them locally by default, while keeping only product-specific composition in NoteLett.
The target is not a direct shadcn adoption. The target is a ByteLyst-owned UI system with shadcn-style ergonomics: composable primitives, local product wrappers, Radix accessibility where useful, Lucide icons, CSS-token styling, and copy-owned source in common platform.
## Current Findings
NoteLett already consumes local common-platform packages through `workspace:*` by default via `.pnpmfile.cjs`.
Common platform currently provides:
- `@bytelyst/ui`: `Button`, `Badge`, `Card`, `Input`, `Textarea`, `Label`, `Select`, `Modal`, `ConfirmDialog`, `EmptyState`, `LoadingSpinner`, `Separator`, `Sidebar`, `StatCard`, `Toast`
- `@bytelyst/design-tokens`: product token packages, including NoteLett `--nl-*`
- `@bytelyst/dashboard-components`: app-level `ErrorPage`, `NotFoundPage`, `LoadingSpinner`, `LoadingSkeleton`, `PageHeader`, `EmptyState`
NoteLett currently has a thin local wrapper at `web/src/components/ui/Primitives.tsx`, but it only exposes `Button`, `Badge`, and `Card`.
Large product surfaces still use raw markup and inline styles:
- raw `button`, `input`, `textarea`, and `select`
- global utility classes such as `surface-card`, `surface-muted`, `badge`, and `input-shell`
- repeated layout patterns: two-column work surfaces, panel headers, metric cards, queue rows, empty states, settings sections, modal shells, and timeline rows
- review UX uses raw buttons/badges/textareas and hand-rolled cards despite being one of the most important operator workflows
Common-platform UI has a useful foundation, but it also needs hardening before broad reuse:
- some status colors use raw Tailwind color literals instead of semantic ByteLyst tokens
- component variants are limited for dense operational apps
- missing primitives: tabs, tooltip, dropdown/menu, segmented control, switch, checkbox, radio group, table/data list, command palette primitives, skeleton, page shell/panel primitives, status dot, icon button
- no dedicated product-token adapter pattern beyond NoteLetts local wrapper
## Architecture Decision
Use a two-layer model.
### Layer 1: Common Platform Core UI
Owned by `../learning_ai/learning_ai_common_plat/packages/ui`.
This layer should contain all reusable, product-agnostic UI primitives and operational patterns:
- primitive controls
- accessible overlays
- data display
- feedback/status
- layout primitives
- navigation primitives
- form primitives
- loading/empty/error states
Common-platform components must use `--bl-*` semantic tokens internally and avoid product-specific `--nl-*` tokens.
### Layer 2: NoteLett Product UI Adapter
Owned by `web/src/components/ui`.
This layer should stay intentionally thin:
- remap common-platform components to NoteLett tokens and density
- expose product-specific default variants
- compose NoteLett-specific domain widgets
- avoid duplicating generic components already available in common platform
Examples that stay NoteLett-local:
- `ProposalReviewCard`
- `AgentTimeline` only if its event model remains NoteLett-specific
- `NoteEditor` and editor toolbar behaviors
- `SmartActionsPanel`
- `PalacePanel` domain composition
- note metadata/link/version panels
Examples that move to common platform:
- `Panel`, `PanelHeader`, `PanelBody`
- `Surface`, `SurfaceList`, `ListItemButton`
- `StatusBadge`, `StatusDot`
- `IconButton`
- `Field`, `Input`, `Textarea`, `Select`, `Checkbox`, `RadioGroup`, `Switch`
- `Tabs`, `SegmentedControl`
- `DropdownMenu`, `Tooltip`
- `DataTable` or `DataList`
- `Timeline`
- `DiffCard` / before-after comparison
- `CommandDialog` primitives
- `PageHeader`, `AppShell` base pieces
## UX Direction
NoteLett should feel like a quiet, dense, professional knowledge-operations tool.
Principles:
- prioritize scanning, triage, comparison, and repeated action over decorative presentation
- keep first-class operator workflows fast: reviews, search, note editing, workspace triage, sharing, settings
- use compact controls with stable dimensions
- use icons for clear actions where possible
- keep cards shallow; avoid cards inside cards
- reserve large typography for page-level headings
- keep all color through tokens
- ensure every interactive element has visible text or `aria-label`
- verify mobile widths for no overlap and no horizontal overflow
## Implementation Roadmap
### Phase UI0 — Baseline Audit And Rules
- [ ] Add UI migration audit commands for raw controls, global surface classes, hardcoded inline styles, and direct `@bytelyst/ui` imports.
- [ ] Document the allowed component layers in `AGENTS.md`: common-platform core UI first, NoteLett wrapper second, product-domain components third.
- [ ] Add a short UI ownership section to `README.md`.
- [ ] Verify: `rg` audits, `pnpm --filter @notelett/web run typecheck`, `git diff --check`.
### Phase UI1 — Harden Common-Platform Core UI
Repo: `../learning_ai/learning_ai_common_plat`
- [ ] Replace raw color literals in `@bytelyst/ui` status components with semantic `--bl-*` tokens and fallbacks owned by design tokens.
- [ ] Add product-safe variants to existing `Button`, `Badge`, `Card`, `Input`, `Textarea`, and `Select`.
- [ ] Add `IconButton`, `Panel`, `PanelHeader`, `PanelBody`, `Surface`, `SurfaceList`, `ListItemButton`, `StatusBadge`, and `StatusDot`.
- [ ] Add `Tabs`, `SegmentedControl`, `Tooltip`, `DropdownMenu`, `Checkbox`, `RadioGroup`, and `Switch` using Radix where appropriate.
- [ ] Add `DataList`/`DataTable`, `Timeline`, and `DiffCard` for operational workflows.
- [ ] Add Storybook stories and basic rendering/a11y tests for every new primitive.
- [ ] Verify in common platform: `pnpm --filter @bytelyst/ui build`, UI package tests/stories where available, and any common-platform lint/typecheck gate.
### Phase UI2 — Expand NoteLett UI Adapter
Repo: `learning_ai_notes`
- [ ] Expand `web/src/components/ui/Primitives.tsx` to re-export or wrap all approved common primitives.
- [ ] Ensure wrappers map `--bl-*` to `--nl-*` through global token aliases, not per-component hardcoding.
- [ ] Add NoteLett defaults for radius, density, focus ring, status mapping, and operational list rows.
- [ ] Remove direct product code dependence on `surface-card`, `surface-muted`, `badge`, and `input-shell` for new or migrated screens.
- [ ] Verify: web typecheck, focused component tests, hardcoded color audit, raw control audit.
### Phase UI3 — Review UX Migration First
Repo: `learning_ai_notes`
The review surface is the highest-value pilot because it is operator-critical and currently hand-rolled.
- [ ] Refactor `web/src/app/(app)/reviews/page.tsx` into product components:
- `ReviewWorkflowNav`
- `ReviewQueueList`
- `ReviewDecisionBar`
- `ReviewNoteField`
- `ProposalDiffCard`
- `ReviewTimeline`
- [ ] Use common `Panel`, `Button`, `Badge`, `Textarea`, `ListItemButton`, `DiffCard`, and `Timeline`.
- [ ] Replace raw `button`, `textarea`, and `badge` elements in review UX.
- [ ] Add keyboard behavior: queue navigation, select all/clear, approve/reject shortcuts only when focus is safe.
- [ ] Add empty/loading/error states through common components.
- [ ] Verify: web typecheck, web tests, Playwright release-flow review spec, desktop/mobile screenshot check.
### Phase UI4 — App Shell And Navigation
- [ ] Move reusable app-shell/sidebar/header patterns into common platform if they are product-agnostic.
- [ ] Keep NoteLett navigation labels, routes, and feature-flag gating local.
- [ ] Replace global sidebar/mobile overlay CSS with common shell primitives.
- [ ] Verify mobile sidebar behavior, keyboard focus order, and no horizontal overflow.
### Phase UI5 — Forms, Modals, And Settings
- [ ] Migrate login/register/forgot-password fields to common `Input`, `Label`, `Button`, and `Card`.
- [ ] Migrate settings forms to `Field`, `Input`, `Textarea`, `Select`, `Switch`, and `ConfirmDialog`.
- [ ] Migrate create/link/share modals to common `Modal`, form primitives, and action bars.
- [ ] Verify auth/settings/share tests and accessibility labels.
### Phase UI6 — Search, Workspaces, Dashboard
- [ ] Replace saved-search/workspace/dashboard cards with common `Panel`, `DataList`, `StatCard`, `Badge`, and `EmptyState`.
- [ ] Replace filter chips with common `StatusBadge` or `FilterChip`.
- [ ] Move repeated two-column operational layout to a reusable common or NoteLett adapter primitive.
- [ ] Verify web tests and responsive visual checks.
### Phase UI7 — Notes, Smart Actions, Palace
- [ ] Keep rich editor behavior local, but replace generic editor shell, toolbar buttons, separators, and popover/menu controls with common primitives.
- [ ] Migrate Smart Actions cards/buttons/result panels to common components.
- [ ] Migrate Palace panels and knowledge graph controls to common panel/list/form primitives while keeping domain rendering local.
- [ ] Verify note detail tests, Smart Actions tests, Palace tests, and release E2E.
### Phase UI8 — Remove Legacy Globals
- [ ] Remove or greatly reduce global `.surface-card`, `.surface-muted`, `.badge`, and `.input-shell` after migrated screens no longer depend on them.
- [ ] Keep only truly global layout/accessibility utilities such as focus-visible, `sr-only`, skip link, and motion preferences.
- [ ] Add CI guard for new raw UI drift:
- raw form controls outside approved primitives
- raw `.badge`/`.surface-*` usage
- hardcoded hex/rgb colors
- direct `@bytelyst/ui` imports outside the adapter unless explicitly allowed
- [ ] Verify full web test/typecheck/lint, E2E, and visual smoke.
## Proposed Component Ownership Matrix
| Component / Pattern | Move To Common Platform | NoteLett Adapter | Keep Product-Local |
| --- | --- | --- | --- |
| Button, IconButton | yes | token/density defaults | no |
| Card, Panel, Surface | yes | NoteLett translucency/radius | no |
| Badge, StatusBadge, StatusDot | yes | NoteLett status mapping | no |
| Input, Textarea, Select, Label | yes | field spacing defaults | no |
| Checkbox, RadioGroup, Switch | yes | default density | no |
| Tabs, SegmentedControl | yes | route/domain mapping | no |
| Dropdown, Tooltip, Modal | yes | theme wrappers | no |
| DataList, DataTable | yes | empty/loading presets | no |
| Timeline | yes | event row adapter | maybe |
| DiffCard | yes | proposal labels | maybe |
| AppShell/Sidebar base | yes | NoteLett nav items/routes | no |
| NoteEditor behavior | no | shell controls only | yes |
| Proposal review data wiring | no | common visual primitives | yes |
| Smart Action execution UI | no | common visual primitives | yes |
| Palace domain rendering | no | common visual primitives | yes |
## Verification Checklist
Each implementation slice should run the smallest relevant subset first, then broader checks before merge:
- `pnpm run install:common-plat --frozen-lockfile`
- `pnpm --filter @notelett/web run typecheck`
- `pnpm --filter @notelett/web run test`
- `pnpm --filter @notelett/web exec playwright test e2e/release-flows.spec.ts --reporter=list --workers=1` when touching release flows
- `rg -n "#[0-9a-fA-F]{3,8}|rgba?\\(" web/src --glob '!**/*.test.*'`
- `rg -n "<button|<input|<textarea|<select|className=\\\"badge\\\"|className=\\\"surface-card\\\"|className=\\\"surface-muted\\\"|className=\\\"input-shell\\\"" web/src/app web/src/components --glob '!**/*.test.*'`
- Playwright screenshot checks at desktop and mobile widths for changed screens
- `git diff --check`
## First Implementation Slice Recommendation
Start with common-platform additions that unblock the review UX:
1. Add or harden common `Panel`, `PanelHeader`, `PanelBody`, `ListItemButton`, `StatusBadge`, `IconButton`, `Textarea`, `Timeline`, and `DiffCard`.
2. Expand NoteLett `Primitives.tsx` to expose those components with NoteLett token defaults.
3. Refactor the Review UX to consume them.
4. Add a CI/audit guard so raw review-surface UI does not drift back.
This slice creates real user value, proves the common-platform pattern, and keeps risk lower than attempting the whole app shell first.