Files
readme-haness/runs/ca-tmpl/20260717-quality-core/README.generated.md
T

9.7 KiB

ca-tmpl — 경계를 실행 가능한 규칙으로 만드는 Spring Boot 템플릿

ca-tmpl은 Java 21과 Spring Boot 4.0.0을 기준으로 구성된 멀티 모듈 서비스 템플릿입니다.

이 저장소의 초점은 기능 예제를 많이 제공하는 데 있지 않습니다. domain, application, adapter, bootstrap의 책임을 나누고, 그 경계가 기능 추가 과정에서 무너지지 않도록 Gradle과 ArchUnit 검증을 함께 제공하는 데 있습니다.

템플릿 개요

19개 Gradle 모듈이 core, inbound adapter, outbound adapter, composition root, sample 역할로 선언되어 있습니다.

다음 상황에 특히 잘 맞습니다.

  • 새 Java 서비스에서 모듈 경계와 검증 기준을 함께 시작하려는 경우
  • HTTP·메시징·캐시·영속성 같은 기술 세부사항을 유스케이스와 분리하려는 경우
  • 예제 코드를 제거한 뒤에도 핵심 구조가 독립적으로 성립하는지 자동 검증하려는 경우

반대로 단일 모듈 CRUD 예제나 특정 조직의 운영 정책까지 완성된 배포판이 필요하다면, 이 템플릿의 범위보다 가벼운 시작점 또는 별도의 플랫폼 기준이 더 적합할 수 있습니다.

저장소가 강제하는 것, 도입자가 결정할 것

저장소가 실행 가능하게 강제하는 것 도입자가 서비스 맥락에 맞게 결정할 것
모든 선언 모듈을 의존성 정책에 포함하고 허용되지 않은 프로젝트 의존성을 실패시킵니다. 실제 도메인 경계와 bounded context
application 코드가 adapter·bootstrap·transport·persistence에 의존하지 못하도록 검사합니다. 사용할 inbound·outbound adapter의 범위
leaf module의 모든 dependency configuration을 STRICT lock mode로 검증합니다. 배포 플랫폼, SLO, 용량과 장애 복구 정책
같은 핵심 테스트를 sample-portfolio 없이 컴파일·실행하는 경로를 제공합니다. 인증·인가, 데이터 보존, 외부 연동의 서비스별 정책

이 구분이 중요합니다. 템플릿은 “어떤 결정을 해야 하는가”와 경계를 지키는 장치를 제공하지만, 서비스 고유의 결정을 대신하지는 않습니다.

아키텍처와 코드 배치

다음 그림의 화살표는 런타임 호출 순서가 아니라 허용된 프로젝트 의존 방향을 요약합니다.

flowchart LR
    Inbound[Inbound adapters<br/>web · gRPC · GraphQL · WebSocket]
    Application[application-core<br/>use cases · ports]
    Domain[domain-core<br/>business invariants]
    Outbound[Outbound adapters<br/>persistence · messaging · cache · integrations]
    Shared[shared-contract<br/>operational contracts]
    Bootstrap[app-bootstrap<br/>composition root]

    Inbound --> Application
    Outbound --> Application
    Application --> Domain
    Inbound --> Shared
    Outbound --> Shared
    Application --> Shared
    Bootstrap --> Inbound
    Bootstrap --> Outbound
    Bootstrap --> Application
    Bootstrap --> Domain
    Bootstrap --> Shared
모듈 그룹 코드 배치 기준
domain-core 외부 라이브러리 의존성 없이 비즈니스 불변식과 도메인 타입을 둡니다.
application-core domain-coreshared-contract에 의존하며 유스케이스와 port를 둡니다.
adapter:inbound:* / adapter:outbound:* 전송 계층 입력과 기술별 출력 구현을 core 바깥에 둡니다.
shared-contract 비즈니스 개념이 아닌 공용 운영 계약을 둡니다.
app-bootstrap 선택한 core와 adapter를 조립하고 Spring Boot 진입점을 소유합니다.
sample-portfolio 템플릿 사용법을 보여주는 참조 구현이며 일반 테스트의 fixture로만 연결됩니다.

Gradle의 verifyCleanArchitectureDependencies는 모듈 간 의존 방향을, CleanArchitectureTest는 application 패키지의 adapter·transport 접근과 같은 코드 수준 경계를 검사합니다.

빠른 시작

필요한 도구는 JDK 21과 실행 중인 Docker daemon입니다. 저장소의 도구 버전 파일은 Temurin 21.0.11+10을 지정하고, bootstrap preflight는 Docker CLI가 daemon에 연결되는지 확인합니다.

저장소 루트에서 다음을 실행합니다.

cd src
./gradlew bootstrap

./gradlew bootstrap은 전체 소스 컴파일, Docker 확인, 로컬 PostgreSQL과 앱 시작, sample 격리 계약, HTTP smoke check를 순서대로 실행합니다.

성공 조건은 http://localhost:8080/api/healthcheck가 HTTP 200과 status=UP을 반환하는 것입니다.

bootstrap은 Compose의 appdb 서비스를 백그라운드로 시작합니다. 작업을 마치면 저장소 루트에서 종료합니다.

cd ..
docker compose -f docker-compose.yml -f docker-compose.local.yml down

위 Compose 명령은 저장소에 선언된 base와 local 구성 파일을 함께 사용해 서비스를 종료합니다.

실제 프로젝트로 전환하기

한 번에 모든 이름과 모듈을 지우기보다, 각 단계에서 검증 가능한 상태를 유지하는 편이 안전합니다.

  1. 식별자를 먼저 정합니다. Gradle root name은 ca-skeleton, Java package root와 main class는 dev.caskeleton 아래에 선언되어 있으므로 서비스 이름과 namespace 정책에 맞게 함께 변경합니다.
  2. 도메인과 유스케이스를 core에 세웁니다. 비즈니스 불변식은 domain-core, 유스케이스와 port는 application-core에 둡니다.
  3. 필요한 adapter만 선택합니다. 전송 기술은 inbound, 데이터베이스·메시징·캐시·외부 연동은 outbound 모듈에서 선택하고 app-bootstrap에서 조립합니다.
  4. 환경·운영 계약을 서비스 기준으로 확정합니다. 환경 키 레지스트리와 Compose 기본값을 검토하되, 조직의 secret 관리·배포·관측 정책을 별도로 적용합니다.
  5. sample을 제거하고 독립성을 확인합니다. sample-portfolio는 일반 테스트의 sampleFixture로만 연결되며 sampleOffTest는 샘플 없는 classpath에서 같은 핵심 테스트 corpus를 실행합니다.

도입 중 코드의 위치가 애매하면 “이 코드는 비즈니스 규칙인가, 유스케이스 조정인가, 기술 구현인가, 조립인가?”를 먼저 묻고 위 모듈 표에 배치하십시오. 새 모듈을 추가하면 Gradle 의존성 정책에도 명시적으로 등록해야 합니다.

검증 루프

작업 목적에 맞는 가장 작은 검증부터 실행하고, 변경을 공유하기 전 전체 계약으로 넓힙니다.

  • 일반 테스트: ./gradlew test
  • 모듈 의존 방향만 빠르게 확인: ./gradlew verifyCleanArchitectureDependencies
  • sample 제거 가능성 확인: ./gradlew :app-bootstrap:sampleOffTest
  • 전체 품질 계약: ./gradlew check
cd src
./gradlew test
./gradlew verifyCleanArchitectureDependencies
./gradlew :app-bootstrap:sampleOffTest
./gradlew check

check는 테스트뿐 아니라 아키텍처 의존성, 환경 키, 산출물, 타입 배치, 취약점 예외, quarantine 만료, README 명령 검증을 집계합니다.

상세 문서 지도와 적용 한계

README는 판단과 첫 실행에 필요한 정보만 유지합니다. 세부 계약은 소유 위치에서 확인하십시오.

도입 전에 다음 한계를 명시적으로 받아들이거나 보완해야 합니다.

  • 여러 inbound·outbound adapter 모듈이 포함되어 있지만 실제 서비스가 채택할 범위와 배포 환경은 템플릿이 결정하지 않습니다.
  • 기본 로컬 실행 경로는 Docker와 PostgreSQL 16 Compose 서비스를 전제로 합니다.
  • 자동 검증은 저장소 내부의 구조·구성 계약을 지킵니다. 조직별 threat model, SLO, 부하 특성, 데이터 보존과 복구 목표는 별도의 설계·검증 대상입니다.