Skip to content

[Refactor/#14] 도메인 모듈 패키지 구조·경계 검증 방식 변경 및 infrastructure:db 설정 골격 - #15

Open
tnals0924 wants to merge 4 commits into
mainfrom
refactor/#14-domain-module-structure
Open

[Refactor/#14] 도메인 모듈 패키지 구조·경계 검증 방식 변경 및 infrastructure:db 설정 골격#15
tnals0924 wants to merge 4 commits into
mainfrom
refactor/#14-domain-module-structure

Conversation

@tnals0924

Copy link
Copy Markdown
Member

#️⃣연관된 이슈

🎯 해결하려는 문제가 무엇인가요?

엔티티 26개를 추가하는 #13에 앞서, 그 코드가 올라갈 도메인 모듈의 구조와 경계 검증 방식을 먼저 정한다. 아울러 infrastructure:db가 실제 MySQL에 붙을 수 있는 설정 골격을 만든다. 이 PR은 기존 member 코드에만 적용하며 새 테이블·엔티티는 포함하지 않는다.

❓ 왜 해결해야 하나요?

  • 기존 컨벤션(공개 타입을 모듈 최상위에, 구현은 internal)은 도메인·계층 단위로 패키지를 나누고 싶은 요구와 맞지 않았다.
  • 계층 패키지로 나누면 Modulith 기본 규칙상 하위 패키지가 전부 비공개가 되어, impl 하나를 감추려고 공개 패키지마다 @NamedInterface를 달아야 한다. 도메인이 늘수록 부담이 커진다.
  • 이 결정이 엔티티 65개 파일과 같은 PR에 섞이면 리뷰가 되지 않는다.

⭐ 어떻게 해결했나요?

  • 패키지 구조: {module}.domain.{도메인}.{domain|repository|service|service.impl}. 도메인 객체만 있는 도메인도 계층 패키지를 생략하지 않는다.
  • 공개 경계: 도메인 모듈 4개를 @ApplicationModule(type = OPEN)으로 두고, service.impl 차단은 ArchUnit 테스트 DomainImplAccessTests가 담당한다. 규칙은 두 개 — ..service.impl..은 같은 패키지 안에서만 참조 가능, ..service.impl..에 public 클래스 금지.
  • 도메인 객체: record 대신 일반 클래스(@Getter + @EqualsAndHashCode + private 전체 생성자 + static of(...)). setter는 Lombok으로 만들지 않고 필요한 필드에만 수동으로 둔다.
  • soft delete: deleted_at DATETIMEis_deleted TINYINT(1) (BaseSoftDeleteEntity.isDeleted).
  • db 설정 골격: application-infrastructure-db.yml(MySQL, ddl-auto: validate, Flyway), .env.exampleDB_*, BaseCreatedTimeEntity, db 모듈의 도메인 모듈 의존.
  • 테스트: DB를 쓰는 테스트는 두지 않기로 하여 H2 의존성과 contextLoads를 제거했다. 남는 테스트는 ModularityTests(모듈 간 순환·의존)와 DomainImplAccessTests(impl 경계)다.
  • 컨벤션 문서 6개를 위 규칙으로 갱신했다.

🧩 이 PR의 한계 & 트레이드오프

  • OPEN 모듈은 Modulith 문서상 "점진적 이행용"이다. 그 경고는 최상위 공개 구조를 전제로 한 것이고, 여기서는 계층 패키지를 의도적으로 택한 결과다. 대신 Modulith verify()의 역할이 모듈 간 순환·의존 검사로 줄고, 모듈 내부 경계는 ArchUnit이 맡는다.
  • contextLoads가 없어져 Entity 매핑 오류는 애플리케이션 기동(bootRun)에서만 드러난다.
  • coding-style.md 2-1절(도메인 객체 record)과 flyway-migration.md(deleted_at 예시)는 이 PR에서 고치지 않았다. 별도 docs 작업이 필요하다.

⛓️ 기존 기능에 미치는 영향

  • Member가 record에서 클래스로 바뀌어 접근자가 id()getId(), 생성이 new Member(...)Member.of(...)로 바뀐다. 현재 호출처는 MemberJpaEntity뿐이다.
  • Member.studentNostudentId로 이름을 바꿨다.
  • MemberService 등 member 타입의 패키지가 바뀐다. 현재 다른 모듈에서 참조하는 곳은 infrastructure:db뿐이며 함께 수정했다.
  • bootstrap/application.yamlapplication-infrastructure-db.yml을 import하므로 기동 시 DB_URL/DB_USERNAME/DB_PASSWORD 환경변수가 필요하다.

🔀 Edge Case & 실패 시나리오

  • service.impl에 public 클래스를 두거나 다른 패키지에서 참조하면 DomainImplAccessTests가 실패한다. 실험으로 확인했다(임시 파일은 제거).
  • 새 모듈을 만들 때 기본 패키지에 package-info.java(OPEN)를 빠뜨리면 그 모듈의 하위 패키지 참조가 verify()에서 실패한다.

📋 검토한 대안과 선택 이유

  • @NamedInterface를 공개 계층 패키지마다 선언: 정확하지만 도메인당 package-info.java 3개가 늘고 하나만 빠져도 verify()가 깨진다. 처음 이 방식으로 구현했다가 OPEN + ArchUnit으로 바꿨다.
  • 원래 컨벤션(최상위 공개 + internal) 유지: 어노테이션이 필요 없지만 도메인·계층 단위 패키지를 포기해야 한다.
  • 테스트에 H2 + ddl-auto: create-drop 유지: Entity 매핑 검증에는 유용하지만 DB를 쓰는 테스트를 두지 않기로 한 방침과 어긋나 제거했다.

💬 리뷰 포인트

  • [r] architecture.md 4-3절 — 패키지 구조와 OPEN + ArchUnit 방식에 동의하는지
  • [r] DomainImplAccessTests 규칙 1이 같은 도메인의 service 패키지에서 impl을 참조하는 것도 막는데, 이 강도가 적절한지
  • [c] 도메인 객체를 record 대신 클래스로 두는 결정(coding-style.md 2-10·2-11절과의 정합)
  • [c] is_deleted boolean으로의 변경

@sangrae2325

sangrae2325 commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator
  1. 이미 정해진 도메인수와 도메인별 공개 계층 패키지수가 많아서, 현재 구현 하신 방식에 동의합니다.
  2. service 패키지는 외부에 공개되는 패키지라서 현재처럼 impl 참조를 막는 강도가 적절해보입니다.
  3. 앞으로 모든 도메인 객체를 일반 클래스로 두는 방향인지, 필요에 따라 record와 클래스를 구분해서 사용하는 방향인지 궁금합니다.

@jjunh33

jjunh33 commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator
  1. 도메인, 계층별 패키지가 많아서 @NamedInterface를 각각 관리하는 것보다 OPEN + ArchUnit으로 검증하는 현재 방식이 관리 측면에서 더 좋아보입니다.
  2. service가 외부에 공개되는 계층인 만큼 service.impl에 직접 의존하지 못하도록 제한하는 것에 동의합니다.
  3. is_deleted를 TINYINT(1) 타입으로 DB에 저장하고, boolean으로 사용하는 구조에 동의합니다.

@xeoxxn
xeoxxn self-requested a review September 7, 2026 05:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

도메인 모듈 패키지 구조·경계 검증 방식 변경 및 infrastructure:db 설정 골격

3 participants