A personal project, open source
TheBlueprintCode
The part of every SaaS that no SaaS is about.
Open-source foundations for SaaS products, released as layers you fork.
Solo build, August to October 2026. MIT licensed.

One PostgreSQL schema per customer
Why I built it: a personal project, not client work
Every SaaS starts with the same months of groundwork. I built it once, properly, and gave it away.
- The problem
- Sign-in, roles, keeping customers' data apart, an admin that doesn't look hand-rolled. None of it is the product. All of it has to be right.
- What I built
- One foundation for any industry: a backend, an admin UI and an AI layer, MIT licensed. No licence key, no dependency on me. Fork it and it is yours.
What a layer had to be
- Forkable, not installableYou own the code. No framework release schedule to inherit.
- Strict from the first bootA missing secret or policy stops it at startup, not in production.
- Running in one commandnpm run setup writes the secrets, migrates and seeds.
One token in, one customer's schema out.
A request arrives with a token.
One foundation. Three layers that already speak to each other.
One token and one tenant boundary through every layer
Backend
Sign-in, roles, customer separation, jobs and email, already working.
- Email, SSO and API keys
- Module-based permissions
- New customer, new schema
- Parallel job lanes
- Branded email templates
- Setup wizard
Any industry. Your brand.
Pick a vertical, name it, theme it. This is the admin a customer forks, working.
Industry
Preset
Font
Mode
Content
Sidebar
Healthcare
Overview
Patients monitored
48
NIBP
122/76
Alerts today
3
Lead II, live
Your records, from one JSON file
bun run generate:form --schema=patient.json{
"entityName": "Patient",
"fields": [
{ "name": "fullName", "type": "string",
"ui": "input", "required": true },
{ "name": "ward", "type": "enum",
"ui": "select",
"options": ["ICU", "Cardiac", "General"] },
{ "name": "admittedOn", "type": "date",
"ui": "date" },
{ "name": "notes", "type": "string",
"ui": "textarea" }
]
}Generated: a Zod schema and a react-hook-form component
The admin UI started from the open-source Studio Admin template (MIT) and was extended from there.
Change the product by editing a file.
Three JSON files decide sessions, roles and permissions. These are the real defaults.
How many devices each kind of user stays signed in on, session expiry and the rate limit.
{
"sessions": {
"maxConcurrent": {
"root": 1,
"tenantWeb": 3,
"tenantMobile": 5
},
"absoluteExpiryDays": 90
},
"rateLimiting": {
"global": { "ttl": 60000, "limit": 100 }
}
}A new customer is a cloned schema.
Sign-up copies the template, registers the account and seeds its first admin.
One identity, two databases, every customer apart.
The backend and AI layers both pick the customer's schema from the verified token, never from the request.
The calls that shaped it.
A schema per customer
over a tenant column
Leakage is structural: other customers' rows are never in scope.
Tenant in the request context
over a tenant argument everywhere
Around thirty service files kept their code unchanged.
Only verified sources
over request headers
A checked signature or a database lookup names the customer. Nothing else can.
Behaviour in JSON
over hardcoded defaults
Roles, sessions and the rate limit change by editing a file.
A queue per lane
over BullMQ's paid groups
Parallel job lanes from the open-source edition.
AI in its own Python service
over AI inside the backend
Heavy AI work can fail without touching core business flows.
Honest limits.
- Early: the backend is at 0.0.1
- Billing and storage are stubs
- No enterprise SSO yet
- Customer roles partly wired
- The AI layer is a scaffold
Built with.
- Backend
- TypeScriptNestJSFastifyDrizzle ORMPostgreSQLRedisBullMQPassportVitest
- Admin UI
- Next.js 16React 19Tailwind CSS v4shadcn/uiZodZustand
- AI
- Python 3.12FastAPIpgvectorPyJWTpytest
- Docs
- Next.js 16FumadocsMDX