Files
sodalive-backend-spring-boot/docs/20260223_채널후원기능추가.md

5.8 KiB

채널 후원 기능 추가 작업 계획

메시지 저장 전략 선택

  • 선택: 기본 메시지는 DB에 저장하지 않고, 후원 이력에는 can, isSecret, additionalMessage를 저장한 뒤 리스트 조회 시 메시지를 생성한다.

  • 이유: 일반/비밀 구분과 캔 수 노출 요구를 구조화 필드로 충족할 수 있고, 문구 변경/다국어 확장 시 DB 마이그레이션 없이 대응 가능하다.

  • 메시지 생성 규칙:

    • 일반 후원: OO캔을 후원하셨습니다.
    • 비밀 후원: OO캔을 비밀후원하셨습니다.
    • 추가 메시지 입력 시: 기본 메시지 + \n + "사용자 추가 메시지"
  • 채널 후원 도메인 모델/저장소 설계 (ChannelDonationMessage 성격의 별도 엔티티, creator/sponsor/can/isSecret/additionalMessage/createdAt)

  • CanUsage에 채널 후원 전용 값 1종 추가 및 영향 범위 정의 (CanPaymentService, 사용내역 타이틀 매핑)

  • 채널 후원 API 요청/응답 스펙 확정 (필드: creatorId, can, isSecret, message, container)

  • 채널 후원 API 서비스 플로우 설계 (인증/크리에이터 검증 -> 캔 차감 -> 후원 메시지 DB 저장)

  • 채널 후원 리스트 API 스펙 확정 (최근 1개월, createdAt 내림차순, 페이징)

  • 채널 후원 리스트 조회 권한 규칙 반영

    • 크리에이터: 모든 후원 내역 조회
    • 유저: 일반 후원 + 본인이 한 비밀 후원 내역 조회
  • 리스트 응답 메시지 조합 규칙 반영 (일반/비밀 기본 메시지 + 추가 메시지 쌍따옴표 처리)

  • explorer/profile/{id} 응답 확장 설계 (최근 1개월 채널 후원 내역 최대 5건 포함)

  • QueryDSL 조회 조건 확정 (createdAt >= now().minusMonths(1), orderBy(createdAt.desc(), id.desc()), limit 5)

  • 테스트 계획 수립 (서비스 단위 테스트 + 리포지토리 날짜 필터/정렬 테스트 + 컨트롤러 통합 테스트)

  • 정산 로직 제외 범위 명시 (정산 비율 변경 작업은 미포함, 채널 후원 기능만 구현)

  • 구현 후 검증 계획 확정 (./gradlew test, ./gradlew build, 필요 시 ./gradlew ktlintCheck)

  • 운영 반영용 DDL 파일 추가 (docs/20260223_channel_donation_message_ddl.sql)

  • 채널 후원 회귀 테스트 구현

    • 서비스: ChannelDonationServiceTest
    • 리포지토리: ChannelDonationMessageRepositoryTest
    • 컨트롤러: ChannelDonationControllerTest

검증 기록

  • 무엇을:
    • 1차 계획 수립: 채널 후원 기능의 API/도메인/조회 범위를 정의하고, 메시지 저장 전략을 선택해 계획 문서로 고정했다.
    • 2차 수정: 채널 후원 리스트 API의 조회 권한 규칙(크리에이터 전체 조회, 유저는 일반 후원+본인 비밀 후원 조회)을 계획 항목에 추가했다.
    • 3차 구현: 채널 후원 API/리스트 API/Explorer 프로필 확장, CanUsage.CHANNEL_DONATION, 메시지 엔티티 저장, 권한별 노출 필터를 구현했다.
  • 왜:
    • 기존 코드 패턴(Explorer/CanUsage/후원 조회)을 따르는 구현 범위를 먼저 고정해 불필요한 확장과 API 불일치를 방지하기 위해.
    • 리스트 조회 시 요청자 역할에 따라 비밀 후원 노출 범위가 달라지므로, 구현 전 권한 규칙을 계획 단계에서 명확히 고정하기 위해.
    • 채널 후원은 기존 라이브/콘텐츠 후원과 정산 분리를 위해 별도 CanUsage와 별도 메시지 저장소가 필요하고, 프로필 화면에 최근 내역 노출 요구가 있어 Explorer 응답 확장이 필요하기 때문에.
  • 어떻게:
    • 내부 탐색: ExplorerController, ExplorerService, ExplorerQueryRepository, CanUsage, CanPaymentService, LiveRoomService, LiveRoomRepository를 확인했다.
    • 병렬 조사: explore 2건(bg_07537536, bg_5be8611b)과 librarian 1건(bg_bfe81033) 결과를 수집해 근거를 보강했다.
    • 추가 확인: AudioContentCommentRepository, CreatorCommunityCommentRepository, LiveRoomRepository의 비밀/본인 공개 조건 패턴(isSecret.isFalse.or(writerId.eq(memberId)))을 확인해 문서 규칙에 반영했다.
    • 구현 파일: explorer/profile/channelDonation/*, CanUsage.kt, CanPaymentService.kt, CanService.kt, ExplorerService.kt, GetCreatorProfileResponse.kt를 수정/추가했다.
    • 검증 명령:
      • ./gradlew test -> 성공
      • ./gradlew build -> 최초 1회 GetCreatorProfileResponse.kt import 정렬 실패(ktlint), 정렬 수정 후 재실행 성공
      • ./gradlew ktlintCheck -> 성공

4차 보완(리뷰 지적사항 반영)

  • 무엇을:
    • 누락됐던 운영 반영용 DDL 파일 docs/20260223_channel_donation_message_ddl.sql을 추가했다.
    • 채널 후원 회귀 테스트 3종(서비스/리포지토리/컨트롤러)을 신규 추가했다.
  • 왜:
    • ddl-auto: validate 환경에서 신규 엔티티 스키마 누락 시 부팅 실패 위험이 있어 적용 스크립트를 분리 관리해야 했기 때문이다.
    • 권한별 비밀후원 노출, 1개월 필터, 정렬/페이징 규칙을 자동 검증해 회귀를 방지하기 위해서다.
  • 어떻게:
    • 추가 파일:
      • docs/20260223_channel_donation_message_ddl.sql
      • src/test/kotlin/kr/co/vividnext/sodalive/explorer/profile/channelDonation/ChannelDonationServiceTest.kt
      • src/test/kotlin/kr/co/vividnext/sodalive/explorer/profile/channelDonation/ChannelDonationMessageRepositoryTest.kt
      • src/test/kotlin/kr/co/vividnext/sodalive/explorer/profile/channelDonation/ChannelDonationControllerTest.kt
    • 검증 명령:
      • lsp_diagnostics -> Kotlin LSP 미설정으로 실행 불가(환경 제약 확인)
      • ./gradlew test --tests "*ChannelDonation*" -> 성공
      • ./gradlew test -> 성공
      • ./gradlew build -> 성공