Institutes¶
Institutes are the top-level organizational unit. Each institute has its own PostgreSQL schema, EMS environments, faculties, identity providers, and exam data.
Creating an Institute¶
Institutes are created via the add_tenant management command, which provisions the schema, routing, and data in one step:
python manage.py add_tenant <slug> "<Name>"
This creates:
- A PostgreSQL schema (<slug_sanitized>)
- A subfolder route (/<slug>/...)
- An Institute record inside the tenant schema
- A Keycloak IdentityProvider
Institute Settings¶
From the admin at /<institute>/admin/institutions/institute/, you can edit:
- Name: Human-readable name
- Timezone: IANA timezone (default: Europe/Amsterdam)
- Default Identity Provider: The OIDC provider used when students log in without specifying one
- Institute ID: Read-only — set at creation, cannot be changed
Faculties¶
Faculties subdivide an institute for teacher filtering. Each faculty has: - Code: Short identifier matching the OIDC claim (e.g., "CS", "MATH") - Name: Human-readable name (e.g., "Computer Science")
Faculties are unique per institute (same code can exist in different institutes, each in its own schema).
Data Isolation¶
All data is scoped to the institute's tenant schema: - Exams, sessions, SEB configurations, LLM configs, manuals, users - The URL path prefix determines which tenant's data is served - There is no institute switcher — the tenant is determined by the URL