본문으로 건너뛰기

테넌트 스키마

목적

tenant 도메인 테이블은 하나의 tenant 안에서 academy 운영을 모델링합니다. 이 ERD는 백엔드 모듈, worker callback, 프론트엔드 데이터 가정을 변경할 때 가장 자주 중요한 제품 관계를 보여줍니다.

소스 경로

경로역할
lumie-backend/app/src/main/resources/db/migration/public/V18__rls_baseline.sqlbaseline tenant 테이블과 foreign key
lumie-backend/app/src/main/resources/db/migration/public/V25__drop_omr_grading_jobs_results.sql더 이상 쓰지 않는 omr_grading_jobs.results 컬럼 제거
lumie-backend/app/src/main/resources/db/migration/public/V26__rename_admin_tables_to_staff.sqladmin-to-staff 용어 migration
lumie-backend/app/src/main/resources/db/migration/public/V40__omr_grading_jobs_add_version.sqlomr_grading_jobs에 누락된 optimistic-lock version 컬럼 추가
lumie-backend/app/src/main/resources/db/migration/public/V41__exam_results_add_omr_grading_job_id.sqlexam_results를 생성한 OMR job과 연결
lumie-backend/app/src/main/resources/db/migration/public/V54__create_file_links.sqltenant-safe file link 모델
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 테이블
lumie-backend/app/src/main/resources/db/migration/public/V65__repair_read_receipt_and_file_download_rls.sqlRLS 수리 migration
lumie-backend/modules/exam/src/main/java/com/lumie/exam/domain/entity/OmrGradingJob.javaomr_grading_jobs의 현재 JPA 매핑
lumie-backend/modules/exam/src/main/java/com/lumie/exam/domain/entity/ReportGenerationJob.javareport_generation_jobs의 현재 JPA 매핑
lumie-backend/libs/common/src/main/java/com/lumie/common/domain/TenantScopedEntity.java상속되는 tenant_id, created_at, updated_at 계약

핵심 테넌트 ERD

시험 및 워커 ERD

tenant_idTenantScopedEntity에서 상속되며, tenant_slug는 downstream 상관관계를 위해 두 job 행에 명시적으로 저장됩니다. 현재 스키마에는 어느 job 테이블에도 request_id 컬럼이 없으므로, 이 ERD는 백엔드가 실제로 사용하는 필드와 정렬된 상태를 유지합니다.

worker 서비스는 이 제품 테이블을 소유하지 않습니다. 백엔드가 job 행을 만들고, 작업 메시지를 발행하며, tenant 컨텍스트와 exam 소유권이 중앙에 남도록 콜백과 결과 상태를 백엔드 소유 서비스로 기록합니다.

콘텐츠 및 파일 ERD

file_linksfile_download는 tenant-safe 첨부 테이블입니다. 관계가 모듈 경계를 넘을 수 있을 때는 migration이 tenant_id 보호를 유지하고, 해당 관계가 hard FK인지 soft reference인지 문서화해야 합니다.

검증

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

예상 성공 신호: baseline create 문이 보이고, resultsV25에서 제거되며, 뒤늦게 version 컬럼이 추가되는 것은 omr_grading_jobs뿐입니다.

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

예상 성공 신호: OmrGradingJob에는 savedCountimageKeys가, ReportGenerationJob에는 studentIdszipFileKey가 노출됩니다.

리뷰 체크리스트

  1. 관계의 모든 테이블이 같은 tenant 경계를 공유하는가?
  2. migration이 join 테이블에 tenant_id를 유지하는가?
  3. cross-tenant 충돌을 피하려면 unique constraint에 tenant_id가 필요한가?
  4. 모듈 소유권을 가로지르는 hard FK보다 soft reference가 더 적절한가?
  5. worker callback이 백엔드 소유 tenant 인지 API를 거치는가?