Skip to content
louay_amor~
Aug – Oct 2026client work

Gamma Academy

I build real products, not just deploymentsFour consoles 110 agencies one database—no mess of multiple apps or logins

problem

The challenge: building a platform that works for many partners without copying or remaking apps for each one

I focused on multi-tenant solutions to keep things simple and reusable

  • Built a modular monolith with NestJS for all consoles
  • Enabled partner branding and URLs with config not extra code
  • Used Cloudflare DNS and simple deploys for all partners
  • Kept all tech choices tracked in clear decision records

pipeline

decisions

  1. Modular monolith with strict module boundaries over microservices.

    tradeoffNo independent scaling of individual domains.

    outcomeOne deployable, one database, no distributed-transaction fallout across identity, registration, agences, and challenges modules.

  2. Schema-level tenancy: a Partenaire table and a required partenaireId FK on every tenant-owned model.

    tradeoffEvery tenant query gets an extra indexed condition and a migration cost when the model set changes.

    outcomeOnboarding the next partner is a database row plus a config entry. No new deployments.

  3. Resolve tenant from the JWT payload, never the URL.

    tradeoffExtra auth coupling in the default grant.

    outcomeA mismatch between the session user and the URL slug is rejected instead of leaking cross-tenant data in the wrong surface.

  4. Run staging and production as separate stacks on one droplet behind one wildcard DNS record.

    tradeoffDisk and compute contention on shared nodes until load justifies a split.

    outcomeDeploys, sonar reports, and staging verifications stay cheap and reproducible with the migration path (managed Postgres, per-partner droplets) kept open.

results

agencies
110
multi-tenant scope
enrolled students
1,618
automated checks
1,005+
451 API, 225 web, 329 end-to-end
Prisma models
41
zero-downtime releases
Yes
4-stage Docker builds

stack

Backend

  • NestJS
  • PostgreSQL
  • Prisma
  • Redis

Frontend

  • Next.js 16
  • React 19
  • Route groups

Repo

  • pnpm
  • turborepo
  • Workspaces

Testing

  • Jest
  • Vitest
  • Playwright

Delivery

  • Docker
  • 4-stage builds
  • nginx
  • GitHub Actions

Platform

  • DigitalOcean
  • Cloudflare DNS
  • SonarQube