Skip to main content

Tenant Schema

Purpose

Tenant domain tables model academy operations inside a single tenant. This ERD shows the product relationships that most often matter when changing backend modules, worker callbacks, or frontend data assumptions.

Source Paths

PathRole
lumie-backend/app/src/main/resources/db/migration/public/V18__rls_baseline.sqlBaseline tenant tables and foreign keys
lumie-backend/app/src/main/resources/db/migration/public/V25__drop_omr_grading_jobs_results.sqlRemoves the dead omr_grading_jobs.results column
lumie-backend/app/src/main/resources/db/migration/public/V26__rename_admin_tables_to_staff.sqlAdmin-to-staff terminology migration
lumie-backend/app/src/main/resources/db/migration/public/V40__omr_grading_jobs_add_version.sqlAdds the missing optimistic-lock version column to omr_grading_jobs
lumie-backend/app/src/main/resources/db/migration/public/V41__exam_results_add_omr_grading_job_id.sqlLinks exam_results rows back to the producing OMR job
lumie-backend/app/src/main/resources/db/migration/public/V54__create_file_links.sqlTenant-safe file link model
lumie-backend/app/src/main/resources/db/migration/public/V55__create_announcement_class_targets.sqlAnnouncement-to-class targeting
lumie-backend/app/src/main/resources/db/migration/public/V57__create_lecture_class_targets.sqlLecture-to-class targeting
lumie-backend/app/src/main/resources/db/migration/public/V62__add_read_receipt_tables.sqlRead receipt tables
lumie-backend/app/src/main/resources/db/migration/public/V65__repair_read_receipt_and_file_download_rls.sqlRLS repair migration
lumie-backend/modules/exam/src/main/java/com/lumie/exam/domain/entity/OmrGradingJob.javaCurrent JPA mapping for omr_grading_jobs
lumie-backend/modules/exam/src/main/java/com/lumie/exam/domain/entity/ReportGenerationJob.javaCurrent JPA mapping for report_generation_jobs
lumie-backend/libs/common/src/main/java/com/lumie/common/domain/TenantScopedEntity.javaInherited tenant_id, created_at, and updated_at contract

Core Tenant ERD

Exam And Worker ERD

tenant_id is inherited from TenantScopedEntity; tenant_slug is stored explicitly on both job rows for downstream correlation. The current schema does not contain a request_id column on either job table, so the ERD stays aligned with the real fields used by the backend.

Worker services do not own these product tables. The backend creates job rows, publishes work messages, and records callbacks or result state through backend-owned services so tenant context and exam ownership remain centralized.

Content And File ERD

file_links and file_download are tenant-safe attachment tables. When a relation can cross module boundaries, the migration must preserve the tenant_id guard and document whether the relation is hard FK or soft reference.

Verification

cd /path/to/Lumie
rg -n "CREATE TABLE omr_grading_jobs|CREATE TABLE report_generation_jobs|DROP COLUMN IF EXISTS results|ADD COLUMN version" \
lumie-backend/app/src/main/resources/db/migration/public/V18__rls_baseline.sql \
lumie-backend/app/src/main/resources/db/migration/public/V25__drop_omr_grading_jobs_results.sql \
lumie-backend/app/src/main/resources/db/migration/public/V40__omr_grading_jobs_add_version.sql

Expected success signal: the baseline create statements appear, results is dropped in V25, and only omr_grading_jobs receives a later version column.

cd /path/to/Lumie
rg -n "class OmrGradingJob|class ReportGenerationJob|tenantSlug|zipFileKey|savedCount|studentIds" \
lumie-backend/modules/exam/src/main/java/com/lumie/exam/domain/entity

Expected success signal: OmrGradingJob exposes savedCount and imageKeys, while ReportGenerationJob exposes studentIds and zipFileKey.

Review Checklist

  1. Does every table in the relation carry the same tenant boundary?
  2. Does the migration keep tenant_id in join tables?
  3. Does a unique constraint need tenant_id to avoid cross-tenant collisions?
  4. Is a soft reference more appropriate than a hard FK across module ownership?
  5. Do worker callbacks go through backend-owned tenant-aware APIs?