ClassHaven
Multi-tenant school management SaaS — one codebase, many verticals.
Overview
Multi-tenant, multi-vertical school management SaaS. One codebase serves music schools, martial-arts dojos, dance studios, preschools and faith schools — each with its own public site, its own portals, and its data isolated from every other school by the database itself.
The problem
Music schools, dojos, dance studios, preschools and faith schools all need the same core — roster, scheduling, attendance, billing, family communication — but each wants its own language and its own public face. One deployment per school does not scale. One shared database, guarded only by application checks, means a single missed WHERE clause shows one school another school's families.
The approach
One config-first codebase, with tenant isolation pushed down into Postgres rather than left to the application. All 69 tables holding school or family data carry ENABLE and FORCE ROW LEVEL SECURITY with a RESTRICTIVE policy that no permissive rule can widen, and every access flows through a single withTenant() chokepoint that stamps the tenant on each statement. The tradeoff is deliberate: a query that skips the chokepoint sees no tenant context and returns zero rows rather than everything, so the failure mode is an empty screen rather than a leak.
Outcome
- Shipped and running in production — five verticals served from one codebase, each on its own domain
- Isolation is enforced by the database, not by convention: a schema lint fails the build when a new table is added without that decision
- A DB-backed leak suite runs as a merge gate, connecting as the unprivileged runtime role, so the policies are exercised rather than merely present
- Mandatory TOTP for every staff role — no per-role exemption, no configuration switch, no recovery codes
- Support impersonation is read-only at the transaction level and expires in 20 minutes; message bodies are stripped in the data layer, so a support session sees that a thread exists and never what it says
What it does
A public site per school
Themed and config-driven, served on the school's own subdomain or custom domain, with an enrolment funnel and lead capture.
Staff portal
Roster, classes and sessions, attendance with a tap-to-check-in kiosk, scheduling and private lessons, ranks and grading, exams and certificates, equipment loans, invoicing, broadcasts and 1:1 family messaging.
Family portal
A parent sees their own children and nothing else: schedule, progress, practice logs, assignments, billing, and one thread with the school.
Two tenant paths that never mix
The public site resolves its tenant from the verified request host; the portals resolve it from the signed-in session's membership, never from a header a caller can set.
Append-only audit log
Enforced by database grants and a trigger rather than by discipline, so history cannot be quietly edited.
Platform console
Tenant provisioning, entitlements, audited read-only impersonation for support, and lead triage.
Ask about ClassHaven
Want something like this, or curious how a piece of it works? Send a note — it reaches me tagged with this project, so I have the context before I reply.