mirror of
https://github.com/luxfi/financial.git
synced 2026-10-30 16:55:56 +00:00
Brand-new sibling Next.js app at app/investor/ for investor.lux.financial,
mirroring the layout/auth/build idiom of @luxbank/console while moving to
Next 15 + React 19 + Tailwind 4 + TypeScript strict.
Foundation (this commit):
- Edge middleware (src/middleware.ts) — verifies the IAM-issued JWT against
iam.luxfi.io's JWKS via jose, scopes to investorID + tenantID, and
injects X-Lux-* identity headers on every (authed) request.
- Gateway client library (src/lib/gateway/{transport,captable,transfer,
treasury,broker,audit}.ts) — typed REST surface routed through the
operator gateway (api.lux.financial) with investor scope. Zero direct
backend exposure to the browser; non-2xx responses throw GatewayError.
- Shell (src/components/shell/{Shell,Sidebar,TopBar}.tsx) — top bar with
brand + account menu, sidebar with grouped nav across all G-22 routes,
responsive grid layout. Brand interop via @luxbank/brand.
- Shared UI primitives (src/components/{data,forms}/) — Card, DataTable,
Notice, Stat, PageHeader, Button, Select.
- Sign-in/out (src/app/(unauthed)/{signin,signout}/) plus API routes for
OIDC callback and magic-link request.
Stage 10.1 — Account dashboard (src/app/(authed)/dashboard/):
- Portfolio NAV summary card with 24h/7d/30d deltas.
- Positions table per offering with quantity, cost basis, NAV, unrealized
P&L, lockup remaining, restrictions label.
- Cost-basis method toggle (FIFO / LIFO / specific-lot) drives a server
re-fetch via ?method=.
- Pending settlement panel with T+0/T+1/T+2 bucket badges and per-trade
side/price/gross.
- Server-side data fetched in parallel via Promise.allSettled so a
single backend hiccup degrades gracefully.
Stage 10.10 — Audit log (src/app/(authed)/activity/):
- Filterable timeline of investor-initiated actions (auth, document,
trade, withdrawal, profile, beneficiary, kyc, comms).
- Filters: category, outcome, since, until — URL-driven.
- Per-entry: timestamp, action verb, target ref, description, IP, UA,
outcome, optional error.
- CSV export — same-origin /api/audit/export.csv proxies the gateway
endpoint with the caller's identity and streams text/csv back.
Tests (vitest + happy-dom + @testing-library/react) — 29 tests across 8
files, all passing:
- auth/session — header extraction + SessionError surface.
- auth/sign-in-url — OIDC authorize + signout URL construction.
- gateway/transport — URL prefixing, identity-header injection, JSON
body + content-type, 204 handling, GatewayError mapping.
- gateway/audit — CSV row escaping (RFC 4180-aware column counter).
- format — currency / percent / number / date / signClass.
- dashboard — render of PortfolioSummaryCard, PositionsTable,
PendingSettlementsCard against typed fixtures.
- activity — render of AuditTimeline (multiple categories + outcomes).
- middleware — matcher regex shape.
Build: pnpm install + pnpm -F @luxbank/investor build → green; 8 routes
compiled (/, /dashboard, /activity, /signin, /signout,
/api/auth/callback, /api/auth/magic-link, /api/audit/export.csv) +
40 kB middleware bundle.
Contract for other G-22 agents:
- Middleware sets X-Lux-Sub / X-Lux-Investor-Id / X-Lux-Tenant-Id /
X-Lux-Email / X-Lux-Name / X-Lux-Exp on every (authed) request.
Read via headers() in any server component / route handler, or use
the readSessionFromHeaders helper.
- gateway clients are server-only (transport.ts lazy-imports
next/headers). Client components must call through a server action or
API route — never import @/lib/gateway directly in 'use client' files.
- New backend sub-clients append to src/lib/gateway/index.ts; they
reuse callGateway() from transport.ts (one path-prefix per service
→ captable / transfer / treasury / broker / audit). Add the entry
to src/components/shell/Sidebar.tsx for nav.
Source-of-design: Lux-Prior-IP
Source-ref: 96510a0caf
Clean-Team-Member: dev-agent (G-22a foundation + dashboard + audit)
Signed-off-by: dev <[email protected]>
6 lines
72 B
JavaScript
6 lines
72 B
JavaScript
module.exports = {
|
|
plugins: {
|
|
'@tailwindcss/postcss': {},
|
|
},
|
|
};
|