Public Schema
Purpose
The public schema mixes three kinds of tables:
- platform-owned control-plane tables such as
tenantsandtenant_settings - tenant-scoped product tables such as
users,staff,classes, andexams - operational support tables such as
event_publication,shedlock, andidempotency_keys
This page is a reference document for the boundary between those families. It
keeps the ERD focused on durable ownership and RLS semantics instead of trying
to dump every table in the schema.
Source Paths
| Path | Role |
|---|---|
lumie-backend/app/src/main/resources/db/migration/public/V1__create_platform_tables.sql | tenants and tenant_settings |
lumie-backend/app/src/main/resources/db/migration/public/V18__rls_baseline.sql | Baseline tenant-scoped domain tables and FK relations |
lumie-backend/app/src/main/resources/db/migration/public/V26__rename_admin_tables_to_staff.sql | Renames admins to staff and admin_permissions to staff_permissions |
lumie-backend/app/src/main/resources/db/migration/public/V13__create_event_publication.sql | Spring Modulith event publication table |
lumie-backend/app/src/main/resources/db/migration/public/V14__create_shedlock.sql | Scheduled job lock table |
lumie-backend/app/src/main/resources/db/migration/public/V16__create_idempotency_keys.sql | Idempotency table |
lumie-backend/libs/common/src/main/java/com/lumie/common/domain/TenantScopedEntity.java | JPA base class that supplies tenant-scoped rows with tenant_id |
Boundary ERD
The diagram intentionally does not draw a hard tenants -> tenant table edge.
The baseline migrations rely on tenant_id plus RLS for tenant ownership, not
on a foreign key from every tenant-scoped table back to tenants(id).
Operational Support Tables
event_publication, shedlock, and idempotency_keys live in the same schema
but are not part of the tenant-domain ERD:
event_publicationstores Spring Modulith publication state and does not carry a tenant-domain relationship.shedlockcoordinates scheduled job locks.idempotency_keysstores request replay protection keyed bytenant_slug,endpoint_path, andidempotency_key.
RLS Boundary
The runtime contract is that tenant-scoped access happens only after backend
code establishes app.tenant_id. A missing tenant context should not silently
fall back to cross-tenant data access.
The JPA base class that backs tenant-scoped entities keeps that contract visible in code:
@MappedSuperclass
public abstract class TenantScopedEntity extends BaseEntity {
@Column(name = "tenant_id", nullable = false, updatable = false)
private Long tenantId;
}
Verification
cd /path/to/Lumie
rg -n "CREATE TABLE (admins|users|students|classes|exams)|CREATE TABLE IF NOT EXISTS event_publication|CREATE TABLE IF NOT EXISTS shedlock|CREATE TABLE idempotency_keys" \
lumie-backend/app/src/main/resources/db/migration/public/V18__rls_baseline.sql \
lumie-backend/app/src/main/resources/db/migration/public/V13__create_event_publication.sql \
lumie-backend/app/src/main/resources/db/migration/public/V14__create_shedlock.sql \
lumie-backend/app/src/main/resources/db/migration/public/V16__create_idempotency_keys.sql
Expected success signal: hits for the baseline tenant tables plus separate hits
for event_publication, shedlock, and idempotency_keys.
cd /path/to/Lumie
rg -n "ALTER TABLE admins RENAME TO staff|ALTER TABLE admin_permissions RENAME TO staff_permissions" \
lumie-backend/app/src/main/resources/db/migration/public/V26__rename_admin_tables_to_staff.sql
Expected success signal: both rename operations appear in V26, confirming the
public-schema ERD should use staff and staff_permissions.
Notes
V18__rls_baseline.sqlstill contains the originaladminsandadmin_permissionstable names becauseV26performs the rename later in the migration chain.- Newer join tables such as announcement and lecture targeting still follow the
same boundary: tenant-scoped rows in
public, guarded by RLS.