Appearance
Provisioning tenants
Who this is for: Platform operators
What you'll achieve: Create a blank school tenant with an owner login
Every tenant starts blank: no example school data is injected. Seeded defaults include grades, capabilities, duty types, and default notification rules/templates.
Option A: Web operator console
- Configure SSO at Operator → Configuration → SSO, and keep one admin with a password for break-glass. Use
OPERATOR_AUTH_DISABLED=1only locally. - Open
/operator/loginand sign in with SSO or your operator account. Roles come from IdP groups or the Admins tab (platform_admin,support,readonly). - Use the sidebar: Overview, Provision school, Schools & flags, Support access, Audit log, Configuration (items appear based on your role).
- New schools get AI assistant chat on with a daily usage allowance. To turn it off: Schools & flags → select a school → AI & helpers.
- Share
https://{host}/t/{subdomain}/loginand owner credentials.
See Operator SSO and access levels.
Option B: CLI
Create a named token at Operator → Configuration → API tokens, then:
bash
export OPERATOR_TOKEN=your-named-token
pnpm tenant:create -- --subdomain riverside --name "Riverside Primary" --email admin@riverside.test --plan trial --seats 50Option C: Self-serve (Stripe)
Schools sign up at /signup → Stripe Checkout → webhook creates tenant and emails welcome credentials. See Sign up and start your trial and docs/BILLING_AND_HOSTING.md in the repository.
Signup supports single school and trust / MAT (multiple sites) organisation types. Trust signups create one portal with at least two school sites; each site runs its own setup wizard. See docs/MULTI_SITE_AND_ORGS.md.
Feature flags (operator)
Post-pilot and pilot-tier features are controlled per tenant in Schools & flags (/operator/tenants → select a school):
| Flag | Purpose | When off |
|---|---|---|
analytics | Analytics nav and API | Analytics hidden/disabled |
ai_import | Setup copilot, staff import mapping, board polish | Tools hidden |
ai_assistant | Floating AI assistant chat (approve-before-apply). On by default for new schools, with a daily token allowance | Launcher hidden; chat blocked |
sso | Single sign-on buttons and OIDC login | Email/password only |
scim | SCIM token provisioning | SCIM endpoints return 403 |
outlook_calendar | Admin → Outlook calendar integration. On by default for new schools | Integration hidden; no Graph sync |
entra_profile_photos | Admin → Microsoft profile photos. On unless you turn it off | Integration hidden; initials only |
google_calendar | Admin → Google Calendar integration | Integration hidden; no Calendar API sync |
multi_site | Multi-site UX (site switcher, scoped routes) | Single-site behaviour |
sms | SMS notification channel (reserved) | Not used yet |
You can also pass flags when creating a tenant via API:
json
POST /api/operator/tenants
{ "featureFlags": { "outlook_calendar": true, "analytics": true, ... } }Or toggle an existing tenant:
http
PATCH /api/operator/tenants/{tenantId}/flags
{ "outlook_calendar": true, "analytics": false }School admins see disabled features as hidden nav items or an explanatory message - not a hard error.
Support impersonation
Platform operators can open a 1-hour audited session as a school user for troubleshooting. See Support impersonation.
After provisioning
- Sign in
- Complete Initial setup
- Import staff (respects seat limit)
- Run the go-live checklist
Subscription cancel feedback
When a school owner cancels from the billing portal, Stripe collects a reason and optional comment. That survey is stored on the school and shown on Schools & flags → school, under portal status. The support mailbox (and the signup notify address) also get an email. You can still open the subscription in Stripe if you need the raw event.
Plans and seats
- Hard seat limit on active rota people
- Trial:
plan=trial,trialEndsAtdefaults to +30 days for new tenants - Stripe-linked tenants: plan/seats sync via webhooks
