테넌트 스키마
목적
tenant 도메인 테이블은 하나의 tenant 안에서 academy 운영을 모델링합니다. 이 ERD는 백엔드 모듈, worker callback, 프론트엔드 데이터 가정을 변경할 때 가장 자주 중요한 제품 관계를 보여줍니다.
소스 경로
| 경로 | 역할 |
|---|---|
lumie-backend/app/src/main/resources/db/migration/public/V18__rls_baseline.sql | baseline 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.sql | admin-to-staff 용어 migration |
lumie-backend/app/src/main/resources/db/migration/public/V40__omr_grading_jobs_add_version.sql | omr_grading_jobs에 누락된 optimistic-lock version 컬럼 추가 |
lumie-backend/app/src/main/resources/db/migration/public/V41__exam_results_add_omr_grading_job_id.sql | exam_results를 생성한 OMR job과 연결 |
lumie-backend/app/src/main/resources/db/migration/public/V54__create_file_links.sql | tenant-safe file link 모델 |
lumie-backend/app/src/main/resources/db/migration/public/V55__create_announcement_class_targets.sql | announcement-to-class targeting |
lumie-backend/app/src/main/resources/db/migration/public/V57__create_lecture_class_targets.sql | lecture-to-class targeting |
lumie-backend/app/src/main/resources/db/migration/public/V62__add_read_receipt_tables.sql | read receipt 테이블 |
lumie-backend/app/src/main/resources/db/migration/public/V65__repair_read_receipt_and_file_download_rls.sql | RLS 수리 migration |
lumie-backend/modules/exam/src/main/java/com/lumie/exam/domain/entity/OmrGradingJob.java | omr_grading_jobs의 현재 JPA 매핑 |
lumie-backend/modules/exam/src/main/java/com/lumie/exam/domain/entity/ReportGenerationJob.java | report_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_id는 TenantScopedEntity에서 상속되며, tenant_slug는 downstream 상관관계를 위해 두 job 행에 명시적으로 저장됩니다. 현재 스키마에는 어느 job 테이블에도 request_id 컬럼이 없으므로, 이 ERD는 백엔드가 실제로 사용하는 필드와 정렬된 상태를 유지합니다.
worker 서비스는 이 제품 테이블을 소유하지 않습니다. 백엔드가 job 행을 만들고, 작업 메시지를 발행하며, tenant 컨텍스트와 exam 소유권이 중앙에 남도록 콜백과 결과 상태를 백엔드 소유 서비스로 기록합니다.
콘텐츠 및 파일 ERD
file_links와 file_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 문이 보이고, results는 V25에서 제거되며, 뒤늦게 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에는 savedCount와 imageKeys가, ReportGenerationJob에는 studentIds와 zipFileKey가 노출됩니다.
리뷰 체크리스트
- 관계의 모든 테이블이 같은 tenant 경계를 공유하는가?
- migration이 join 테이블에
tenant_id를 유지하는가? - cross-tenant 충돌을 피하려면 unique constraint에
tenant_id가 필요한가? - 모듈 소유권을 가로지르는 hard FK보다 soft reference가 더 적절한가?
- worker callback이 백엔드 소유 tenant 인지 API를 거치는가?