개발
이 페이지는 백엔드 중심의 how-to 레퍼런스입니다. 프로젝트가 어떻게
구성되어 있는지, 어떤 Gradle task가 의미 있는지, 그리고 현재
모듈러 모놀리스 런타임에서 무엇이 “일반적인” 검증인지 다룹니다.
소스 경로
| Path | 역할 |
|---|---|
lumie-backend/AGENTS.md | 백엔드 리포지토리 규칙과 명령 |
lumie-backend/build.gradle.kts | 공통 Java, test, Spotless, Error Prone, JaCoCo, integration-test 설정 |
lumie-backend/app/build.gradle.kts | 런타임 의존성과 snapshotOpenApi task |
lumie-backend/settings.gradle.kts | 현재 모듈 목록 |
lumie-backend/app/src/main/resources/application*.yml | 런타임 및 profile별 설정 |
프로젝트 레이아웃
| Path | 목적 |
|---|---|
app/ | Spring Boot 엔트리포인트와 공통 런타임 설정 |
libs/common | tenant context, base entity, exception, idempotency, logging, auth helper |
libs/internal-api | 모듈 간 interface와 event |
libs/messaging | 공통 AMQP 상수 |
modules/* | 모놀리스에 로드되는 제품 모듈 |
모듈 코드는 일반적으로 Architecture에 문서화된 경계 형태를 따릅니다.
일반적인 로컬 워크플로
백엔드는 bootRun으로 실행할 수 있지만, 팀에서 보통 사용하는 워크플로는
다음과 같습니다.
- Tilt를 통해 공용 dev 환경을 실행합니다
- frontend는 HMR과 함께 로컬에 유지합니다
- backend, worker, PostgreSQL, RabbitMQ, Redis, MinIO는 클러스터 기반 환경을 사용합니다
이는 루트 AGENTS.md의 안내와도 일치합니다. 즉, frontend는 로컬,
backend와 stateful service는 dev cluster에서 실행합니다.
필요한 의존성이 이미 준비되어 있고 의도적으로 로컬 JVM을 띄우고 싶을 때는
bootRun을 사용하세요.
자주 쓰는 명령어
cd /Users/bluemayne/Projects/Lumie/lumie-backend
| Command | 용도 | 참고 |
|---|---|---|
./gradlew build | 전체 컴파일과 기본 검증 | check를 포함하며, spotlessCheck와 license check에 의존합니다 |
./gradlew test | 빠른 기본 테스트 실행 | @Tag("integration") 테스트는 제외합니다 |
./gradlew integrationTest | TestContainers 기반 integration test | Docker 접근이 필요합니다 |
./gradlew -Pintegration test | 기본 테스트와 integration test를 한 번에 실행 | 느리지만 대규모 백엔드 머지 전에 유용합니다 |
./gradlew :modules:student:test | 모듈 범위 검증 | 변경한 모듈 이름으로 student를 바꾸세요 |
./gradlew :app:test | 공통 런타임 wiring과 OpenAPI snapshot test | security, RLS, data source, migration 작업에 유용합니다 |
./gradlew bootRun | 백엔드를 로컬에서 시작 | PostgreSQL, RabbitMQ, Redis, MinIO가 도달 가능해야 합니다 |
./gradlew snapshotOpenApi | 실행 중인 /v3/api-docs를 lumie-frontend/openapi.json으로 가져오기 | kubectl exec를 통해 실행 중인 dev backend pod에서 읽습니다 |
빌드가 실제로 강제하는 것
build.gradle.kts와 app/build.gradle.kts 기준:
- Java toolchain: 21
- 기본
test는@Tag("integration")을 제외 integrationTest는@Tag("integration")만 포함spotlessCheck는check의 일부- Error Prone은 빌드를 실패시키지 않는 warning mode로 실행
- JaCoCo report는 테스트 후 생성되지만, coverage verification은 아직
check에 연결되어 있지 않음 - license compliance는 루트
check의 일부
따라야 할 백엔드 전용 규칙
- 동기식 모듈 간 접근에는
libs/internal-api를 사용하세요. - 커밋 후 모듈 간 후속 처리는 Spring Modulith event를 발행하세요.
- 외부 HTTP 호출은 긴
@Transactional경계 밖에 두세요. - DTO에는 record를 사용하고 query service에는
@Transactional(readOnly = true)를 사용하세요. - tenant-safe read/write가 동작하려면 context에 tenant ID가 있어야 하고, RLS가 바인딩될 실제 트랜잭션도 필요하다는 점을 기억하세요.
OpenAPI 계약 워크플로
백엔드는 다음 경로를 노출합니다.
/v3/api-docs/swagger-ui.html
./gradlew snapshotOpenApi는 frontend로 계약을 전달하는 문서화된 절차입니다.
이 task는:
kubectl exec로 실행 중인 backend pod에 접근하고http://localhost:8080/v3/api-docs를 다운로드한 뒤- 결과를
../lumie-frontend/openapi.json에 씁니다
이 파일이 frontend codegen의 source of truth입니다.
변경 유형별 검증 플레이북
| If you changed... | 최소한 유용한 검증 |
|---|---|
| controller, security, filter | ./gradlew :app:test와 영향받은 모듈 test task |
| RLS, migration, data source | ./gradlew integrationTest |
| 한 모듈의 application 또는 domain logic | ./gradlew :modules:<name>:test |
| queue, outbox, worker integration code | ./gradlew :modules:exam:test와 보통 ./gradlew :app:test |
libs/common의 shared library code | ./gradlew :libs:common:test |
일반적인 개발 제약 사항
- TestContainers 기반 integration test에는 Docker 접근이 필요합니다.
그래서 기본
test에서는 의도적으로 제외됩니다. snapshotOpenApi는 실행 중인 backend pod와 정상 동작하는kubectlcontext를 전제로 하며, 백엔드를 직접 부팅해 주지 않습니다.bootRun은 사용할 수 있지만, 기본 dev topology는 여전히 클러스터 기반입니다. 여러 백엔드 경로가 실제 인프라 서비스에 기대기 때문입니다.