Skip to content
Mudassir MohammedRésumé

Personal project

Nexus SaaS

A multi-tenant business platform: one codebase serving many organisations, each with its own subdomain, features, roles and billing.

Role
Sole engineer
When
Nov 2025 – Mar 2026
Status
In progress
Stack
Next.js · TypeScript · PostgreSQL · Prisma · NextAuth · Stripe

Overview

Nexus is a business-management platform for agencies and small companies that want separate, branded workspaces from a single deployment. Each tenant gets a subdomain or a custom domain. Each tenant also gets its own set of enabled modules, roles and permissions, and a subscription.

The modules are deliberately broad. The interesting work is the layer underneath them that every module relies on.

The platform layer

  • Tenant resolution. The request host is normalised, then matched to a tenant by subdomain or by a mapped custom domain.
  • Shared schema. Tenant-owned tables carry a tenant id, and queries are scoped to it.
  • Permissions. Around 40 seeded permission keys such as finance.invoice.create, attached to roles per tenant and checked in server actions.
  • Feature flags. Per-tenant flags decide which modules a tenant has, and the navigation follows them.
  • Billing. Stripe Checkout and subscriptions. Webhooks are verified, deduplicated and update the tenant's plan.
  • Operations. A super-admin panel for provisioning tenants, toggling features and reviewing usage, plus an audit log for sensitive changes.

Engineering decisions

  1. Idempotent webhook handling

    Why
    Stripe retries webhooks, and a retried checkout.session.completed must not provision twice. Each event is claimed by id in a WebhookEvent row before it's handled. A duplicate returns 200 so Stripe stops retrying. A failure releases the claim so the retry can run.
  2. One guard for super-admin actions

    Why
    Admin checks used to be mixed across actions. I replaced them with a single super-admin guard and applied it to every cross-tenant action, including usage reporting, which had been missing a check.
  3. Tenant deletion in a transaction

    Why
    Deleting a tenant removes its dependent records in one transaction, so a failure part-way can't leave orphaned data behind.

Known gaps

Nexus isn't finished, and the backlog says so:

  • Many module actions check tenant membership but not the specific permission. Enforcing per-action permissions everywhere is the top item, ahead of any new feature.
  • Read and write permission semantics need tightening, so that every mutation maps to one stable key and the UI hides exactly what the backend forbids.