모듈 레퍼런스
Lumie 백엔드를 구성하는 22개 모듈(libs 3 + modules 19)의 책임과 주요 컴포넌트를 정리합니다.
공유 라이브러리 (libs/)
libs/common
모든 모듈이 공통으로 사용하는 컨텍스트 홀더, 예외 처리, 베이스 엔티티, Role 열거형을 제공합니다.
주요 컴포넌트
| 컴포넌트 | 설명 |
|---|---|
TenantContextHolder | ThreadLocal 기반 테넌트 슬러그·ID 저장소. withinContext(slug, tenantId, action) 으로 어댑터에서 안전하게 전환 |
UserContextHolder | ThreadLocal 기반 사용자 ID·역할 저장소 |
Role | OWNER(0) > MANAGER(1) > INSTRUCTOR(2) > STUDENT(3) 계층 열거형 |
BaseEntity | createdAt, updatedAt 공통 필드 및 JPA Auditing |
TenantScopedEntity | RLS 대상 엔티티 기반 클래스 — @PrePersist로 tenant_id 자동 설정 |
ApiResponse<T> | 표준 API 응답 래퍼 |
BusinessException | 비즈니스 예외 최상위 클래스 |
ErrorCode | 에러 코드 인터페이스 |
GlobalExceptionHandler | @RestControllerAdvice 전역 예외 처리기 |
// Role.java — 계층 권한 확인
public enum Role {
OWNER(0), MANAGER(1), INSTRUCTOR(2), STUDENT(3);
public boolean hasAuthority(Role required) {
return this.level <= required.level; // OWNER는 모든 역할에 권한 있음
}
public boolean canManage(Role target) {
return this.level < target.level; // 동급 관리 불가
}
}
libs/internal-api
모듈 간 직접 빈 주입(in-process)을 위한 인터페이스와 내부 DTO(record)를 정의합니다. 구현체(XxxServiceAdapter)는 각 모듈의 adapter/in/internal/ 에 있습니다. 소비자는 adapter/out/internal/ 에서 인터페이스를 주입 받습니다.
libs/internal-api/src/main/java/com/lumie/
├── auth/api/AuthService.java
├── tenant/api/TenantService.java
├── billing/api/BillingService.java
├── student/api/StudentService.java
├── staff/api/StaffService.java
├── classroom/api/ClassService.java
├── lecture/api/LectureService.java
├── exam/api/ExamService.java
├── content/api/ContentService.java
├── file/api/FileService.java
├── assignment/api/AssignmentService.java
└── activitylog/api/ActivityLogService.java
자세한 내용은 아키텍처 — 모듈 간 통신을 참고하세요.
libs/messaging
RabbitMQ Exchange, Queue, Routing Key 상수와 공통 메시지 DTO를 정의합니다. OMR 배치 채점 워크플로우에서 사용합니다.
// RabbitMqConstants.java
public final class RabbitMqConstants {
public static final String LUMIE_COMMANDS_EXCHANGE = "lumie.commands";
public static final String LUMIE_DLX_EXCHANGE = "lumie.dlx";
public static final String GRADING_OMR_REQUEST_QUEUE = "grading.omr-request";
public static final String GRADING_OMR_REQUEST_DLQ = "grading.omr-request.dlq";
public static final String GRADING_OMR_COMPLETED_QUEUE = "grading.omr-completed";
}
도메인 모듈 (modules/)
modules/tenant
책임: 테넌트(학원/기관) 등록, 상태 관리, 커스텀 도메인 라우팅
주요 컴포넌트
| 컴포넌트 | 설명 |
|---|---|
TenantProvisioningService | 신규 테넌트 가입 시 데이터 초기화 + 프리 구독 생성 |
TenantServiceAdapter | TenantService 구현체 — 타 모듈에 테넌트 정보 제공 |
내부 API (TenantService)
Optional<TenantData> getTenant(Long tenantId);
Optional<TenantData> getTenantBySlug(String slug);
Optional<TenantData> getTenantByCustomId(String customId); // 공개 랜딩 라우 팅
List<TenantData> listActiveTenants();
ValidateTenantResult validateTenant(String slug);
CreateTenantResult createTenant(String instituteName, String businessRegistrationNumber,
String ownerEmail, String ownerName);
modules/auth
책임: JWT 발급·검증, OAuth2 소셜 로그인(Google, Kakao), Redis 기반 토큰 관리
주요 컴포넌트
| 컴포넌트 | 설명 |
|---|---|
JwtAuthenticationFilter | 모든 요청에서 JWT를 추출하고 TenantContextHolder + UserContextHolder + SecurityContext 설정 |
JwtTokenProvider | 액세스·리프레시 토큰 생성, 파싱, 검증 |
AuthRegistrationService | 원장 등록 — tenant 생성 → staff 생성 이벤트 발행 |
AuthServiceAdapter | AuthService 구현체 |
JWT Claims 구조
{
"sub": "28",
"tenant_slug": "inst-c704d223",
"tenant_id": 18,
"role": "OWNER",
"type": "access",
"iss": "lumie-auth-svc",
"iat": 1775313347,
"exp": 1775316947,
"jti": "a022ead2-a80e-4091-82ea-1023b9c51560"
}
자세한 인증 플로우는 인증 & 멀티테넌시를 참고하세요.
modules/billing
책임: 테넌트 구독 플랜 관리, 기능별 사용량 할당량(Quota) 추적
주요 컴포넌트
| 컴포넌트 | 설명 |
|---|---|
SubscriptionService | 구독 플랜 생성, 갱신, 만료 처리 |
QuotaService | MetricType 기반 사용량 확인 및 차감 |
BillingServiceAdapter | BillingService 구현체 |
// exam-svc에서 OMR 할당량 확인 예시
QuotaResult quota = billingService.checkQuota(tenantSlug, MetricType.OMR_MONTHLY_QUOTA);
if (!quota.allowed()) throw new ExamException(ExamErrorCode.QUOTA_EXCEEDED);
modules/student
책임: 학생 프로필, 학부모 연락처 관리
내부 API (StudentService)
Optional<StudentData> getStudent(String tenantSlug, Long studentId);
StudentListData getStudentsByIds(String tenantSlug, List<Long> studentIds);
Optional<StudentData> getStudentByPhone(String tenantSlug, String phone);
StudentListData getStudentsByUserIds(String tenantSlug, List<Long> userIds);
ValidateStudentResult validateStudent(String tenantSlug, Long studentId);
modules/staff
책임: 직원(원장/부원장/강사) 계정, 세분화된 권한(퍼미션) 관리
주요 컴포넌트
| 컴포넌트 | 설명 |
|---|---|
StaffCommandService | 직원 등록, 상태 변경, 권한 부여 |
StaffQueryService | 직원 목록 조회, 단건 조회 |
PermissionQueryService | 직원별 퍼미션 코드 조회 |
StaffServiceAdapter | StaffService 구현체 |
내부 API (StaffService)
Optional<StaffData> getStaff(String tenantSlug, Long staffId);
Optional<StaffData> getStaffByUserId(String tenantSlug, Long userId);
StaffPermissionsData getStaffPermissions(String tenantSlug, Long staffId);
StaffListData getAllStaff(String tenantSlug, int page, int size);
modules/class
책임: 반 편성, 수업 일정, 학생·강사 배정
내부 API (ClassService)
Optional<ClassData> getClass(String tenantSlug, Long classId);
ClassListData getClassesByTeacher(String tenantSlug, Long teacherId, int page, int size);
ClassListData getClassesByStudent(String tenantSlug, Long studentId, int page, int size);
List<Long> getEnrolledStudentIds(String tenantSlug, Long classId);
modules/lecture
책임: 여러 반에 공개할 수 있는 강의 생성·관리
내부 API (LectureService)
Optional<LectureData> getLecture(String tenantSlug, Long lectureId);
LectureListData getLecturesByClass(String tenantSlug, Long classId, int page, int size);
modules/assignment
책임: 과제 출제·관리, 제출 현황 추적
내부 API (AssignmentService)
Optional<AssignmentData> getAssignment(String tenantSlug, Long assignmentId);
AssignmentListData getAssignmentsByClass(String tenantSlug, Long classId, int page, int size);
modules/exam
책임: 시험 생성·관리, OMR 자동 채점, 성적 통계
주요 컴포넌트
| 컴포넌트 | 설명 |
|---|---|
ExamService | 시험 CRUD, 문항 설정, 등급 체계 관리 |
OmrGradingService | 단건 동기 채점 (grading-svc HTTP 호출) |
OmrBatchGradingService | Presigned URL 발급 → RabbitMQ 비동기 배치 채점 |
ExamStatisticsService | 평균, 표준편차, 등급 분포 계산 |
GradingServiceClient | grading-svc HTTP 클라이언트 (adapter/out/external/) |
ReportServiceClient | report-svc HTTP 클라이언트 (adapter/out/external/) |
ExamServiceAdapter | ExamService 구현체 (미등록 학생 결과 백필) |
OMR 배치 채점 흐름
modules/content
책임: 공지사항, 학습 자료(파일 첨부) 등 콘텐츠 관리
내부 API (ContentService)
String createAnnouncement(Long authorId, String title, String content,
boolean isImportant, boolean isAsset);
modules/attendance
책임: 학생 출결 체크인 기록 및 조회
modules/ai
책임: AI 챗봇 프록시 — chatbot-svc(Python/LangGraph)로의 SSE 스트리밍 중계, RLS 범위 내 대화·메시지 영속성, 예약 태스크 관리
Spring AI는 사용하지 않습니다. 2026-05-26 Phase 5에서 모든 Spring AI 코드가 제거되었으며, LLM 오케스트레 이션은 전적으로 chatbot-svc에서 담당합니다.
주요 컴포넌트
| 컴포넌트 | 설명 |
|---|---|
ChatbotClient | chatbot-svc HTTP(SSE) 프록시. adapter/out/external/. 모든 호출에 X-Tenant-Slug 전파, HTTP/1.1 고정 (uvicorn 호환) |
ChatService | 대화·메시지 영속성 (RLS 범위 내). @Transactional 메서드로 RlsTenantContextAspect 경유 |
ConversationController | 대화 목록·메시지 조회 (adapter/in/web/) |
ChatController | 스트리밍·비스트리밍 채팅, confirm 엔드포인트 |
InternalChatbotController | worker가 콜백하는 /internal/chatbot/** 엔드포인트 (HMAC 인증) |
ScheduledTaskExecutor | 반복 예약 태스크 실행 |
modules/notification
책임: SMS 알림 발송, 발송 이력 관리
modules/file
책임: MinIO 기반 파일 업로드·다운로드, Presigned URL 발급
내부 API (FileService)
void deleteFilesByEntity(String entityType, Long entityId);
void deleteFilesByIds(List<UUID> fileIds);
// MinioStorageAdapter 사용 예시
minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(objectKey)
.stream(inputStream, size, -1)
.contentType(contentType)
.build()
);
modules/tuition
책임: 수강료 청구서 생성, 납부 추적, 현금영수증
modules/activity-log
책임: 사용자 행동 감사 로그 기록
내부 API (ActivityLogService)
void log(Long actorId, String actorName, String actorRole,
String action, String entityType, Long entityId,
String entityName, String description);
modules/homepage
책임: 테넌트 공개 랜딩 페이지 라우팅 (/v1/homepage/public/**)
모듈 의존성 맵
관련 문서
- 아키텍처 — 모듈형 모놀리스 구조와 internal-api 통신
- 인증 & 멀티테넌시 — JWT, RLS 기반 멀티테넌시
- 인프라 — 배포 환경, CI/CD
- 개발 가이드 — 새 모듈 추가 방법