Commit Graph

4 Commits

Author SHA1 Message Date
Sharang Parnerkar 0797f8f99c feat(portal): M10.2 — MSW handlers + ToastHost + InviteButton end-to-end
ci / test (pull_request) Failing after 4m54s
ci / shared (pull_request) Successful in 11s
ci / e2e (pull_request) Has been skipped
ci / image (pull_request) Has been skipped
Closes out the design pass with the missing piece: a real client-side
mock-API pipeline so the write-path CTAs the design shows (invite a
teammate, run a scan, kick off a workflow test, request reactivation)
actually do something visible without a backend.

* `public/mockServiceWorker.js` — generated by `pnpm exec msw init`.
* `src/mocks/handlers.ts` — POST handlers for `/api/team/invites`,
  `/api/scans`, `/api/workflows/:id/test`, `/api/billing/reactivate`.
  Each returns the design's mono status-code header
  (`201 · invite.created`, `202 · scan.queued`, etc.) so the toast
  surface reads identical to the handoff. A `x-bp-tenant-status` hint
  header lets the same handler respond 402 (frozen) or 410 (archived)
  without needing a real session.
* `src/mocks/browser.ts` — thin `setupWorker(...handlers)` wrapper,
  imported lazily so prod bundles don't pull MSW.
* `src/components/portal/MockWorker.tsx` — client component that boots
  the worker only when `window.__BP_MOCK_API__` is true (set by
  `[slug]/layout` when `BP_DEV_FIXTURE` is on the server). Real Auth.js
  builds skip the worker entirely.
* `src/components/portal/ToastHost.tsx` — global bottom-right toast
  queue, mounted in `[slug]/layout`. Emits via a custom event so any
  client component can call `toast({ msg, code })` without prop-drilling.
* `src/components/portal/InviteButton.tsx` — first live write affordance.
  Modal with email + role-segmented buttons, POSTs to `/api/team/invites`
  with the tenant-status hint header, surfaces 201/402/410 differently.
  Wired into the Team page.
* `src/middleware.ts` — added `mockServiceWorker.js` to the matcher
  exclusion list so the host-rewrite doesn't 404 the worker script.

Verified end-to-end via Playwright: SW registers at the root scope,
click Invite member → fill email → Send invitation → MSW intercepts →
toast "Invitation sent · 201 · invite.created" → modal closes.

This closes the last open M10.2 task. Branch is ready to review/merge.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-04 16:11:18 +02:00
Sharang Parnerkar f3c95123fa feat(portal): M10.2 design system foundations — tokens, shell, Dashboard
Brings in the handoff design system from `Breakpilot Platform.zip`
(`breakpilot/design_handoff_customer_portal/`) as the base for restyling
every customer-area surface.

What's in:

* **Design tokens & layout primitives** — `src/app/globals.css` is the
  handoff `styles.css` in full (OKLCH paper + ink + brand-violet,
  --rule-* hairlines, --sev-* severity ramp, corner-tick bracket
  treatment, ledger table, 32–36px row density, dark mode via
  `[data-theme="dark"]`). Tailwind v4 layered on top via PostCSS for
  utility helpers; the design system itself stays in plain CSS.
* **Geist + Geist Mono** wired through `next/font/google` so the
  monospaced metadata/figures everywhere render at the intended weight.
* **Shell chrome** under `src/components/portal/`:
  `Brand` (Breakpilot. wordmark with the violet trailing dot),
  `Lifeline` (top full-width tenant rail — active / trial / frozen /
  demo variants; archived swaps in `ArchivedLockout`),
  `NavRail` (232px left rail with tenant switcher + workspace/admin/
  settings groups + user chip; locked routes show a lock icon and a
  "Requires X" tooltip rather than vanishing),
  `Topbar` (breadcrumb + ⌘K button placeholder + theme toggle),
  `ThemeToggle` (Sun/Moon, persists to `localStorage["bp.theme"]`,
  no-flash via a head script in the root layout).
* **Dashboard** at `/[slug]/dashboard` rebuilt per handoff §1:
  page-head with Export + Run scan (the latter wrapped in the frozen
  write-guard hovercard surfacing `HTTP 402 · payment required`),
  5-cell bracketed KPI rail (open findings + 14-day sparkbars + 7-day
  delta, critical with severity stack, controls passing with violet
  ring gauge + n/240, evidence area sparkline, last-scan cadence),
  12-col grid: 30-day findings flow + severity stack legend +
  top-5 open findings table on the left, product posture rows +
  scan-activity heatmap (5x7) + recent-activity feed on the right.
  Plain USER role drops the KPI rail and the org-wide panels per spec.
* **Charts** — minimal SVG primitives in `components/portal/charts/`:
  Sparkbars, Sparkline (area + line), Ring, StackBar, Heatmap +
  HeatLegend. All token-driven (`var(--sev-*)`, `var(--accent)`).
* **Fixtures** — `src/lib/fixtures.ts` is a TS port of the handoff's
  `data.js`. Deterministic mulberry32 generators give the same
  realistic DACH/EU compliance data every reload (~5 tenants × 30+ days
  activity / 4–13 findings per product / 9 months invoices / hash-
  chained audit). Source of truth for the design until tenant-registry
  is enriched to carry these fields end-to-end. RBAC table (`canAccess`,
  `landingFor`) ported alongside.
* **Dev session bypass** — `src/lib/get-session.ts` returns a synthetic
  `SessionWithExtras` from one of the 6 fixtures when
  `BP_DEV_FIXTURE=<id>` is set. Lets the portal render the design
  without Keycloak + tenant-registry up. Real Auth.js wiring untouched.

What's NOT in yet (next commits):

* Products / Product launch / Org / Team / Billing / Audit / SSO pages
* Workflows editor (palette + canvas + inspector + drag-wiring)
* Command palette + toast system
* MSW handlers for the tenant data shapes (today the page reads the
  fixture module directly server-side; MSW is for client-side calls)

Run locally:
  pnpm install
  BP_DEV_FIXTURE=admin-acme pnpm dev
  open http://acme.localhost:3000/acme/dashboard

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-04 13:29:29 +02:00
sharang 99fe3b55b2 feat(test): M5.3 — Playwright e2e harness for the dev stack
ci / shared (push) Successful in 4s
ci / test (push) Successful in 23s
ci / e2e (push) Has been skipped
ci / image (push) Has been skipped
playwright.config.ts + tests/e2e/{apex,tenant,health}.spec.ts. make e2e for local. CI e2e job opt-in via RUN_E2E repo variable. OIDC click-through deferred to when stage is up.

Refs: M5.3
2026-05-19 14:53:18 +00:00
sharang e7a1290246 feat(app): Next.js 16 + Auth.js v5 portal skeleton
ci / shared (push) Successful in 4s
ci / test (push) Successful in 26s
ci / e2e (push) Has been skipped
ci / image (push) Has been skipped
Next.js 16 + Auth.js v5 skeleton: host→slug middleware, tenant-context layout, OIDC sign-in flow against breakpilot-dev realm. 100% coverage on src/lib. Bumps next to 16.2.6 to clear trivy CVEs in 15.0.3.
2026-05-19 09:35:05 +00:00