What “enterprise-ready” actually means
Turning a consumer product into one an institution can buy is not a feature list. It is a boundary — and almost everything hard about it follows from deciding where that boundary sits.
In short
Enterprise-ready means every row of data is scoped to an organisation, every role is defined relative to that organisation, and every mutation is auditable against it. Single sign-on, seat licensing and admin consoles are consequences of that boundary, not substitutes for it. A consumer product scoped to a single user id cannot be retrofitted with these by adding screens.
What actually changes when you go from consumer to enterprise?
The unit of ownership. Everything else is downstream of that one decision.
In a consumer product every row belongs to a user id. That single assumption is load-bearing in a way that is easy to miss until you try to remove it: queries, permissions, billing, analytics and support tooling all quietly depend on it.
In an institutional product the organisation owns the data and the user is granted access to some of it. That inverts the relationship. A teacher does not own a student's results — the school does, and the teacher is permitted to see them because of a role that exists only inside that school.
This is why 'add a team feature' is not a path to enterprise. You are not adding a layer on top of the user; you are moving the ownership boundary underneath them.
What does the hierarchy need to look like?
Organisation, then optional nestable units, then classes — and the units are the part most teams leave out.
The temptation is to ship organisation and class, and add units later when a bigger customer asks. That later change touches every permission check in the system, because 'can this admin see this class' stops being a single comparison and becomes a tree walk.
- Organisation
- The billing and policy boundary. One school, college or district. Everything is scoped to it and nothing crosses it.
- Org unit
- Campuses and departments, nestable. Optional for a single-site school, essential for a multi-branch college or a district. Retrofitting this later is painful because it changes every access check.
- Class
- A durable, term-scoped roster with lead and co-teachers — not an ephemeral join code. This is the object teachers actually work in.
How should roles work?
Scoped to the organisation, carried in the token, and never global.
A user must be able to be a teacher in one institution and an administrator in another without those roles leaking into each other. That means the role cannot live on the user record. It lives on the membership — the join between a user and an organisation — and the active organisation's role travels in the token.
Six roles covered every real case we encountered: organisation owner, organisation admin, unit admin, teacher, student, and a billing-only admin. The last one surprises people, but finance staff routinely need invoices without any access to student data, and if you cannot give them that cleanly, someone will share an admin login instead.
How do you isolate tenants without rewriting every query?
An organisation id on every table, indexed, enforced in the query layer and again at the database.
- Give every new table an organisation id from the first migration. Adding it later means backfilling and auditing every existing read path.
- Retrofit inherited consumer tables with a nullable organisation id so the same instance can serve both models during a transition.
- Index every one of those columns. Tenant filters appear in effectively every query, so an unindexed column is a site-wide performance problem, not a local one.
- Enforce in two places — the query layer and row-level policies. One is a mistake away from a cross-tenant leak.
- Write an audit log entry from every mutation, including staff actions, scoped to the organisation.
Is single sign-on actually necessary?
Often less than procurement implies — and the reason is worth knowing before you build it.
SSO appears on every enterprise checklist, so the instinct is to build it early. But it is worth asking who will actually authenticate through it. In school deployments, pupils frequently have no email address at all; logins have to be minted synthetically. An identity provider integration built for a population that has no identities with that provider is expensive shelfware.
Our position: build OIDC and SCIM because procurement asks and the storage design is cheap to get right up front, keep them disabled by default, and be honest internally that they may never be switched on. Deliberately skipping SAML unless a customer pays for it is a defensible call, not a gap.
The general lesson is to separate 'needed to answer a procurement questionnaire' from 'needed to operate'. They are different budgets and they deserve different levels of polish.
What should you delete?
Whatever did not survive contact with real institutions — and delete it properly.
When the consumer product became an institutional one, two significant surfaces went: the chat-based AI tutor and the video course module. Neither was failing technically. Schools simply did not use them, and every surface you keep is a surface you maintain, test, secure and explain in a demo.
Deleting is harder than it sounds because half-deleted features are worse than either state. Tables that still exist but nothing reads, feature flags that gate nothing, code paths kept 'just in case' — these accumulate into a codebase nobody can reason about. If a table is dead, say so in writing next to it, so the next person does not spend a day working out whether it matters.
What is the honest sequencing?
Tenancy, roles and rosters first. Consoles and billing after. Identity last, if at all.
- Get the boundary right before building anything on top of it — every later change is more expensive than this one.
- Persistent rosters before clever features. Teachers need the class list to be correct far more than they need anything generated.
- Analytics that need no AI — attendance, timetable, syllabus coverage — deliver value immediately and cost almost nothing.
- Seat licensing and entitlements derived from the plan, rather than a separate licence table you now have to keep in sync.
- Identity integrations when a paying customer asks, not when a checklist does.
Questions this answers
What does multi-tenant mean in a SaaS product?
It means one deployment serves many customer organisations, with each organisation's data isolated from the others. In practice that requires an organisation id on every table, indexed and enforced both in the query layer and by database row-level policies, plus roles that are scoped to an organisation rather than global to a user.
Can you convert a consumer app into an enterprise product?
Only by moving the ownership boundary, not by adding features. In a consumer app every row belongs to a user; in an enterprise product the organisation owns the data and users are granted access through org-scoped roles. That inversion touches permissions, billing, analytics and support tooling, so it is a re-architecture rather than a feature.
Do B2B education platforms need SSO and SCIM?
Procurement almost always asks, but actual usage is often low — school pupils frequently have no email address and are given synthetically generated logins, so there is no identity provider to federate with. Building OIDC and SCIM and leaving them disabled by default is usually the right trade: it answers the questionnaire cheaply without over-investing in a feature that may never be switched on.
Should organisation units be built up front or added later?
Up front. Adding a nestable unit layer later changes every access check in the system, because deciding whether an admin can see a class stops being a single comparison and becomes a tree walk. It is one of the most expensive things to retrofit.