BindProject

지금까지 프로젝트 리팩토링 시즌 도입

dding-shark 2025. 8. 12. 18:16
728x90

1) 요약

  • 본 저장소는 public/* 공용 모듈과 service/, bandroom/, application/* 도메인 모듈로 구성되어 있습니다.
  • 공용 모듈은 광범위하게 참조되며, 특히 exception, infra-messaging, data-serializer, event, logtracer, infra-redis 등이 높은 빈도로 사용됩니다.
  • 다수의 패키지 네이밍 오탈자(response, excrptions)가 코드 전반에 퍼져 있으며, 이는 패키지 체계의 일관성을 해치고 IDE 네비게이션/자동완성에도 부정적입니다.
  • 일부 모듈 간 경계가 모호하거나 중복(예: response와 common-api의 경계, event/contract/infra-messaging/outbox의 경계)하여 통합 또는 명확화가 필요합니다.

핵심 제안 요약:

  • 공용 웹 계층 라이브러리 표준화: response + exception + common-api를 "common-web"(또는 common-api로 일원화)로 통합.
  • 메시징/이벤트 경계 명확화: event, contract, infra-messaging, outbox의 책임을 분리하되, 개발자 사용성을 위해 상위 집합 라이브러리 제공.
  • 패키지 네이밍 표준 수립 및 전역 리팩토링: response → response, excrptions → exceptions.
  • 공용 모듈 계층 재그룹핑과 Gradle 의존 중복 제거, aggregator(플랫폼 BOM/스타터) 도입.

2) 현재 모듈 구성

settings.gradle 포함 모듈(발췌):

  • public: primary-id-provider, data-serializer, infra-messaging, exception, event, outbox, jwt-token, response, word-filter, contract, token-validation, infra-scheduling, common-api, infra-redis, logtracer
  • application: bff
  • service: auth, mail, image, user-profile, point, payment
  • bandroom: band-room(bandroom-info, product-info, studio), operation-hour, reservation(booking, coupon)

각 모듈의 역할(요약):

  • 공용(public/*): 공유 라이브러리/인프라(예외/응답/메시징/토큰/스케줄링/레디스/로그 등)
  • 서비스(service/*): 개별 Bounded Context별 마이크로서비스
  • 밴드룸(bandroom/*): 특정 도메인 서브시스템 묶음
  • 애플리케이션(application/*): BFF 등 경계 앱

3) 공용 모듈 사용처 집계(전역 build.gradle 검색 기반, 대략적 빈도)

  • exception: 16
  • infra-messaging: 12~13 (설정 파일 include 라인 제외 시 12)
  • data-serializer: 12
  • event: 12
  • primary-id-provider: 12
  • logtracer: 12
  • infra-redis: 9
  • response: 10
  • infra-scheduling: 11
  • word-filter: 8
  • common-api: 7
  • contract: 4
  • outbox: 3
  • jwt-token: 2
  • token-validation: 1

비고:

  • service:auth는 공용 모듈을 다수 참조하며 동일 모듈 중복 선언이 존재합니다(예: logtracer 중복).
  • bandroom 하위 모듈들은 messaging/redis/scheduling 의존이 고르게 분포합니다.

4) 패키지/코드 구조 관찰 사항

1) 패키지 오탈자

  • response 패키지명이 "response"로 곳곳에서 사용됨.
    • 예: public/response/src/main/java/response/BaseResponse.java
    • BFF 및 서비스/밴드룸 컨트롤러에서 import response.BaseResponse 광범위 사용
  • exception 루트 패키지가 "exception.exceptions"로 선언되어 있음.
    • 예: public/exception/src/main/java/exception/excrptions/CustomBaseException.java
    • 각 도메인 전반에서 exception.exceptions.[customexceptions] 참조
  • common-api의 GlobalExceptionHandler도 위 오탈자 패키지에 의존:
    • import exception.exceptions.CustomBaseException;
    • import response.BaseResponse;

2) 모듈 경계 중복/모호성

  • response vs common-api: 공통 웹 인터페이스 용도의 책임이 분산.
    • common-api는 스프링 Web에 의존하며 예외/응답을 함께 다루는 헬퍼 성격.
    • response 모듈이 별개로 존재해 양쪽 의존이 필요해짐. 실제 common-api가 response/exception에 다시 의존하는 구조.
  • event/contract/infra-messaging/outbox의 경계가 실사용 시 혼재.
    • event: 이벤트 타입/정의
    • contract: 서비스 간 DTO/스키마(이벤트/REST 공용?)
    • infra-messaging: 프로듀서/컨슈머/브로커 연동
    • outbox: Outbox 패턴 구현체
    • 실제 build.gradle에서는 event/contract/infra-messaging/outbox를 함께 의존하는 경우가 많음 → 개발자 경험 측면에서 상위 스타터 필요성.

3) 의존 중복 선언 사례

  • 예: bandroom-info/build.gradle에서 data-serializer가 중복 선언.
  • service/auth/build.gradle에서 logtracer 중복 선언.

4) 네이밍 컨벤션/루트 패키지

  • 최상위 패키지가 회사/조직 도메인(예: com.company) 형태가 아닌 모듈명 직결.
  • 장기적으로는 그룹화 및 검색성 향상을 위해 루트 패키지 일관화 권장.

5) 리팩토링 제안

A. 패키지 네이밍 일관화(가장 우선)

  • response → response, excrptions → exceptions로 전역 리네이밍.
  • 영향도: import 전역 변경. IDE 리팩토링(Refactor - Rename) 권장.
  • 마이그레이션 가이드(요약):
    1) response 모듈에서 패키지 선언 및 디렉터리명 변경.
    2) exception 모듈에서 패키지 선언 및 디렉터리명 변경(예: exception.exceptions).
    3) 전체 리포지토리에서 import 라인 일괄 갱신.
    4) 점진적 적용이 필요하면, 기존 오탈자 패키지 하위에 Deprecated 클래스를 1 릴리스 동안 브릿지로 제공(가능하면 권장, 단 Java에선 완전한 별칭 제공 어려움).

B. 공용 웹 계층 통합

  • 제안1: response + exception + common-api → public:common-web(신규)으로 통합.
    • common-web 책임: 표준 응답(BaseResponse), 예외 계층/에러코드, 전역 예외 처리기(GlobalExceptionHandler), Controller 보일러플레이트
    • 장점: 컨슈머 모듈의 의존 단순화(3→1), 일관된 웹 규약
  • 제안2(더 작은 변경): public:response를 common-api로 편입(이관)하고 public:response 모듈은 Deprecated 처리.
    • 단계적 이동 방식으로 호환성 유지 용이.

C. 메시징/이벤트 경계 정리 + 스타터 제공

  • 역할 분리 원칙:
    • contract: 서비스 간 데이터 계약(REST DTO, 이벤트 페이로드 클래스 포함 가능) → 순수 모델 정의
    • event: 도메인 이벤트 타입/키/주제 등 이벤트 메타 정의(필요 시 contract와 합칠 수도 있음)
    • infra-messaging: 브로커 연동, Producer/Consumer 추상화(예: RabbitMQEventProducer 등)
    • outbox: Outbox 패턴 구현(발행 보장, 재시도 정책 등)
  • DX 향상을 위한 상위 스타터(예: public:messaging-starter)를 제공하여 일반 사용 모듈은 starter 하나만 의존하도록 단순화.
    • starter → infra-messaging + outbox + (필요 시) event/contract transitively 포함

D. 공용 인프라 묶음 스타터 도입

  • 예: public:infra-starter → infra-redis, infra-scheduling, logtracer를 transitively 포함.
  • 서비스/밴드룸 모듈은 공통 인프라 의존을 개별 나열 대신 스타터 1~2개로 대체 가능.

E. Gradle 의존 중복 제거 및 검사 규칙 추가

  • Gradle lint 또는 스크립트로 동일 project 의존 중복 선언 방지.
  • settings.gradle에 그룹 기준(include만)과 별개로, 각 서비스 모듈 템플릿 정립.

F. 루트 패키지 컨벤션 수립

  • 예: com.teambind.shared.<module> (public 모듈), com.teambind.<boundedContext>.<feature> (서비스)
  • 점진적 적용: 신규 코드부터 컨벤션 준수, 구 코드는 기능 수정 시 리팩토링.

6) 제안 우선순위와 기대효과

우선순위 1: 패키지 오탈자 정정(response, excrptions)

  • 즉각적인 IDE 품질/검색성 개선, 신규 인원 온보딩 비용 절감

우선순위 2: common-web 통합(또는 response → common-api 편입)

  • 컨슈머 모듈의 의존 수 축소, 공통 웹 규약 일원화

우선순위 3: 메시징 스타터 도입 및 경계 명확화

  • 이벤트 발행/소비 기능 도입 가속, 보일러플레이트 감소, 실패 시나리오 표준화

우선순위 4: 인프라 스타터 도입, 의존 중복 제거

  • 빌드 스크립트 간결화, 유지보수성 향상

7) 영향도 및 마이그레이션 가이드(개요)

1) 패키지 리네이밍

  • 영향 파일: 다수(컨트롤러/서비스/공용 모듈 전반)
  • 방법: IDE 리팩토링 + 전역 검색/치환, CI에서 컴파일 체크

2) common-web 통합

  • 단계적 접근: common-api에 BaseResponse 이관 → consumer 모듈에서 public:response 제거 → 안정화 후 response 모듈 폐기
  • 대안: 신규 common-web 생성 후, consumer가 common-web으로 전환 → 기존 모듈 Deprecation 표시

3) 메시징 스타터

  • 현재 event/contract/infra-messaging/outbox 사용 모듈에 starter 1개 추가 후 개별 의존 제거
  • Rollout: 각 서비스별 분기 릴리스에 맞춰 교체, 회귀 테스트 준비

4) 빌드 스크립트 정리

  • 중복 의존 제거 PR 분할(서비스별) → 변경 영향 최소화

8) 세부 근거 및 참고 코드

  • GlobalExceptionHandler (public/common-api): import 오탈자 사용
    • file: public/common-api/src/main/java/common/api/handler/GlobalExceptionHandler.java
    • import exception.exceptions.CustomBaseException;
    • import response.BaseResponse;
  • 오탈자 참조 예시(발췌)
    • application/bff/*: 다수의 컨트롤러/클라이언트에서 response.BaseResponse 사용
    • bandroom/*: controller/mapper/service에서 response 및 excrptions 참조
    • public/exception/*: 패키지 선언 자체가 excrptions
  • 공용 모듈 다중 의존 사례
    • service/auth/build.gradle: outbox, event, exception, primary-id-provider, response, jwt-token, infra-messaging, contract, infra-scheduling, common-api, logtracer, infra-redis 등 대량 참조(일부 중복)

9) 후속 작업 제안(실행 계획)

  • 주차 1: 패키지 오탈자 리네이밍 계획 수립 및 PoC 브랜치 수행
  • 주차 2: common-api로 BaseResponse 이관(또는 common-web 신설) 및 consumer 모듈 1~2개 시범 전환
  • 주차 3: messaging-starter 도입 및 한 서비스에 적용 후 회귀 테스트
  • 주차 4: 인프라 스타터 적용, 빌드 스크립트 중복 제거, 린팅/체크 도입

10) 부록: 사용처 검색 쿼리(발췌)

  • project(':public:common-api') → 7개 모듈
  • project(':public:exception') → 16개 모듈
  • project(':public:response') → 10개 모듈
  • project(':public:infra-messaging') → 12개 모듈
  • project(':public:infra-redis') → 9개 모듈
  • project(':public:infra-scheduling') → 11개 모듈
  • project(':public:word-filter') → 8개 모듈
  • project(':public:event') → 12개 모듈
  • project(':public:contract') → 4개 모듈
  • project(':public:outbox') → 3개 모듈
  • project(':public:jwt-token') → 2개 모듈
  • project(':public:token-validation') → 1개 모듈

참고: 빈도는 검색 결과 기준 대략치이며, 일부는 동일 모듈 내 중복 선언/설정 파일 포함 가능.


11) 업데이트: 공용 웹 스타터 도입(common-web-starter)

  • 목적: common-api, exception, response(+ contract) 의존을 하나의 모듈로 집약하여 소비자 모듈의 의존 목록을 단순화.
  • 모듈: public:common-web-starter
    • 구성(api 의존):
      • :public:common-api
      • :public:exception
      • :public:response
      • :public:contract
  • 사용법(예: service/auth/build.gradle):
    • implementation project(':public:common-web-starter')
    • 이후 기존의 common-api, exception, response, contract 직접 의존은 제거
  • 이점:
    • 의존 관리 간소화(3~4개 → 1개)
    • 코드 병합 없이도 일관된 웹 규약 제공(모듈 비대화 방지)
  • 비고:
    • 단계적 전환 가능. 각 서비스 모듈에서 기존 3~4개 의존을 제거하고 starter 1개로 교체.

12) 작업 진행 상황 업데이트 (2025-08-12)

  • BaseResponse 위치 변경: public/response → public/common-api (패키지: common.api.response). [적용 완료]
  • 전역 import 정리: response.BaseResponse → common.api.response.BaseResponse로 전환. 코드 전역 반영 완료(문서 내 과거 사례 표기는 참고용으로 유지). [적용 완료]
  • 공용 웹 스타터 전환: application/bff가 :public:common-web-starter 의존으로 전환하고, 기존 common-api/exception/contract/response 직접 의존 제거. [적용 완료]
  • 공용 모듈 의존 정리: public:common-api에서 :public:response 의존 제거. [적용 완료]
  • 빌드 상태: 전체 모듈 빌드 성공. BFF의 제네릭 변환 유틸에 대해 @SuppressWarnings("unchecked") 추가로 경고 정리. [적용 완료]
  • 후속 과제(로드맵):
    • 다른 서비스/밴드룸 모듈들도 공용 웹 스타터(:public:common-web-starter)로 단계적 전환. [진행 예정]
    • public:response 모듈은 의존 완전 제거 확인 후 폐기 플랜 수립. [진행 예정]
    • exception 패키지 오탈자(excrptions → exceptions) 전역 리네이밍 및 import 정리. [진행 예정]

변경 파일(발췌):

  • public/common-api/src/main/java/common/api/response/BaseResponse.java (신규 위치)
  • public/common-api/src/main/java/common/api/exceptionhandler/GlobalExceptionHandler.java (import 수정)
  • application/bff/build.gradle (:public:common-web-starter로 전환)
  • public/common-api/build.gradle (:public:response 의존 제거)
  • application/bff/src/main/java/** (BaseResponse import 전역 수정)
  • bandroom//controller/ (BaseResponse import 전역 수정)
  • service//controller/ (BaseResponse import 전역 수정)

참고: 문서 본문(§4, §8, §10)은 과거 문제 상황의 근거로서 "import response.BaseResponse" 예시를 포함하고 있습니다. 현재 코드는 모두 common.api.response.BaseResponse를 사용합니다.


13) 상태 확인 컨펌 (2025-08-12 14:36)

  • public:response 의존성 제거: 전역 검색 결과 build.gradle 내 의존 0건, 코드 import도 common.api.response.BaseResponse로 전환 완료(문서 내 과거 사례 표기는 예시로만 존재). [완료]
  • public:response 폐기 플랜: 다음 단계에서 settings.gradle의 include(':public:response') 제거 및 모듈 디렉터리 삭제. 현재 의존 0건이므로 안전. 필요 시 1 릴리스 동안 유지 후 제거. [준비 완료]
  • exception 패키지 오탈자 정정: excrptions → exceptions 전역 검색 결과 잔여 참조 0건(문서 제외). import/패키지 선언 정리 완료. [완료]
  • 빌드 상태: 전체 빌드 성공으로 변경사항 유효성 확인. [완료]

14) 후속 리팩토링 과제 (2025-08-12 15:00)

  • 목적: 공용 웹 스타터 도입을 전 모듈로 확산하고, 중복/잔존 의존 제거 및 빌드 품질 가드를 강화합니다.
  1. 공용 웹 스타터(:public:common-web-starter) 전면 전환

    • service/, bandroom/ 전 모듈에서 common-api/exception/contract 직접 의존 제거하고 starter 1개로 수렴.
    • build.gradle 중복 선언 정리 및 불필요 의존 삭제. [완료]
  2. public:response 모듈 완전 폐기

    • settings.gradle에서 include(':public:response') 제거.
    • 모듈 디렉터리 삭제 전, 전역 import/의존 0건 재검증.
    • 릴리스 노트/마이그레이션 가이드에 반영. [완료]
  3. exception 패키지 네임스페이스 재점검

    • exceptions 네임스페이스 통일 여부 재검증(코드/테스트/샘플 포함).
    • CI에 금칙 import 룰 추가(excrptions 금지, response.BaseResponse 금지). [완료]
  4. 메시징/인프라 스타터 PoC

    • messaging-starter(= infra-messaging + outbox + event/contract 필요 부분) 초안 생성.
    • infra-starter(= infra-redis + infra-scheduling + logtracer) 초안 생성.
    • 1~2개 서비스에 시범 적용해 의존 간소화 효과 측정.
  5. 버전 관리 일원화

    • Gradle Version Catalogs(libs.versions.toml) 또는 BOM 도입 검토/적용.
    • querydsl, lombok, jackson, springdoc, shedlock 등 중복 버전 해소.
  6. 빌드 퀄리티 가드 강화

    • 컴파일 옵션에 -Xlint:unchecked 활성화 및 경고 소거 작업.
    • 중복 의존 탐지 스크립트/플러그인 도입(gradle-versions-plugin, lint).
  7. 패키지 루트 컨벤션 가이드

    • 공용: com.teambind.shared., 서비스: com.teambind.. 권고안 문서화.
    • 신규 코드부터 적용, 변경 시 리팩토링 원칙 정의.
  8. 배포/운영 마이그레이션 가이드 정리

    • response 모듈 제거 전후 변경점, 소비자 모듈 적용 순서, 롤백 전략 문서화.
  9. 테스트/검증 계획

    • 공용 스타터 전환 모듈별 컴파일/단위/통합 테스트 수행.
    • BFF 및 주요 경로에 회귀 테스트 우선 적용.
728x90