Multi-tenant CMS and Billing Platform
One backend serving many client websites, each defining its own content types, its own team permissions and its own subscription.
Problem
An agency running websites for many clients was maintaining a separate backend per site. Every client wanted different content types, their own editors with their own permissions, and their own billing. A codebase per client means every fix has to be applied everywhere.
Approach
One centralised backend where content structure is data rather than code. A client defines a collection with its own fields from the dashboard and starts storing rows immediately, with no migration and no deploy. Each site is a tenant with its own users, per-resource permission grants, trilingual content, and an independent subscription with invoicing and gateway payment.
Outcome
A new client site onboards without touching the codebase. One deployment serves all of them, so a fix ships once instead of per site.
How it's built
Schema as data: collections declare their fields, items store shapes against them. Three roles plus five per-resource grant lists, so permissions are per-collection rather than global. Full subscription lifecycle with invoice generation and gateway integration.
Dynamic collections over a fixed schema per client
The product premise is that clients define their own content types. Storing field definitions as data is what allows onboarding without a deploy.
Content fields cannot be indexed because names are not known ahead of time, and validation against declared types has to be rebuilt at the application layer rather than inherited from the database.
Compensating rollback around payment initialisation
Subscription and invoice are created before the gateway call, so a gateway failure has to unwind both rather than leaving an orphaned pending subscription.
Two writes to undo instead of one transaction, the cost of an external system that has no concept of your transaction.
Explicit timeout on the gateway call
A payment gateway that stops responding must fail fast rather than hold a request open, because the retry path is safe and the hung path is not.
A slow but successful response can be abandoned, which webhook reconciliation resolves.
Adjacent systems
Multi-tenant Restaurant Platform
A complete restaurant operating system on one multi-tenant backend: customer ordering, driver dispatch, owner dashboard and point of sale.
Vehicle Rental Platform
Rent a scooter or e-bike from an app: scan the QR, the physical lock opens over cellular, ride, park in a permitted zone, pay by the minute from a prepaid wallet.
Freelance Marketplace with Escrow
Two-sided marketplace for architecture and design work: the platform holds the money until delivery is confirmed, with bidding happening in real-time chat.