A compliance dashboard for fintech teams: alert triage, restricted-list screening and beneficiary KYC, with a real TOTP login that demos without a backend.

Home: pending payment alerts grouped by rule (hardstop, general, potential match)

Clients: searchable, paginated TanStack Table with per-client alert counts

Restricted lists: beneficiaries screened across blacklist, greylist and whitelist

First-login TOTP enrollment: the QR code is generated client-side from a real otpauth URL
// OVERVIEW
Compliance work is queue work: payment alerts to clear, names to screen against restricted lists, beneficiary files to keep current, KYB documents to check. Adamo Compliance puts those queues on one screen. I built it for Adamo end to end on Next.js 15 and React 19: the component library on shadcn/ui and Tailwind CSS 4, the TanStack Query data layer, Zod validation on every form, Spanish and English copy through next-intl, and a Supabase auth layer with TOTP two-factor.
One requirement shaped the architecture: the portfolio demo had to run with no backend at all. Instead of ripping auth out, I kept the real Supabase integration and wrote a mock behind the same three client factories. It implements exactly the supabase-js surface the app touches, keeps the session in a cookie the Next.js middleware can read, remembers MFA enrollment across sign-outs, and saves profile edits to localStorage. The same code runs against live Postgres, Auth and TOTP MFA once two env vars are set; the mock is there so the public demo needs zero configuration.
Every flow on the live demo is clickable with the pre-filled credentials. First login forces a password change and TOTP enrollment with a generated QR code, a return visit gets the six-digit challenge, and the forgot-password loop completes without sending an email. 71 Vitest tests cover the same service layer the UI runs on.
The performance pass was mostly deleting things. The data services shipped with a hard-coded 800 ms delay, so it went first. Lodash moved to per-method imports, which cut the heaviest route's JavaScript by 65%, from 36.6 kB to 13 kB. A route-level loading state covers the gap, and ESLint and tsc come back clean.
// KEY FEATURES
When Supabase env keys are absent, the same client factories serve a mock that stores the session in cookies, so Next.js middleware still guards every route.
First-login password change, TOTP enrollment with a generated QR code, and a 6-digit challenge modal for returning users, all on @supabase/ssr cookie sessions.
Clients, payment alerts (hardstop / general / potential match), beneficiaries, KYB documents and restricted lists, built on TanStack Query and Table.
Spanish and English via next-intl; every screen, form error and toast is translated.
71 Vitest tests cover the auth and user services against the mock client; type-check, ESLint and the production build run clean with zero env vars.
// RELATED WORK