SaaS platform · CRM
Multi-tenant SaaS CRM
A CRM where every company gets its own isolated workspace, covering contacts, deals, leads, invoices, tickets, marketing, telephony and automation.
- Multi-tenant architecture
- Postgres RLS
- RBAC
- Payment idempotency
- Design systems
- Edge APIs

Product screens with sample data. Names and figures inside the screens are illustrative.
The problem
One codebase serves many companies at once, each with its own members, roles, data and billing. The hard requirement: no workspace can ever read another workspace's records, whatever happens in the interface.
- ~100
- Database tables
- 25+
- Product modules
- RLS
- Isolation enforced in Postgres
What I built
A pipeline teams actually live in
Deals, contacts, leads and tickets share one consistent workspace, built from a single-source component library so every module looks and behaves the same.

Permissions as data, enforced in the database
Role-based access through workspace-role permission sets, backed by row-level security. The UI hides what you can't do; Postgres refuses it.
- Per-module view, create, edit, delete and export
- Record scope: own, team or workspace
- Tenant isolation on every query

Onboarding that sets up a whole company
A multi-step workspace wizard with cascading country, state and city selects, localisation and monthly or yearly plans.

Payments that survive retries
Invoices record every payment event. A redelivered webhook is recognised by its event id and ignored, so a retry never becomes a second charge.

Key decisions
Schema first, screens second
Roughly 100 tables across 25+ modules with workspace-level isolation, soft deletes and numbered, idempotent migrations.
Edge-first API
A Hono and TypeScript API on Cloudflare Workers, with Supabase Postgres for data and R2 for files.
Architecture that guards itself
Automated reviewer roles (Component Librarian, Design System Guardian, Architecture Guardian) keep the frontend on one component library.
