Commit Graph

169 Commits

Author SHA1 Message Date
saravanakumardb1
91b859746b fix(docker): bake NEXT_PUBLIC_* values at build time, drop hardcoded api.bytelyst.com
Root cause: docker-compose.yml hardcoded NEXT_PUBLIC_NOTES_API_URL to
https://api.bytelyst.com/notelett — a production URL that doesn't
exist on this network — as the *build arg* for the web image. The
docker-compose.override.yml correctly set localhost:4016/api but only
on the runtime environment, which has no effect because NEXT_PUBLIC_*
values are baked into the Next.js bundle at build time (pnpm run build
inside the Dockerfile), not read at runtime.

Symptom: every authenticated client-side fetch from the deployed web
container went to https://api.bytelyst.com/notelett/... which the
corporate proxy intercepted with a blockpage. The saved-views client
in particular fired on every (app)/ layout mount, surfacing a
'Failed to fetch' toast on dashboard load. 4 release-flows.spec
tests failed because page.route('**/api/**') couldn't match the
api.bytelyst.com URLs at all.

Discovery: inspected the deployed bundle inside the running container.
'grep -oE "api.bytelyst.com" /app/web/web/.next/static/chunks/*.js'
returned multiple hits across the (app)/ layout, (auth)/ pages, and
share page. The string was absent from the source tree, which proved
it had been injected at build time via the broken arg default.

Discovery debug pattern (kept for future use):
  page.on('requestfailed', r => console.log(r.method(), r.url()));
  page.route('**/api/**', route => route.fulfill({status:200,body:'{}'}));
  await page.goto('/dashboard');
  // FAILED REQUESTS will list any URL not under /api/** that the SPA
  // attempted, exposing baked-in production URLs immediately.

Fix (three layers, defense in depth):

1. docker-compose.yml — replace hardcoded
   'NEXT_PUBLIC_NOTES_API_URL: https://api.bytelyst.com/notelett'
   in the build.args block with
   '${NEXT_PUBLIC_NOTES_API_URL:-http://localhost:4016/api}'.
   Same treatment for the runtime environment block. Add build args
   for the four other NEXT_PUBLIC_* values (extraction, MCP,
   diagnostics, product name/id, telemetry transport) so a single env
   var on the host controls both build and runtime layers.

2. web/Dockerfile — declare ARG and ENV lines for all seven
   NEXT_PUBLIC_* values so the build args reach 'pnpm run build'.
   Previously only NOTES_API_URL and PLATFORM_SERVICE_URL were
   declared, which meant overriding extraction/MCP/diagnostics via
   docker compose silently had no effect on the bundle.

3. docker-compose.override.yml — add a build.args block mirroring the
   four URL overrides so the local-only override also reaches build
   time, not just runtime. Comment block explains the bake-time vs
   runtime distinction so future contributors don't repeat the bug.

Verified end-to-end after the fix:
  - docker compose build --no-cache web + up -d → grep of bundle now
    shows 'localhost:4016/api', api.bytelyst.com fully gone.
  - Debug interception test: zero requestfailed events on /dashboard.
  - Playwright release-flows.spec.ts: 4 failed → 4 passed (after URL
    fix; no test code changed for these four tests).
  - Full Playwright suite (--ignore-snapshots): 43 passed.
  - scripts/e2e-docker-test.sh: 9/9 backend API lifecycle steps pass.
  - pnpm run verify: backend 380/380, web 96/96, mobile 97/97.
2026-05-23 10:04:36 -07:00
saravanakumardb1
131b73cfc1 fix(web): repair Next.js standalone static-chunks 404 in Docker + harden 2 e2e specs
Root cause of bug: web Dockerfile copied .next/static to the wrong path
in the runtime stage. The Next.js 16 standalone server (CMD 'node
web/server.js' from /app/web) runs from /app/web/web/server.js because
'standalone' wraps the source directory. It serves /_next/static/* from
'./web/.next/static' (relative to the standalone server's location),
not from './.next/static' (which is what the previous COPY produced).

Symptom: in the deployed Docker stack at http://localhost:3050 every
client-side JS chunk under /_next/static/chunks/* returned HTTP 404
with content-type text/plain. The browser refused to execute the
chunks (strict MIME), so the SPA never hydrated. All Playwright tests
that ask for any dynamic UI text on a (app)/ page would time out
because AuthGuard never ran in the browser.

Discovery path: deployed compose stack via 'docker compose up -d
--build' + 'scripts/e2e-docker-test.sh' (backend API 9/9 ✓), then ran
Playwright against NOTELETT_WEB_PORT=3050. settings.spec failed with
'product configuration section' not visible. Page snapshot showed
just <skip-to-content link> + toast region — no other content. Console
logs revealed every /_next/static/chunks/* was 404 with text/plain.
'docker exec ls' showed BUILD_ID at /app/web/web/.next/BUILD_ID and
static at /app/web/.next/static — wrong path. Moved static into the
standalone tree and chunks now serve 200 with application/javascript.

Fix:
  web/Dockerfile: change
    COPY --from=builder /app/web/.next/static ./.next/static
  to
    COPY --from=builder /app/web/.next/static ./web/.next/static
  with explanatory comment so this doesn't regress.

Test hardening (these tests were dev-server-only by accident — they
worked locally because Next.js dev did not enforce the same static
path layout; the bug above hid them in production builds too):

  web/e2e/accessibility.spec.ts — 'focus-visible ring appears on tab
  navigation' was navigating to /dashboard which AuthGuard correctly
  redirects when unauthenticated, leaving the DOM empty (AuthGuard
  returns null until verifySessionAndReadiness completes) so Tab
  presses focused nothing. Switched to /login which is unauthenticated
  by design and has known focusable form inputs.

  web/e2e/settings.spec.ts — 'shows product configuration section'
  expected /settings to render content without auth. Now obtains real
  tokens from platform-service via API, seeds them via addInitScript,
  and falls back to test.skip with a clear message if platform-service
  is not reachable.

Verified:
  - All 31 Playwright tests across navigation/accessibility/dashboard/
    search/settings/smart-actions/reviews specs PASS against the
    deployed Docker stack at :3050.
  - 'pnpm run verify': backend 380/380, web 96/96, mobile 97/97.
  - 'bash scripts/e2e-docker-test.sh': 9/9 backend API CRUD steps pass.
  - 'curl -sI http://localhost:3050/_next/static/chunks/app/error-*.js'
    now returns 200 + application/javascript.

Not migrated: e2e/release-flows.spec.ts and e2e/visual-regression.spec.ts
intentionally remain dev-server-targeted. release-flows.spec uses
page.route() to mock backend responses and is meant to test the UI in
isolation against a dev server. visual-regression.spec needs baseline
regeneration after the UI5-UI8 migration; this is a separate workstream
tracked in docs/UI_UX_PLATFORM_CORE_ROADMAP.md.
2026-05-23 02:29:40 -07:00
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
8d484c30d1 feat(web/ui6): migrate dashboard, workspaces, search, chat pages
Phase UI6 — the three highest-traffic operator surfaces plus chat
move off legacy globals onto @bytelyst/ui Card + Badge + Input +
Select + Textarea + Button primitives via the local adapter.

dashboard/page.tsx:
- Welcome card, Saved views card, Quick links card, Operator workflows
  card, Recent note activity card — all section.surface-card → Card.
- All saved-view/quick-link/workflow/note rows: surface-muted with
  inline styles → grid+rounded+bg utility classes with hover state.
- All inline 'badge' spans (scope, status, tags) → Badge with
  semantic variants (workflow status maps to warning/success).

workspaces/page.tsx:
- Saved-views aside, filter section, workspace article rows, error
  banner — all surface-card → Card.
- Filter input → Input. Visibility/owner/tag chips → Badge.
- Workspace-note rows → utility-class hover panels.

search/page.tsx:
- POST /notes/search action chip → Badge.
- Saved searches aside + results pane — both surface-card → Card.
- '+ Save current' button + per-view Remove button — raw <button>
  → Button (size sm, ghost variant for Remove).
- Search input + filter chips + result rows — Input + Badge +
  utility-class panels.

chat/page.tsx:
- Workspace <select> → Select with options=[{value,label}].
- Question <textarea> → Textarea.

Ratchet impact for this commit:
  raw interactive controls       25 → 19  (-6)
  legacy global surface classes  67 → 38  (-29)

Cumulative since session start (38/92 baseline):
  raw   38 → 19  (-19)
  legacy 92 → 38  (-54)

Verified: pnpm typecheck, test (96/96), audit:ui:ratchet at new
baseline.
2026-05-23 01:38:35 -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
7103660c95 test(e2e): fix 4 pre-existing E2E failures and make port-conflict-proof
Audit of the full E2E suite (43 specs) surfaced four issues that were
hiding behind 'all 96/96 web unit tests pass' but actually meant the
browser-level coverage was broken end-to-end. All four are fixed and
the suite now passes 43/43.

1. Port conflict silently testing wrong app. playwright.config.ts hard-
   coded baseURL=http://localhost:3000 with reuseExistingServer:true on
   non-CI hosts. When the dev host had ANY service on :3000 (Grafana,
   chronomind, etc), Playwright happily ran the entire E2E suite
   against the wrong app and reported the unrelated failures as
   'real'. Now honors NOTELETT_WEB_PORT env (default 3000) so a
   contributor can opt into any free port and Playwright drives both
   baseURL and the dev-server PORT consistently.

2. Missing test dependency. web/e2e/accessibility.spec.ts imports
   @axe-core/playwright but web/package.json never declared it.
   The accessibility coverage was DOA — every CI run that included
   this spec would module-not-found-error before a single check ran.
   Added @axe-core/playwright to devDependencies.

3. Mock that never fires. smart-actions.spec.ts 'history API mock
   returns items' used page.route() to mock /api/note-prompts/history
   then bypassed the mock entirely with page.request.get() (which uses
   Playwright's separate request context, not the browser context that
   page.route intercepts). The request went to the dev server and got
   404. Replaced with page.goto + page.evaluate(fetch(...)) so the
   browser-side fetch hits the page.route mock as intended.

4. Missing visual-regression baselines. visual-regression.spec.ts had
   no committed baseline screenshots for dashboard / workspaces /
   search. First run on a clean host always reported 'snapshot doesn't
   exist, writing actual'. Generated and committed darwin baselines.

Verified end-to-end (NOTELETT_WEB_PORT=3050 against this host's free
port):
  43 passed (34.8s)

Total test-tier counts on main now:
  backend unit + integration (memory)   380/380
  backend cosmos emulator (live)        4/4
  web vitest                            96/96
  mobile vitest                         97/97
  web playwright e2e                    43/43
  ---
  TOTAL                                 620/620
2026-05-23 00:50:29 -07:00
saravanakumardb1
3c4d46f3ad fix(web): resolve the 5 actionable React-compiler lint advisories
Web lint warnings reduced from 20 → 15 by fixing the categories that
flag real architectural smells rather than the canonical
fetch-on-mount setState pattern.

Real fixes:

1. web/src/lib/use-theme.ts — replace useEffect + setState mount-sync
   pattern with React.useSyncExternalStore. The hook now subscribes to
   browser storage events, returns a stable snapshot for SSR, and uses
   a manual storage-event dispatch so same-document setters refresh
   correctly. Eliminates the cascading-render advisory and gains free
   cross-tab theme sync.

2. web/src/lib/use-keyboard-shortcuts.ts — move ref assignment from
   render time into a useEffect. Fixes the 'Cannot access refs during
   render' advisory without behavior change.

3. web/src/components/NoteEditor.tsx — move onSaveRef.current = onSave
   from render time into a useEffect for the same reason.

4. web/src/app/(app)/reviews/page.tsx — wrap handleDecision and
   handleBatchDecision in useCallback so the useEffect that depends
   on them no longer re-subscribes the keydown listener on every
   render. Fixes both react-hooks/exhaustive-deps warnings and the
   underlying perf bug they pointed at.

5. web/src/app/(app)/prompts/page.tsx — wrap loadTemplates in
   useCallback declared before the useEffect that calls it. Fixes
   the 'Cannot access variable before it is declared' advisory.

Remaining 15 warnings are React-compiler runtime hints about
fetchData().then(setData) patterns inside useEffect, which is the
canonical fetch-on-mount pattern shown in React's own docs. Resolving
them properly requires Suspense + use() or risky startTransition
wraps; both are out of scope and tracked under future tech debt.

Verified:
- pnpm --filter @notelett/web run typecheck: passes
- pnpm --filter @notelett/web run lint: 0 errors, 15 warnings (down 5)
- pnpm run verify: backend 380/380, web 96/96, mobile 97/97
2026-05-23 00:20:02 -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
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
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
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
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
db9b4557d8 refactor(ui): remove legacy shell css 2026-05-06 13:40:24 -07:00
7063e59078 refactor(ui): isolate notelett navigation 2026-05-06 13:37:49 -07:00
63211c0019 feat(ui): consume common app shell 2026-05-06 13:35:54 -07:00
6c562f05d8 test(ui): add review visual smoke 2026-05-06 13:28:57 -07:00
6472a58ad1 feat(ui): add review empty states 2026-05-06 13:18:52 -07:00
d63fdd1def feat(ui): add review keyboard shortcuts 2026-05-06 13:15:37 -07:00
de75d93e59 refactor(ui): split review workflow components 2026-05-06 13:13:46 -07:00
c79aa2b6fd feat(ui): migrate review workflow primitives 2026-05-06 11:43:34 -07:00
cf5e9c03fd feat(ui): add notelett primitive defaults 2026-05-06 11:36:05 -07:00
0f5ddb400b feat(ui): map platform tokens globally 2026-05-06 11:34:23 -07:00
b73c969d14 feat(ui): wire platform core primitives 2026-05-06 11:12:09 -07:00
5e38496d8a test(web): run Playwright release flows 2026-05-05 14:07:34 -07:00
9bded74567 fix(lint): clear production lint blockers 2026-05-05 14:04:49 -07:00
00d022071d docs(roadmap): record P10.1 verification 2026-05-05 13:56:26 -07:00
d929247db5 ci(web): add playwright e2e job 2026-05-05 13:27:12 -07:00
6b896949d4 chore(web): add bundle analysis gate 2026-05-05 12:45:20 -07:00
62cda1fb22 test(web): add release journey e2e coverage 2026-05-05 12:34:25 -07:00
e71febe51a fix(sharing): harden note share revocation flows 2026-05-05 12:25:16 -07:00
09f30c003e feat(notes): harden import export readiness 2026-05-05 12:15:11 -07:00
a72d6b79d3 fix(web): add user-facing dependency states 2026-05-05 11:59:17 -07:00
454b2003e9 fix(web): add mutation retry handling 2026-05-05 11:45:25 -07:00
6418ab2836 fix(web): harden auth session refresh flow 2026-05-05 11:40:55 -07:00
837a187bd1 fix(web): stabilize mobile layouts 2026-05-05 10:58:10 -07:00
d26a4ae9de refactor(web): use shared ui primitives 2026-05-05 10:49:25 -07:00
01c2d31514 fix(web): label interactive controls 2026-05-05 10:22:49 -07:00
6ede2bee7e refactor(web): replace hardcoded app colors 2026-05-05 10:17:06 -07:00
efa20979fc test(platform): verify client propagation 2026-05-05 09:33:10 -07:00
da3129c89b fix(platform): align mcp service urls 2026-05-05 09:19:11 -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
cce4ca610f refactor(web): merge platform-api.ts into platform.ts
platform.ts and platform-api.ts both created PlatformClient instances.
Merge all typed helpers (getUserSettings, updateUserSettings,
listSessions, revokeSession, updateProfile) into platform.ts and
delete the duplicate file. Use lazy singleton instead of eager.
2026-04-13 11:06:40 -07:00
saravanakumardb1
4813c850a3 feat(web,mobile): add @bytelyst/billing-client and platform-client
Web:
- New lib/billing-client.ts: factory wrapper using shared getAccessToken.
- Add @bytelyst/billing-client to web deps.

Mobile:
- New lib/billing-client.ts: factory wrapper using MMKV token storage.
- New lib/platform-api.ts: typed platform-client wrapper for settings,
  sessions, and profile management.
- Add @bytelyst/billing-client and @bytelyst/platform-client to deps.
2026-04-13 10:30:02 -07:00
saravanakumardb1
58a778bc1e feat(web): init feature flags + kill switch on startup, fix hardcoded colors
- Providers.tsx now calls initFeatureFlags() and checkKillSwitch()
  on mount (both were wired but never initialized).
- globals.css: replace hardcoded #0b1020 with color-mix() from canvas token.
- layout.tsx: make themeColor responsive (dark/light media queries).
- use-theme.ts: prefix localStorage key with PRODUCT_ID for consistency.
2026-04-13 09:59:54 -07:00
saravanakumardb1
4246d58798 fix(docker): switch Alpine to Debian slim and remove prod NODE_TLS_REJECT_UNAUTHORIZED
Alpine breaks under corporate proxy TLS interception. Debian slim
works reliably. NODE_TLS_REJECT_UNAUTHORIZED=0 removed from production
stages — only kept in build stages where npm registries need it.
2026-04-13 09:59:36 -07:00