Tarrek Osama

Port Said local time

Colour theme

Selected workCircuit 3 · Tenants

Lead2Done CRM

One codebase, a subdomain per customer

My role
Backend architect
When
Freelance · 2023 – present
Where it stands
Freelance · client
tenantfrom hostacmeglobex*.app.com
subdomain → tenant → guard · data kept apart

What I built

The multi-tenant backend of a SaaS CRM: tenant resolution, a modular RBAC module and the Paddle payments integration.

Why it mattered

A CRM sold as SaaS must keep every customer’s data apart while running on one codebase. Billing has to stay in sync with the payment provider, even when its events arrive later.

Try itType a subdomain. Middleware resolves the tenant from it, then a guard checks the role before any action. Try an unknown subdomain, or switch to a role that can’t delete.

hostacme.app.com

tenantAcme

Signed in as an admin of Acme.

Illustration running in your browser. It shows the real system’s approach in simplified form; names and numbers are invented, and nothing here touches the real system.

What made it difficult

  • One app, many customers

    Every request has to land on the right tenant before anything else happens.

  • Roles per module

    What a user may do changes from module to module, and every endpoint must respect it.

  • Billing happens elsewhere

    Subscription changes happen at Paddle, and the app hears about them by webhook.

How I solved it

  1. Tenant from the subdomain

    Nginx wildcard subdomains send every tenant to one app, and custom middleware resolves the tenant on each request.

  2. Guards for access

    Modular role-based access control is enforced with NestJS guards.

  3. Webhooks drive billing

    Paddle payments are integrated with webhook handling, so subscriptions follow what the provider reports.

What I delivered

The backend architecture of Lead2Done, a SaaS CRM, built for a freelance client.

Multi-tenancy by subdomain, modular RBAC with guards, and Paddle billing with webhooks.

No usage numbers are published here.

Built with

  • NestJS
  • TypeScript
  • Nginx
  • Paddle
  • RBAC