NC Nati Correa
AI systems and agents
40.7128 N / 74.0060 W
LOG / 02
/ Case study / Pugs Media

The client portal

The agency's client-facing product, where contracts, payments, messaging, and onboarding all live behind deny-by-default security. Every client runs on it.
/ The problem

Client-facing operations lived in a third-party tool that covered a fraction of the workflow and none of the agency's shape. Contracts, payments, status, and messaging each needed a login somewhere else.

The bar for replacing it was production software rather than a demo, because it would handle real money, real signatures, and real client data with hard isolation between clients. It also had to be operable by a four-person team without babysitting.

/ What I built

A Next.js and Supabase portal where the database itself enforces who sees what: role and client identity are stamped into the auth token server-side, all 23 tables run row-level security, and the model is deny by default, so no policy means no access even if application code slips. The audit log is append-only at the database level; not even the server's own admin role can edit history.

Contracts e-sign through DocuSeal with cryptographically verified webhooks. Payments run on Stripe: month one is charged at signature and the card saved, months two onward roll into a subscription automatically. Client messages relay into the team's Slack, and nothing goes back to a client unless a human explicitly writes it; a CI gate fails any build that even imports an email-sending library. Onboarding walks a new client one locked step at a time, proposal to signature to payment to kickoff, and the moment a contract is signed the client's CRM record creates itself. None of it is theoretical, either; real clients run the whole flow in production, from proposal to paid.

22,213lines of TypeScript
23tables, all deny-by-default
36row-level security policies
100%of clients run on it
/ Proof
Security posture / enforced in the database and in CITABLES ..................... 23, RLS ON ALL 23
POLICY MODEL ............... DENY BY DEFAULT
LIVE POLICIES .............. 36
ISOLATION PROOF ............ 24 SQL ASSERTIONS, TWO SEEDED TENANTS
AUDIT LOG .................. APPEND ONLY, EVEN FOR ADMIN
E-SIGN WEBHOOKS ............ HMAC VERIFIED, TIMING SAFE
EMAIL-SENDING LIBRARIES .... BLOCKED IN CI
LOGGED-OUT REQUEST ......... REDIRECTED, NOTHING RENDERED
/ Inside the product
These screens are recreated in HTML straight from the production codebase, using the real layouts and copy with invented demo clients, so nothing real ever needed blurring. / Built to be operated

Production software earns its keep by running itself. Eight scheduled jobs handle CRM sync, contract nudges, message nudges, upload watching, and relay health checks. Staff get a sandbox mode that clones a real client into a throwaway test tenant and walks the entire journey, proposal to signature to payment, in Stripe test mode, with a hard guard so teardown can never touch a real client.

Before the all-client cutover, a four-pass audit covered payments, access control, legal, and debugging. Access control came back clean, with no path found for one client to reach another's data, and the money-path error handling was hardened so a failed database write can never report success. Everything shipped before the cutover.

Back to the build log