Files
sodalive-backend-spring-boot/docs/20260316_캔사용내역조회리팩토링.md

2.9 KiB

20260316_CanServiceGetCanUseStatusRefactoring.md

작업 목표

  • CanService.getCanUseStatus 함수의 비효율적인 필터링 및 데이터 로딩 로직 개선.
  • Kotlin 레벨에서 수행하던 필터링을 DB 레벨(Querydsl)로 이동.
  • Entity 전체를 조회하는 대신 필요한 필드만 조회(Query Projection)하도록 리팩토링.

작업 내용

  • CanService.getCanUseStatus 현재 기능 검증용 테스트 코드 작성.
  • UseCanQueryDto 생성 (QueryProjection용 DTO).
  • CanRepository에 Querydsl 기반의 고도화된 getCanUseStatus 추가 (또는 기존 메서드 수정).
    • member.id 필터링 (기존 유지).
    • (can + rewardCan) > 0 필터링.
    • container(aos, ios, else)별 paymentGateway 필터링 (Join 사용).
    • 필요한 연관 엔티티(Member, Room, AudioContent 등)의 필드만 선택적으로 조회.
  • CanService.getCanUseStatus 리팩토링.
    • 리포지토리에서 바로 DTO 또는 필요한 데이터만 받아오도록 수정.
    • Kotlin filter 제거.
    • Kotlin map 로직 단순화 또는 QueryProjection으로 흡수 가능한지 판단하여 처리.
  • 작성한 테스트 코드로 기능 검증.
  • 테스트 코드에 @DisplayName 추가 및 예외/엣지 케이스 테스트 보강.
  • 성능 및 쿼리 최적화 확인.

검증 결과

  • 기능 검증:
    • CanServiceTest.kt를 작성하여 리팩토링 전후의 필터링 및 맵핑 로직이 동일하게 유지됨을 확인.
    • @DisplayName을 추가하여 테스트 의도를 명확히 기술.
    • 유효하지 않은 타임존 입력 시 DateTimeException이 발생하는 예외 케이스 추가.
    • 데이터가 없을 때 빈 리스트 반환 및 각 CanUsage별 nullable 필드(닉네임, 제목 등)가 누락되었을 때의 기본 타이틀 처리 로직 검증.
  • 성능 개선:
    • Kotlin 레벨의 필터링을 DB 레벨(Querydsl)로 이동하여 불필요한 데이터 조회를 줄이고 페이지네이션 정확도 향상.
    • Entity 전체 조회 대신 필요한 12개 필드만 조회하는 UseCanQueryDto 사용 (Projection).
    • CHANNEL_DONATION 시 별도의 Member 조회를 위해 발생하던 N+1 또는 추가 쿼리를 Join을 통해 1번의 쿼리로 최적화.
  • 코드 품질:
    • CanService에서 더 이상 사용하지 않는 memberRepository 의존성 제거.
    • 복잡한 맵핑 로직을 QueryProjection DTO 기반으로 깔끔하게 정리.

단계별 검증 내용

  1. 1차 구현 및 단위 테스트: CanServiceTest를 통해 aos, ios 컨테이너별 필터링 조건이 올바르게 DB 쿼리에 반영되고 결과가 맵핑되는지 검증 (성공).
  2. 쿼리 최적화 확인: UseCanCalculate 및 관련 엔티티들을 leftJoininnerJoin을 통해 한 번의 쿼리로 가져오도록 구현됨을 코드 레벨에서 확인.