본문으로 건너뛰기

개발

이 페이지는 백엔드 중심의 how-to 레퍼런스입니다. 프로젝트가 어떻게 구성되어 있는지, 어떤 Gradle task가 의미 있는지, 그리고 현재 모듈러 모놀리스 런타임에서 무엇이 일반적인 검증인지 다룹니다.

소스 경로

경로역할
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런타임 및 프로필별 설정

프로젝트 레이아웃

경로목적
app/Spring Boot 엔트리포인트와 공통 런타임 설정
libs/common테넌트 컨텍스트, 기본 엔티티, 예외, 멱등성, 로깅, 인증 헬퍼
libs/internal-api모듈 간 인터페이스와 이벤트
libs/messaging공통 AMQP 상수
modules/*모놀리스에 로드되는 제품 모듈

모듈 코드는 일반적으로 아키텍처에 문서화된 경계 형태를 따릅니다.

일반적인 로컬 워크플로

백엔드는 bootRun으로 실행할 수 있지만, 팀에서 보통 사용하는 워크플로는 다음과 같습니다.

  1. Tilt를 통해 공용 dev 환경을 실행합니다.
  2. 프론트엔드는 HMR과 함께 로컬에 둡니다.
  3. 백엔드, 워커, PostgreSQL, RabbitMQ, Redis, MinIO는 클러스터 기반 환경을 사용합니다.

이는 루트 AGENTS.md의 안내와도 일치합니다. 즉, 프론트엔드는 로컬, 백엔드와 상태 저장 서비스는 dev 클러스터에서 실행합니다.

필요한 의존성이 이미 준비되어 있고 의도적으로 로컬 JVM을 띄우고 싶을 때는 bootRun을 사용하세요.

자주 쓰는 명령어

cd /Users/bluemayne/Projects/Lumie/lumie-backend
명령용도참고
./gradlew build전체 컴파일과 기본 검증check를 포함하며, spotlessCheck와 license check에 의존합니다
./gradlew test빠른 기본 테스트 실행@Tag("integration") 테스트는 제외합니다
./gradlew integrationTestTestcontainers 기반 integration testDocker 접근이 필요합니다
./gradlew -Pintegration test기본 테스트와 integration test를 한 번에 실행느리지만 대규모 백엔드 머지 전에 유용합니다
./gradlew :modules:student:test모듈 범위 검증변경한 모듈 이름으로 student를 바꾸세요
./gradlew :app:test공통 런타임 연결과 OpenAPI snapshot testsecurity, RLS, data source, migration 작업에 유용합니다
./gradlew bootRun백엔드를 로컬에서 시작PostgreSQL, RabbitMQ, Redis, MinIO가 도달 가능해야 합니다
./gradlew snapshotOpenApi실행 중인 /v3/api-docslumie-frontend/openapi.json으로 가져오기kubectl exec를 통해 실행 중인 dev backend pod에서 읽습니다

빌드가 실제로 강제하는 것

build.gradle.ktsapp/build.gradle.kts 기준:

  • Java 툴체인: 21
  • 기본 test@Tag("integration")을 제외
  • integrationTest@Tag("integration")만 포함
  • spotlessCheckcheck의 일부
  • Error Prone은 빌드를 실패시키지 않는 경고 모드로 실행
  • JaCoCo report는 테스트 후 생성되지만, coverage verification은 아직 check에 연결되어 있지 않음
  • license 검사는 루트 check의 일부

따라야 할 백엔드 전용 규칙

  • 동기식 모듈 간 접근에는 libs/internal-api를 사용하세요.
  • 커밋 후 모듈 간 후속 처리는 Spring Modulith event를 발행하세요.
  • 외부 HTTP 호출은 긴 @Transactional 경계 밖에 두세요.
  • DTO에는 record를 사용하고 query service에는 @Transactional(readOnly = true)를 사용하세요.
  • 테넌트 안전 read/write가 동작하려면 context에 테넌트 ID가 있어야 하고, RLS가 바인딩될 실제 트랜잭션도 필요하다는 점을 기억하세요.

OpenAPI 계약 워크플로

백엔드는 다음 경로를 노출합니다.

  • /v3/api-docs
  • /swagger-ui.html

./gradlew snapshotOpenApi는 프론트엔드로 계약을 전달하는 문서화된 절차입니다. 이 task는:

  1. kubectl exec로 실행 중인 backend pod에 접근하고
  2. http://localhost:8080/v3/api-docs를 다운로드한 뒤
  3. 결과를 ../lumie-frontend/openapi.json에 씁니다

이 파일이 프론트엔드 codegen의 기준 원본입니다. 공유 응답, 오류, 페이지네이션, 멱등성, 장기 작업 envelope이 orval에 맞게 exported spec을 안정적으로 유지하는 방식은 API 계약에서 다룹니다.

변경 유형별 검증 플레이북

변경한 항목최소한 유용한 검증
controller, security, filter./gradlew :app:test와 영향받은 모듈 test task
RLS, migration, data source./gradlew integrationTest
한 모듈의 application 또는 domain logic./gradlew :modules:<name>:test
queue, outbox, 워커 integration code./gradlew :modules:exam:test와 보통 ./gradlew :app:test
libs/common의 공용 라이브러리 코드./gradlew :libs:common:test

일반적인 개발 제약 사항

  • Testcontainers 기반 integration test에는 Docker 접근이 필요합니다. 그래서 기본 test에서는 의도적으로 제외됩니다.
  • snapshotOpenApi는 실행 중인 backend pod와 정상 동작하는 kubectl context를 전제로 하며, 백엔드를 직접 부팅해 주지 않습니다.
  • bootRun은 사용할 수 있지만, 기본 dev topology는 여전히 클러스터 기반입니다. 여러 백엔드 경로가 실제 인프라 서비스에 기대기 때문입니다.

관련 페이지