Commit Graph

23 Commits

Author SHA1 Message Date
saravanakumardb1
0c982de7e6 feat(web/ui8): remove legacy global classes + tighten audit regex + lock CI gate
UI8 closes the migration cycle started by UI0. The four legacy global
classes (.surface-card, .surface-muted, .badge, .input-shell) are
removed from web/src/app/globals.css and the CI ratchet now enforces
zero new occurrences across three of the four drift categories.

Changes:

1. Audit regex precision (scripts/ui-drift-audit.sh, scripts/ui-drift-ratchet.sh)

   The previous pattern 'className="[^"]*(badge|surface-card|surface-muted|input-shell)'
   matched the literal token anywhere inside className, which caused 21
   false positives against Tailwind arbitrary values like
   'bg-[color:var(--nl-surface-muted)]' where the legacy name appears
   inside a 'var(--nl-...)' reference.

   New pattern requires the legacy class to be a whole class token —
   either at the start of className, or preceded by a space, and
   followed by a space or closing quote. Result: 21 false positives
   eliminated; the ratchet now reports an honest 0 for the legacy
   category.

2. globals.css cleanup (web/src/app/globals.css)

   Removed .surface-card, .surface-muted, .badge, .input-shell rules.
   Only truly global utilities remain (typography, focus-visible,
   sr-only, skip-link, motion preferences, layout grids). A header
   comment documents that re-introductions should be solved at the
   call-site with a primitive, not by restoring the global rule.

3. Ratchet baseline (scripts/ui-drift-baseline.json)

   Final counts after UI5–UI8 across the session:
     raw interactive controls       14   (was 38 at start)
     legacy global surface classes  0    (was 92 at start)
     hardcoded color literals       0    (no change, was already 0)
     direct @bytelyst/ui imports    0    (no change, was already 0)

   The 14 remaining raw controls are intentional and tracked:
     NoteEditor toolbar buttons (10)
     ArtifactPanel hidden file input (1)
     search/page radio inputs (2)
     NoteVersionsPanel disclosure button (1)

4. CI gate (.github/workflows/ci.yml release-guards job)

   Documented that the ratchet is the canonical gate post-UI8: because
   legacy/colors/imports baselines are 0, any new occurrence in those
   three categories now fails CI. The strict-audit script is kept as
   a local diagnostic tool but not wired as a gate (would fail on the
   14 intentional raw controls).

5. Roadmap (docs/UI_UX_PLATFORM_CORE_ROADMAP.md)

   Marked UI5, UI6, UI7, UI8 all complete with per-phase commit hashes
   and explicit deliverables.

Cumulative migration impact (from initial baseline):
   raw interactive controls       38 → 14   (-24, -63%)
   legacy global surface classes  92 → 0    (-92, -100%)

Verified:
- pnpm run verify: backend 380/380, web 96/96, mobile 97/97
- bash scripts/ui-drift-ratchet.sh: all four categories at baseline
- bash scripts/ui-drift-audit.sh: only "Raw interactive controls"
  category has matches (intentional, tracked above)
- Live Docker stack at http://localhost:3050 still serves 200,
  backend health 200
2026-05-23 01:55:36 -07:00
saravanakumardb1
3288e28f5c feat(web/ui7): migrate note detail, palace, gaps/prompts pages, broadcast banner
Phase UI7 — completes the note detail surface, the Palace knowledge
exploration page + its panels, the knowledge-gaps page, the prompts
page empty states, and the broadcast banner. Brings the ratchet down
to 14 raw controls / 21 legacy class matches — both genuine remaining
intentional items (NoteEditor toolbar, hidden file input, audit false
positives matching Tailwind arbitrary values).

notes/[noteId]/page.tsx:
- 'Loading' badge → Badge variant=neutral.
- Loading/error sections → Card.
- Review-state link → Link wrapping Badge.

palace/page.tsx:
- Wing <select> → Select with options=[{value,label}].

palace components:
- PalacePanel.tsx — search input → Input, hall chip → Badge.
- MemoryTimeline.tsx — hall chip → Badge.
- KnowledgeGraphView.tsx — entity query input → Input.

workspaces/[id]/gaps/page.tsx:
- Topic Coverage section → Card, chip → Badge.
- Empty-state + per-gap items → Card.

prompts/page.tsx:
- Loading + empty-state divs → Card.

landing page (/):
- section.surface-card → Card.
- 'Backend-backed web surface' badge → Badge.
- 'Open dashboard'/'Browse workspaces' links → utility classes.

share/[token]/page.tsx:
- Read-only public share badge → Badge.
- Main content surface-card + input-shell body wrapper → Card with
  bordered body container.

BroadcastBanner.tsx:
- CTA + Dismiss raw <button> → Button (ghost variant, size sm).

Cumulative ratchet impact since session start:
  raw interactive controls       38 → 14   (-24)
  legacy global surface classes  92 → 21   (-71)
  hardcoded color literals       0           (clean)
  direct @bytelyst/ui imports    0           (clean)

Verified: pnpm typecheck, test (96/96), ratchet at new baseline.
2026-05-23 01:49:15 -07:00
saravanakumardb1
2408f43426 feat(web/ui5+ui7): migrate 12 components to @bytelyst/ui primitives
Finishes UI5 and kicks off UI7 by migrating the remaining form-heavy
components plus the note-detail right-rail panels. Drops legacy class
matches from 92 → 67 (-25) and raw interactive controls from 38 → 25
(-13). Ratchet baseline updated to the new floor.

Components migrated:

UI5 finish:
- NoteEditor.tsx — surface-card wrapper → Card, title input → Input,
  Tiptap editor className updated to use border + bg classes instead
  of input-shell. Toolbar buttons left as raw (intentional, tightly
  styled icon controls).
- SmartActionsPanel.tsx — result panel surface-muted → Tailwind
  bg-[var(--nl-surface-muted)] utility.
- ArtifactPanel.tsx — section→Card, badge→Badge, all three input-shell
  inputs/selects/textareas→Input/Select/Textarea, surface-muted form
  shell + per-artifact row → Tailwind bg-utility, raw <button> Open
  → Button.
- CommandPalette.tsx — surface-card command sheet → Tailwind layered
  classes, search input → Input (now ref-forwarded), kind badge → Badge.

UI7 component pass:
- MetadataPanel.tsx — section→Card, tag badge→Badge.
- LinkedNotesPanel.tsx — section→Card, surface-muted link row →
  Tailwind bg-utility with hover state.
- PalaceStats.tsx — section→Card, inline styles → Tailwind utilities.
- ExtractedTasksPanel.tsx — surface-muted row → Tailwind.
- NoteVersionsPanel.tsx — all three section/surface-card variants →
  Card + raw button → preserved (interactive disclosure).
- Pagination.tsx — raw <button> Previous/Next → Button, surface-muted
  → built-in secondary variant.
- TaskReviewPanel.tsx — full migration: section→Card, badge→Badge,
  input-shell + textarea + raw button → Input/Textarea/Button.
- SurveyBanner.tsx — survey answer input-shell → Input.

Adapter changes:
- web/src/components/ui/Primitives.tsx — Input and Textarea now use
  React.forwardRef so callers like CommandPalette can attach refs.

Verified:
- pnpm --filter @notelett/web run typecheck: passes
- pnpm --filter @notelett/web test: 96/96 still pass
- pnpm run audit:ui:ratchet: at new baseline (25/67/0/0)
- pnpm run audit:ui: legacy class matches now in dashboard / search /
  workspaces / notes-detail / palace / chat pages (UI6/UI7 page targets)
2026-05-23 01:33:48 -07:00
saravanakumardb1
d5e857dbf7 test(e2e): docker compose E2E test + seed scripts + 9-step verification
Implements the full E2E flow against the deployed docker stack and
documents it as a repeatable test playbook.

Surfaced and fixed three real issues while building the E2E:

1. JWT secret mismatch — docker-compose.override.yml backend was using
   a NoteLett-only JWT_SECRET that platform-service did not share, so
   every Authorization: Bearer call returned 'Invalid or expired token'.
   Aligned the override to use platform-service's actual secret
   (dev-ecosystem-secret-do-not-use-in-production).

2. CORS preflight missing PATCH/DELETE — @bytelyst/fastify-core registers
   @fastify/cors with only { origin }, which leaves Access-Control-Allow-
   Methods at the @fastify/cors default of 'GET,HEAD,POST'. Real browser
   PATCH/DELETE preflights would fail. Added an onSend hook in
   backend/src/server.ts that rewrites the header to
   'GET,HEAD,POST,PATCH,PUT,DELETE,OPTIONS' on CORS preflight responses.

3. Product 'notelett' wasn't registered with platform-service — auth
   register/login both error with 'Unknown or disabled product: notelett'.
   The seed script now POSTs to /api/products idempotently.

Deliverables:

- scripts/e2e-docker-seed.sh — idempotent: registers the notelett product
  and creates two test users (admin@notelett.app with role=admin who can
  write, user@notelett.app with role=user who is read-only). Re-runs are
  no-ops once seeded.

- scripts/e2e-docker-test.sh — 9-step E2E that drives the deployed stack
  via HTTP only (no browser): login → CORS preflight for PATCH →
  workspace create → note create → note read → note PATCH (status:
  draft→active) → note list → note delete → workspace delete.

- docs/testing/E2E_DOCKER_TESTING.md — full playbook covering prereqs,
  seed, automated E2E, manual UI smoke, stack architecture diagram,
  troubleshooting (JWT mismatch, unknown product, role rejection,
  CORS, port conflict, data loss), tear-down, CI wiring guidance.

- package.json — pnpm e2e:docker:seed and pnpm e2e:docker:test
  shortcuts.

Verified live on this host's deployed stack:

  $ bash scripts/e2e-docker-seed.sh
  ↷ product 'notelett' already exists
  ↷ admin user already registered + login works
  ✓ user created
  🟢 Seed complete.

  $ bash scripts/e2e-docker-test.sh
  ✓ user=usr_e094e0c2-... role=admin
  ✓ CORS allows PATCH
  ✓ workspace created
  ✓ note created
  ✓ note read matches
  ✓ note patched (status: draft → active)
  ✓ note list returned (1 item)
  ✓ note deleted (HTTP 204)
  ✓ workspace deleted (HTTP 204)
  🟢 All 9 E2E steps passed.

Backend regression suite still green: 380/380.
2026-05-23 01:16:19 -07:00
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
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
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
b73c969d14 feat(ui): wire platform core primitives 2026-05-06 11:12:09 -07:00
389a4c868f ci(deps): add dependency health workflow 2026-05-05 13:36:04 -07:00
694a0be0fa ci(security): add release guard audits 2026-05-05 13:34:05 -07:00
cae5941374 ci(docker): add compose smoke script 2026-05-05 13:31:10 -07:00
7fb44d09ae ci(docker): build backend and web images 2026-05-05 13:29:22 -07:00
a2053a70f1 chore(platform): add local smoke script 2026-05-05 09:29:42 -07:00
saravanakumardb1
ff7f658628 fix(docker): filter pnpm build to packages/ only — avoids mcp-server type error 2026-04-13 15:51:39 -07:00
saravanakumardb1
cc6558277c fix(docker): bash 3.2 compat + .docker-deps COPY + pnpm.overrides for transitive deps
- docker-prep.sh: replace declare -A with temp file (macOS bash 3.2)
- docker-prep.sh: inject pnpm.overrides so transitive @bytelyst/* deps resolve from tarballs
- backend/Dockerfile + web/Dockerfile: COPY .docker-deps/ into build context
- .npmrc.docker: remove scoped registry (tarballs handle all @bytelyst/* resolution)
2026-04-13 14:02:31 -07:00
saravanakumardb1
6bff2d3e2e chore(devops): add LLM env vars to .env.example, docker-compose, docker-prep 2026-04-06 11:15:36 -07:00
saravanakumardb1
0a4c13b1d6 chore: add Husky pre-commit hooks + secret-scan scripts 2026-03-27 23:07:30 -07:00
saravanakumardb1
e9f4aedb7a chore: remove docker-prep.sh — replaced by Gitea registry-backed Dockerfiles 2026-03-24 06:20:47 -07:00
saravanakumardb1
90dd2d3bd5 feat(repo): migrate notelett workspace to pnpm 2026-03-22 15:50:54 -07:00
saravanakumardb1
a71747e3fb chore(devops): add Dockerfiles, docker-compose, CI workflow, docker-prep script [C1-C5]
- backend/Dockerfile: multi-stage Node.js build (install → build → runtime)
- web/Dockerfile: multi-stage Next.js standalone build
- docker-compose.yml: backend (4016) + web (3000) with health check
- scripts/docker-prep.sh: pack @bytelyst/* tarballs + rewrite file: refs (--restore to undo)
- .github/workflows/ci.yml: backend (typecheck+test+build), web (typecheck+test+build), mobile (typecheck)
2026-03-19 08:47:04 -07:00