Commit Graph

526 Commits

Author SHA1 Message Date
saravanakumardb1
78433b0e45 feat(ci): one-way UI drift ratchet to prevent regressions
UI8 deferred deleting the legacy global classes (.surface-card,
.surface-muted, .input-shell, .badge) because 69+ call sites in UI6/UI7
territory (dashboard, search, workspaces, notes detail, chat, palace)
still depend on them. Removing the globals before those screens migrate
would visually break the app.

Instead, ship a one-way ratchet that solves the actually-important
problem: prevent NEW legacy usage from creeping in while existing
sites get migrated.

- scripts/ui-drift-ratchet.sh — reads scripts/ui-drift-baseline.json
  and FAILS if any of the four UI drift categories regress above the
  tracked baseline. Pure bash, no jq required, works with grep or
  ripgrep. Uses the same patterns as scripts/ui-drift-audit.sh.
- scripts/ui-drift-baseline.json — checked-in baseline captured today:
  raw controls 38, legacy classes 92, hardcoded colors 0, direct imports 0.
- package.json — adds pnpm run audit:ui:ratchet and
  audit:ui:ratchet:update scripts.
- .github/workflows/ci.yml release-guards job — runs the ratchet as a
  required step plus the existing audit in report mode.
- docs/UI_UX_PLATFORM_CORE_ROADMAP.md — marks the CI-guard checklist
  item complete, documents the path to fully strict mode (drive
  baseline to zero, then delete globals.css legacy classes, then flip
  audit:ui:strict from advisory to required).

Verified:
- Ratchet at baseline: exits 0
- Synthetic regression (added a file with surface-card + raw <input>):
  ratchet correctly exits 1, reporting +1 in each affected category
- pnpm run verify: backend 380/380, web 96/96, mobile 97/97 (no
  behavior change)
2026-05-23 00:13:50 -07:00
saravanakumardb1
30a30ceb0f feat(web/ui5): migrate settings page + 4 modals to @bytelyst/ui primitives
Completes the high-leverage half of UI5 by migrating the most form-heavy
authenticated screens off the legacy 'input-shell' / inline-style pattern
onto Input, Textarea, Select, and AlertBanner primitives.

Migrated:
- web/src/app/(app)/settings/page.tsx — change-password form, feedback
  form, MCP/API-tokens/offline-queue cards. Replaces 'surface-card'
  sections with Card components, 'input-shell' inputs/selects/textareas
  with Input/Select/Textarea, and inline error/success divs with
  AlertBanner.
- web/src/components/CreateNoteModal.tsx — template/workspace/title/body/tags
  fields. Select primitive uses options=[{value,label}].
- web/src/components/LinkNoteModal.tsx — search input + relationship-type
  select + alert banner for errors.
- web/src/components/ShareDialog.tsx — user-id input, permission select,
  collaborator/public-link rows now use AlertBanner (tone='neutral') for
  the muted-surface look. Web Share API unsupported message is now a
  proper tone='warning' banner.
- web/src/components/PromptTemplateEditor.tsx — full form (name, slug,
  description, 3 selects, 2 textareas) migrated.

All existing tests continue to pass without modification because
@testing-library queries (getByLabel, getByPlaceholder, getByText) are
robust against the underlying HTML structure changes.

Verified:
- pnpm --filter @notelett/web run typecheck: passes
- pnpm --filter @notelett/web run test: 96/96 (existing CreateNoteModal,
  LinkNoteModal, ShareDialog suites all green)
- pnpm run verify: end-to-end (backend 380/380, web 96/96, mobile 97/97)
- Legacy class matches in web/src dropped from 89 to 69 over the UI5
  slice; remaining matches are in UI6/UI7 territory (dashboard, search,
  workspaces list, notes detail, chat, palace, NoteEditor).
2026-05-23 00:05:49 -07:00
saravanakumardb1
a83e60a60a fix(workspace): pin React and React-DOM to a single version via pnpm overrides
While migrating CreateNoteModal to use @bytelyst/ui Input/Select/Textarea
(which internally call React.useId), Vitest tests failed with:

  TypeError: Cannot read properties of null (reading 'useId')

Root cause: the web package pins react@19.2.0 but @bytelyst/ui declared
react: '^19.0.0' as a peer, so pnpm resolved 19.2.6 for it from the
common-platform side. Two React copies coexisted (19.2.0 and 19.2.6),
the @bytelyst/ui components linked against one and react-dom test-rendered
against the other, and useId failed because the dispatcher belonged to
a different React instance than the consumer.

Fix: declare pnpm.overrides in the workspace root so the entire monorepo
resolves to a single react@19.2.0 / react-dom@19.2.0 pair. Verified via
'pnpm why react' (all transitive references now point at 19.2.0) and the
on-disk symlinks (web/node_modules/@bytelyst/ui/node_modules/react and
common-plat/packages/ui/node_modules/react both link to
.pnpm/react@19.2.0).
2026-05-23 00:05:31 -07:00
saravanakumardb1
f4564d7cd6 chore(web): remove dead code surfaced by lint
Three mechanical lint warnings in the web package are resolved with
zero behavior change:

- web/src/app/(app)/notes/[noteId]/page.tsx — rename onTagsAccepted
  callback param to '_tags' to match the no-unused-vars allowlist
  (the param is intentionally unused; we trigger a re-save regardless).
- web/src/lib/feedback-client.ts — drop the unused PRODUCT_ID import.
- web/src/lib/notes-client.ts — delete the dead toWorkspaceSummary()
  helper. Workspace summaries are produced by listWorkspaceSummaries()
  on the backend response now; the local helper had no callers.

Web lint goes from 23 → 20 warnings. Remaining 20 are React-compiler
advisories about setState-in-effect patterns; those require careful
per-component refactoring (useReducer, derive-from-props, or
startTransition) and are tracked under Sprint D / Q1 tech debt rather
than fixed mechanically.
2026-05-22 23:51:59 -07:00
saravanakumardb1
aba7152097 fix(scripts): make ui-drift-audit work without ripgrep
The audit script silently passed on hosts without ripgrep installed
because 'rg -n ...' would fail, '|| true' swallowed the failure,
'matches' would be empty, and report() would print 'ok: no matches'.
This hid genuine UI drift from local 'pnpm run audit:ui' runs.

Changes:
- Detect ripgrep availability at startup and emit a stderr note when
  falling back.
- Add a grep-based fallback that translates rg '--glob !path' exclusions
  into 'grep --exclude=<basename>' so caller-side exclusions (e.g. the
  @bytelyst/ui adapter file at Primitives.tsx) still apply.
- Guard the optional 'extra_excludes' array expansion against 'set -u'
  when no exclusions are configured.

Result: on this host (no rg) the audit now correctly reports
2 categories with matches — raw interactive controls and legacy global
surface classes — instead of the false 'all green' it produced before.
'pnpm run audit:ui:strict' exits non-zero when matches remain, ready to
wire into CI once UI5–UI8 finish migrating the remaining call sites.
2026-05-22 23:51:47 -07:00
saravanakumardb1
9c65899387 feat(web/ui5): migrate auth pages and CreateWorkspaceModal to @bytelyst/ui primitives
Sprint C / UI5 — migrate the highest-leverage user-facing forms off the
legacy 'input-shell' / inline-style pattern onto the @bytelyst/ui Input,
Textarea, and AlertBanner primitives via the local Primitives.tsx adapter.

Adapter additions (web/src/components/ui/Primitives.tsx):
- Re-export AlertBanner, FormSection, and FieldGrid from @bytelyst/ui so
  product code never imports from the underlying package directly.

Migrated screens:
- web/src/app/(auth)/login/page.tsx
- web/src/app/(auth)/register/page.tsx
- web/src/app/(auth)/forgot-password/page.tsx
- web/src/components/CreateWorkspaceModal.tsx

Each migration replaces the ad-hoc 'input-shell' inputs and manual
label/error/success divs with the Input (label + hint props), Textarea,
and AlertBanner (tone='error'|'success') primitives. Inline style blocks
are replaced with Tailwind utility classes that read from the existing
--nl-* CSS custom properties so the visual tokens remain unchanged.

The 3 auth pages alone remove 9 input-shell call sites; the
CreateWorkspaceModal removes 2 more.

Verified:
- pnpm --filter @notelett/web run typecheck: passes
- pnpm --filter @notelett/web run test: 96/96 pass
- pnpm run verify: end-to-end green (backend 380/380, web 96/96, mobile 97/97)
2026-05-22 23:51:34 -07:00
saravanakumardb1
4667f85e20 docs(cleanup): move historical roadmaps to docs/archive/ and update AGENTS.md
Sprint B — closes audit item B7 (doc consolidation).

- docs/AGENT_TASK_ROADMAP.md, docs/ARCHITECTURE_REVIEW_AND_REUSE_ROADMAP.md,
  docs/GAP_ANALYSIS.md were each self-marked as historical snapshots
  but kept polluting the top of docs/. Moved them under docs/archive/
  in the previous commit; this commit:
  - Adds docs/archive/README.md explaining what's archived vs active
  - Repoints cross-doc links in docs/IMPLEMENTATION_TRACKER.md,
    docs/WEB_AI_FAST_ROADMAP.md, and docs/roadmaps/*.md to the new
    archive paths
  - Fixes relative links inside the archived files themselves so
    historical readers can still navigate back to active docs
- AGENTS.md §1.1 refreshed: reflects the May 22 re-verified state
  (382/96/97 tests), links the two new runbooks, and points readers
  away from docs/archive/ as a work source.
2026-05-22 23:23:50 -07:00
saravanakumardb1
bcad7d330a docs(runbooks): add MEK rotation and secret-management runbooks
Sprint B — closes audit items B4 and B5.

- docs/runbooks/MEK_ROTATION.md: step-by-step procedure for rotating
  the field-encrypt master key in Azure Key Vault, including pre-flight
  checks, rewrapAllDeks usage, verification queries, rollback, and lost-MEK
  recovery. Replaces the previous gap where MEK rotation had no
  documented operator path.
- docs/runbooks/SECRET_MANAGEMENT.md: inventory of every secret consumed
  by NoteLett with its production source (AKV), two production-grade
  patterns (workload identity vs K8s CSI), the compose-host pattern,
  rotation flow per secret type, verification commands, and red-flag
  triage.

Both docs cross-link each other and call out concrete open items
(automation, dual-JWT support, audit-log emission) for later sprints
rather than overstating current capabilities.
2026-05-22 23:23:38 -07:00
saravanakumardb1
1258d49488 feat(backend): emit task.created + workspace.created events; add share revocation regression test
Sprint B — closes audit items B6 (event-bus completeness) and B3
(public-share revocation regression).

Event bus:
- note-tasks/repository.ts createNoteTask now emits task.created with
  taskId, noteId, workspaceId, userId, title
- workspaces/repository.ts createWorkspace now emits workspace.created
  with workspaceId, userId, name

The event-bus already declared these event types (event-bus.ts) and
webhook subscribers can target them, but they were never emitted —
making the contract dead. Emissions follow the same .catch(() => {})
pattern used by note.created/updated/deleted in notes/repository.ts so
a subscriber failure cannot break the create flow.

Regression tests:
- note-tasks/repository.test.ts and workspaces/repository.test.ts
  exercise the emission paths end-to-end through the in-memory
  datastore.
- note-shares/repository.integration.test.ts adds a 5-test integration
  suite for the public-share revocation path: token resolves before
  revocation; token returns null after deleteShare (hard delete);
  expired token returns null; cross-product token rejected;
  listSharesForNote does not include revoked shares.

Verified:
- pnpm --filter @notelett/backend run test: 380/380 (was 373, +7 new)
- pnpm run verify end-to-end green
2026-05-22 23:23:08 -07:00
saravanakumardb1
c75ed3dc25 docs(sprint-a): record build restoration and refreshed sprint plan
- Commit previously untracked docs/NEXT_SPRINT_ROADMAP.md with refreshed
  May 22 status; mark Sprint 1 (backend build) and Sprint 2 (lint) as
  resolved by Sprint A workspace-path fix
- Add post-Sprint-A re-verification section to
  docs/PRODUCTION_READINESS_HANDOFF_ROADMAP.md documenting the
  workspace-path regression and the re-verified gates
- Update README quick-start to reference the canonical common-platform
  checkout path with BYTELYST_COMMON_PLAT_ROOT override note
2026-05-22 15:08:42 -07:00
saravanakumardb1
b2d824c8c6 fix(workspace): canonicalize common-plat path to ../learning_ai_common_plat
Restores green build after the May 12 Docker/UI regression.

Root cause: pnpm-workspace.yaml referenced a sibling path
(../learning_ai/learning_ai_common_plat/...) that did not exist on
dev/CI hosts. .pnpmfile.cjs fell back to ../learning_ai_common_plat for
some packages but missed others, so @bytelyst/ui was pulled from a
stale Gitea 0.1.0 tarball with zero exports (breaking web typecheck +
26 tests) and @bytelyst/monitoring was never linked into node_modules
(breaking backend typecheck + 2 test suites).

Changes:
- pnpm-workspace.yaml now references ../learning_ai_common_plat/packages/* directly
- .pnpmfile.cjs swaps DEFAULT/LEGACY common-plat roots so the canonical
  path is the default and the older nested path is the fallback
- scripts/docker-prep.sh, scripts/local-smoke.sh, scripts/release-guard-audit.sh
  follow the same canonical-first / legacy-fallback pattern
- .github/workflows/ci.yml symlinks directly to ../learning_ai_common_plat
- pnpm-lock.yaml regenerated with @bytelyst/ui@0.1.9 and
  @bytelyst/monitoring@0.1.5 linked to the local common-plat checkout

Verified:
- pnpm run verify: backend 373/373, web 96/96, mobile 97/97
- pnpm run audit:release-guards: passes
- backend, web, mobile lint all exit 0 (advisory warnings retained)
2026-05-22 15:08:30 -07:00
root
3dd981198e fix: Update docker configuration for production deployment
- Fixed NEXT_PUBLIC_NOTES_API_URL to use public API endpoint
- Updated docker-compose.yml environment format to proper YAML
- Updated Dockerfiles to remove Gitea secrets and use .docker-deps
- Added docker-prep.sh script for dependency packaging
- Changed NODE_ENV back to development for compatibility with memory DB

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-12 08:20:12 +00:00
root
4337793034 fix(docker): use shared docker-prep.sh and update Dockerfile for tarball approach
Some checks failed
CI — NoteLett / Backend — typecheck + test + build (push) Failing after 0s
CI — NoteLett / Web — typecheck + test + build (push) Failing after 0s
CI — NoteLett / Mobile — typecheck (push) Failing after 0s
CI — NoteLett / E2E — Playwright (push) Failing after 0s
Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-10 01:50:55 +00:00
root
3c5856b2f5 perf(docker): optimize docker-prep.sh with caching and shared cache
Some checks are pending
CI — NoteLett / Backend — typecheck + test + build (push) Waiting to run
CI — NoteLett / Web — typecheck + test + build (push) Waiting to run
CI — NoteLett / Mobile — typecheck (push) Waiting to run
CI — NoteLett / E2E — Playwright (push) Waiting to run
Implemented 7 optimizations to significantly improve docker-prep.sh performance:
1. Git-based incremental builds (only rebuild changed packages)
2. Hash-based caching (content-addressable cache)
3. Persistent tarball cache (survives git clean)
4. Smart manifest tracking (track what's been built)
5. Cache-first build strategy (check cache before building)
6. Shared global cache (all products use same cache at ~/.cache/bytelyst-packages)
7. Custom cache location via BYTELYST_CACHE_DIR env var

Performance improvements:
- First build: 2-3 minutes (same as before)
- Subsequent builds: 5-10 seconds (cache hit)
- Multi-product deployment: 60% faster (6-9 min → 2.5-3.5 min)
- Disk usage: Reduced from 5.1MB to 1.7MB (shared cache)

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-10 00:10:28 +00:00
root
fa00722a39 revert(docker): revert to docker-prep.sh approach due to workspace complexity
The base image approach is too complex for the current pnpm workspace structure.
Products cannot easily use the base image's workspace because pnpm expects all
workspace packages to be present during install. Reverting to the proven
docker-prep.sh tarball approach for now.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-09 23:35:37 +00:00
root
28189ac916 fix(docker): install all dependencies in builder stage for build tools
The base image only includes production dependencies, so we need to install
all dependencies (including devDependencies) in the builder stage to have
TypeScript and Next.js available for building.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-09 23:23:36 +00:00
root
b50e340f5a refactor(docker): use shared base images for @bytelyst/* packages
Update Dockerfiles to use bytelyst-common-base-backend and bytelyst-common-base-web
images instead of installing @bytelyst/* packages via tarballs.

Benefits:
- Smaller final images (~50MB vs ~250MB)
- Faster builds (base image cached)
- Consistent package versions across products
- No need for docker-prep.sh tarball packing

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-09 23:22:57 +00:00
root
3fe4f0786c feat(ux): add UX testing setup guide and common platform integration 2026-05-09 22:09:43 +00:00
a983e044b1 docs(ui): record shell css cleanup 2026-05-06 13:40:45 -07:00
db9b4557d8 refactor(ui): remove legacy shell css 2026-05-06 13:40:24 -07:00
2ba846698f docs(ui): record navigation boundary 2026-05-06 13:38:10 -07:00
7063e59078 refactor(ui): isolate notelett navigation 2026-05-06 13:37:49 -07:00
2a2c773ca1 docs(ui): record app shell migration 2026-05-06 13:36:25 -07:00
63211c0019 feat(ui): consume common app shell 2026-05-06 13:35:54 -07:00
4cfe5aee5e docs(ui): record review verification 2026-05-06 13:29:33 -07:00
6c562f05d8 test(ui): add review visual smoke 2026-05-06 13:28:57 -07:00
ca0f64e416 docs(ui): record review empty states 2026-05-06 13:19:23 -07:00
6472a58ad1 feat(ui): add review empty states 2026-05-06 13:18:52 -07:00
192a2aafde docs(ui): record review keyboard shortcuts 2026-05-06 13:16:01 -07:00
d63fdd1def feat(ui): add review keyboard shortcuts 2026-05-06 13:15:37 -07:00
116c0c982b docs(ui): record review component split 2026-05-06 13:14:18 -07:00
de75d93e59 refactor(ui): split review workflow components 2026-05-06 13:13:46 -07:00
936d2899fe docs(ui): record review primitive migration 2026-05-06 11:49:06 -07:00
c79aa2b6fd feat(ui): migrate review workflow primitives 2026-05-06 11:43:34 -07:00
1784f72d70 docs(ui): record adapter defaults 2026-05-06 11:36:42 -07:00
cf5e9c03fd feat(ui): add notelett primitive defaults 2026-05-06 11:36:05 -07:00
02c691bd8e docs(ui): record token alias migration 2026-05-06 11:34:46 -07:00
0f5ddb400b feat(ui): map platform tokens globally 2026-05-06 11:34:23 -07:00
e95db18f50 docs(ui): record common ui verification 2026-05-06 11:31:52 -07:00
fd90d07339 docs(ui): record primitive story coverage 2026-05-06 11:31:14 -07:00
d7516a3566 docs(ui): record data display primitive migration 2026-05-06 11:28:16 -07:00
c1c23b194e docs(ui): record control primitive migration 2026-05-06 11:26:05 -07:00
bb1e400dfc docs(ui): record surface primitive migration 2026-05-06 11:22:11 -07:00
6540f5c494 docs(ui): record primitive variant migration 2026-05-06 11:20:55 -07:00
109810572f docs(ui): record status token migration 2026-05-06 11:16:56 -07:00
4e01733f31 docs(ui): record platform core migration verification 2026-05-06 11:13:34 -07:00
b73c969d14 feat(ui): wire platform core primitives 2026-05-06 11:12:09 -07:00
5009a22675 docs(ui): add platform core migration roadmap 2026-05-06 11:06:30 -07:00
1da310f2ec chore(deps): default to local bytelyst packages 2026-05-06 11:01:14 -07:00
f18abbe5fc docs(roadmap): record P10.8 remote status 2026-05-05 14:21:39 -07:00