As a Full Stack Architect, most of my production work at VendAxis sits inside multi-tenant SaaS - shared infrastructure, isolated customer data, and payment flows that can't drop events. This post is a field guide to the patterns I keep reaching for with Next.js, Node.js, PostgreSQL, and Stripe.
Tenancy that stays boring
For most B2B products, a shared PostgreSQL database with a tenantId on every business table is the right default. It's cheaper to operate than one-database-per-customer and scales farther than you'd expect when indexes and query habits are solid.
Rules that prevent late-night incidents:
- Resolve the tenant once per request (subdomain, session, or API key) and never trust a client-supplied tenant id alone
- Scope every Prisma query with
tenantId- treat missing scope as a bug - Keep auth, billing, and tenant metadata in a small core schema; feature data can grow around it
Stripe webhooks as a reliability boundary
Subscriptions are a state machine: trial → active → past_due → canceled. Model that explicitly in your database, then let Stripe webhooks drive transitions.
Production habits that matter:
- Verify signatures on every webhook
- Make handlers idempotent - store event ids and skip duplicates
- Acknowledge quickly; do heavy work asynchronously if needed
- Reconcile periodically - webhooks will eventually miss something
I've shipped Stripe webhook pipelines designed for high availability for that reason: payments are not a place for "best effort" handlers.
TypeScript strict mode as a team contract
Strict TypeScript, PR reviews, and consistent deploy paths (Docker + Coolify in our case) sound process-heavy until you've inherited a loosely typed SaaS. Types catch tenant leaks and billing edge cases before users do. Prefer explicit DTOs at API boundaries over leaking Prisma models into the UI.
Frontend still counts
Multi-tenant backends often get all the attention, but product quality shows up in the UI: Next.js App Router for structure, careful client boundaries for interactivity, and performance work that keeps Lighthouse scores high. Fast APIs with a slow dashboard still feel broken.
Closing
Good SaaS architecture is mostly discipline: clear tenancy, idempotent billing, typed boundaries, and a stack you can operate. React, Next.js, Node.js, and PostgreSQL are enough - if you use them with production constraints in mind.
I'm Masab Qurban - open to roles, freelance, and collaborations. If this overlaps with a product you're building, reach out via the contact page.


