아키텍처
Lumie 백엔드 아키텍처는 하나의 Spring Boot 프로세스 내부에서 코드 수준의 모듈 경계로 정의됩니다. 핵심 설계 결정은 서비스 간 네트워크 분리가 아니라, 모놀리스 내부에서 의존성 방향을 엄격히 지키는 것입니다.
이 페이지는 경계 중심의 overview 문서입니다. 비즈니스 규칙이 어디에
살아 있는지, 모듈이 어떻게 협력해야 하는지, 어떤 공유 코드가 시스템에서
중요한 역할을 맡는지 이해할 때 사용하세요.
소스 경로
| Path | 역할 |
|---|---|
lumie-backend/AGENTS.md | 표준 백엔드 모듈 레이아웃과 multi-tenancy 규칙 |
.codex/knowledge/backend/BACKEND_RULES.md | 백엔드 작업에 적용되는 경로 수준 아키텍처 규칙 |
lumie-backend/app/src/main/java/com/lumie/app/LumieApplication.java | 단일 @SpringBootApplication 엔트리포인트 |
lumie-backend/settings.gradle.kts | 현재 포함된 모듈 목록 |
lumie-backend/libs/common/src/main/java/com/lumie/common/tenant/* | tenant context, request context, RLS binding |
lumie-backend/libs/internal-api/src/main/java/** | 모듈 간에 공개된 프로세스 내부 계약 |
lumie-backend/modules/*/src/main/java/** | 모듈이 소유하는 domain, application, adapter 코드 |
경계 모델
표준 모듈 레이아웃
lumie-backend/AGENTS.md와 BACKEND_RULES.md는 표준 형태를 다음과 같이
정의합니다.
modules/{module}/src/main/java/com/lumie/{package}/
├── domain/{entity,vo,exception}/
├── application/{service,port/out,dto/{request,response}}/
└── adapter/{in/web,in/messaging,in/internal,out/persistence,out/external}
현재 코드베이스에서 각 계층의 의미는 다음과 같습니다.
domain: persistence-backed aggregate, value object, 모듈별 error code를 담습니다. 이 모놀리스에서 aggregate에 JPA annotation을 두는 것은 의도된 설계입니다.application/service: use case orchestration, transaction boundary, 여러 port 간 coordination을 담당합니다.application/port/out: 모듈이 소유하는 outbound dependency를 정의합니다.adapter/in/*: inbound transport 또는 integration entrypoint입니다.adapter/out/*: persistence, storage, queue, cache, external-service 구현입니다.
의도적으로 없는 것:
application/port/in/*UseCase계층은 없습니다. 컨트롤러는 application service를 직접 주입받습니다.infrastructure/패키지는 없습니다.- 다른 모듈의
domain/entity타입을 직접 import하지 않습니다.
공통 라이브러리와 그 경계
| Library | 모듈이 사용할 수 있는 용도 | 사용하면 안 되는 용도 |
|---|---|---|
libs/common | tenant context, user context, base entity, exception, idempotency, logging, auth helper, pagination utility | 제품 도메인 계약을 공개하는 용도 |
libs/internal-api | 동기식 프로세스 내부 service interface와 모듈 간 event record | persistence adapter나 JPA entity 공유 |
libs/messaging | AMQP 기반 흐름에 쓰이는 queue, exchange, routing-key 상수 | queue topology나 비즈니스 orchestration 선언 |
허용되는 협업 패턴
동기식 모듈 간 호출
libs/internal-api 인터페이스와, 해당 모듈이 소유하는
adapter/in/internal/*Adapter 구현을 사용합니다.
현재 코드의 실제 예시:
modules/homepage/adapter/out/internal/TenantLookupAdapter는com.lumie.tenant.api.TenantService에 의존합니다modules/staff/application/service/StaffCommandService는AuthService,BillingService,ClassService,ContentService에 의존합니다modules/exam/adapter/in/event/StudentRegisteredListener는ExamService에 의존합니다
비동기 모듈 간 후속 처리
public.event_publication에 저장되는 Spring Modulith event를 사용하고,
이후 @ApplicationModuleListener가 이를 소비합니다.
현재 예시:
TenantCreatedEvent-> billing trial provisioningOwnerRegisteredEvent-> owner staff bootstrapStudentRegisteredEvent-> exam-result backfill