본문으로 건너뛰기

개요

Lumie 백엔드는 Spring Boot 3 + Java 21 기반의 모듈러 모놀리스입니다. 단일 app 모듈이 19개의 도메인 모듈과 3개의 공유 라이브러리를 하나의 JAR로 통합하여 배포합니다. 각 모듈은 헥사고날 아키텍처를 따르며, PostgreSQL RLS 기반 멀티테넌시와 RabbitMQ 비동기 메시징을 사용합니다. AI 챗봇 기능은 Spring AI 제거(2026-05-26) 이후 lumie-worker(Python/LangGraph)에서 운영됩니다.

기술 스택

분류기술버전
런타임Java21
프레임워크Spring Boot3.4.13
빌드Gradle (Kotlin DSL)8.12
DBPostgreSQL + Flyway + HikariCP-
커넥션 풀CNPG PgBouncer Pooler-
메시징RabbitMQ (Spring AMQP)-
인증Spring Security + JWT (jjwt)-
캐시Redis Sentinel-
스토리지MinIO SDK-
코드 생성Lombok / MapStruct1.18.36 / -
이벤트Spring Modulith (JDBC 아웃박스)-
분산 락ShedLock (JDBC)-
API 문서springdoc-openapi-
관측성Micrometer + Prometheus-
로깅Logstash Logback Encoder (구조화 로그)-

프로젝트 구조

lumie-backend/
├── app/ # 단일 Spring Boot 엔트리포인트
│ ├── build.gradle.kts # 모든 모듈 의존, bootJar 생성
│ └── src/main/
│ ├── java/com/lumie/app/
│ │ ├── LumieApplication.java
│ │ └── config/ # SecurityConfig, OpenApiConfig, CorsConfig, ...
│ └── resources/
│ ├── application.yaml # 통합 설정
│ └── db/migration/ # Flyway 마이그레이션 (public/ + tenant 공통)

├── libs/ # 공유 라이브러리
│ ├── common/ # 멀티테넌시, 예외, 베이스 엔티티, Role enum
│ ├── internal-api/ # 모듈 간 직접 주입 인터페이스 (XxxService)
│ └── messaging/ # RabbitMQ 상수

└── modules/ # 도메인 모듈 (각 Gradle 서브프로젝트)
├── tenant/ # 테넌트 관리, 프로비저닝
├── auth/ # 인증, JWT, OAuth2
├── billing/ # 구독, 요금제, 할당량
├── homepage/ # 공개 랜딩 페이지 라우팅
├── student/ # 학생 프로필
├── staff/ # 직원(강사/관리자), 권한(RBAC)
├── exam/ # 시험, OMR 채점
├── content/ # 공지사항, 학습 자료
├── class/ # 반 편성
├── assignment/ # 과제
├── lecture/ # 수업 일지
├── attendance/ # 출결
├── ai/ # 챗봇 프록시 (chatbot-svc 연동)
├── notification/ # SMS 알림
├── file/ # 파일 업로드 (MinIO)
└── tuition/ # 수강료 청구

settings.gradle.kts

include(
"app",
"libs:common",
"libs:internal-api",
"libs:messaging",
"modules:tenant",
"modules:auth",
"modules:billing",
"modules:homepage",
"modules:student",
"modules:attendance",
"modules:staff",
"modules:exam",
"modules:content",
"modules:class",
"modules:assignment",
"modules:lecture",
"modules:ai",
"modules:notification",
"modules:file",
"modules:tuition"
)

공유 라이브러리

libs/common

모든 모듈이 공유하는 멀티테넌시 인프라, 예외 처리, 베이스 엔티티, Role enum을 제공합니다.

  • TenantContextHolder — ThreadLocal 기반 테넌트 컨텍스트 (slug, tenantId). withinContext(slug, tenantId, action) 으로 어댑터에서 안전하게 테넌트 전환
  • UserContextHolder — ThreadLocal 기반 사용자 컨텍스트 (userId, role 등)
  • RoleOWNER(0) > MANAGER(1) > INSTRUCTOR(2) > STUDENT(3) 계층 열거형. hasAuthority(Role) / canManage(Role) 제공
  • BaseEntity — 공통 JPA 엔티티 (createdAt, updatedAt, JPA Auditing)
  • TenantScopedEntity — RLS 대상 엔티티 기반 클래스 (@PrePersist 로 tenant_id 자동 설정)
  • BusinessException — 비즈니스 예외 기반 클래스. 모든 모듈 예외는 이를 상속
  • GlobalExceptionHandler — @RestControllerAdvice 전역 예외 처리기

libs/internal-api

모듈 간 직접 빈 주입(in-process 메서드 호출)을 위한 Java 인터페이스와 내부 DTO(record)를 정의합니다. 구현체(XxxServiceAdapter)는 각 모듈의 adapter/in/internal/ 에 있습니다.

인터페이스패키지제공 모듈
TenantServicecom.lumie.tenant.apitenant
AuthServicecom.lumie.auth.apiauth
BillingServicecom.lumie.billing.apibilling
StudentServicecom.lumie.student.apistudent
StaffServicecom.lumie.staff.apistaff
ClassServicecom.lumie.classroom.apiclass
LectureServicecom.lumie.lecture.apilecture
ExamServicecom.lumie.exam.apiexam
ContentServicecom.lumie.content.apicontent
FileServicecom.lumie.file.apifile
AssignmentServicecom.lumie.assignment.apiassignment

libs/messaging

RabbitMQ Exchange, Queue, Routing Key 상수를 정의합니다. OMR 채점 비동기 워크플로우에서 사용합니다.


빌드 및 실행

# 전체 빌드 (단일 JAR)
./gradlew :app:bootJar

# 테스트 실행
./gradlew test

# 통합 테스트 (@Tag("integration"), TestContainers)
./gradlew :app:integrationTest

# 로컬 실행
./gradlew :app:bootRun --args='--spring.profiles.active=dev'

# Docker 이미지 빌드
docker build -t lumie-backend:latest .

빌드 산출물: app/build/libs/lumie-backend.jar


배포

  • 클러스터: K3s (1 master + 4 workers)
  • 네임스페이스: lumie-backend
  • Replica: 3
  • Ingress: Traefik (StripPrefix 미들웨어로 /api/*/* 변환)
  • CI/CD: Tekton → Kaniko 빌드 → ArgoCD GitOps
  • 시크릿: Vault + VaultStaticSecret

자세한 내용은 인프라 문서를 참고하세요.