Files
sodalive-backend-spring-boot/docs/20261019_첫충전보너스신규지급중단/prd.md
T

82 lines
7.3 KiB
Markdown

# 첫 충전 보너스 신규 지급 중단 PRD
## 문서 정보
| 항목 | 내용 |
|---|---|
| 문서 상태 | 구현·검증·독립 리뷰 완료, 미배포 |
| 작성일 | 2026-10-19 |
| 최종 수정일 | 2026-10-19 |
| 대상 제품 | 충전 이벤트 보너스 지급 |
| 작성자·결정권자 | 사용자 요청 |
| 관련 구현 계획 | [plan-task.md](plan-task.md) |
| 관련 review | [plan-task.md 최종 Gate 기록](plan-task.md#p1-gate-최종-판정-2026-10-19) |
## 1. 개요와 문제
변경 전에는 결제 완료 뒤 `ChargeEventJobService`가 인증 회원의 첫 충전을 판정해 원본 충전량의 15%를 올림 계산한 `FIRST_CHARGE` 작업을 만들었다. 이번 변경은 첫 충전 보너스 신규 생성을 중단하되, 이미 저장된 작업과 일반 활성 충전 이벤트의 지급 계약을 유지한다.
사용자 확인 정책: 기존 지급은 정상 동작 중이며, “이미 생성된 것은 기존대로 지급한다.” 이 문서는 정책과 구현 범위를 기록할 뿐이며, 문서 변경 자체는 실제 지급을 중단하지 않는다.
## 2. 목표와 제외 범위
### 목표
- 이후 코드가 만드는 새 보너스 작업은 기존 `ACTIVE_CHARGE_EVENT` 조건을 만족할 때만 생성한다.
- 신규 `FIRST_CHARGE` 작업을 만들지 않는다.
- 저장된 작업은 현재 worker와 관리자의 기존 계약대로 처리한다.
- 현재 `test` 브랜치에서 작업하며 별도 worktree나 브랜치를 생성하지 않는다. 문서 작성 후 사용자 승인에 따라 아래 범위만 구현한다.
### 제외
- 원본 유료 충전, 회원 정보 응답의 `chargeCount`, `isFirstCharged` 광고 추적, 클라이언트 API 변경.
- `FIRST_CHARGE` enum, 기존 작업 스냅샷, 지급·알림·현지화·재시도·멱등성 처리 제거 또는 변경.
- 과거 작업·보너스 데이터 수정/삭제, clawback, DB migration, feature flag, cutoff-date 설정.
- 새 의존성, 광범위한 정리, 사용처가 없는 레거시 서비스 제거.
## 3. 확정 요구사항과 수용 기준
| ID | 상태 | 요구사항 | 수용 기준 |
|---|---|---|---|
| STOP-001 | 확정 | 새 `FIRST_CHARGE` 작업을 생성하지 않는다. | 각 결제 게이트웨이의 검증을 통과한 신규 충전에서 생성되는 작업이 없거나 `ACTIVE_CHARGE_EVENT`뿐이다. 15% 계산 및 첫 충전 사유 스냅샷을 신규 생성 경로에서 사용하지 않는다. |
| STOP-002 | 확정 | 일반 활성 이벤트를 기존 기준으로 유지한다. | 인증 회원의 첫 결제도 같은 `buildActiveEventSnapshot` 경로를 따른다. 활성 이벤트 부재 또는 회원별 횟수 한도 소진이면 작업을 만들지 않는다. 결제 및 일반 충전 처리는 성공한다. |
| STOP-003 | 확정 | 이미 생성된 작업을 기존대로 처리한다. | 저장된 `PENDING`은 worker 대상이다. `FAILED`는 관리자 재시도 후 worker 대상이다. `PROCESSING`에는 자동 복구를 새로 추가하지 않는다. `DONE`은 재지급하지 않는다. 처리 과정은 인증/이벤트 자격을 재계산하지 않고 저장된 gateway, container, amount, method snapshot을 사용한다. |
| STOP-004 | 확정 | 원본 충전 기록과 외부 계약을 보존한다. | 유료 충전, 회원 충전 이력/광고 추적, 공개 API에는 변경이 없다. |
## 4. 기술 범위와 보존 경계
변경 지점은 [`ChargeEventJobService.kt`](../../src/main/kotlin/kr/co/vividnext/sodalive/v2/can/charge/event/ChargeEventJobService.kt)의 `buildSnapshot(charge, member): ChargeEventJob?`이다. `buildActiveEventSnapshot`을 직접 반환하도록 하며, 결제 gateway 검증은 그 호출 전에 유지한다. 이후 인증회원 첫 결제 여부와 무관하게 활성 이벤트 조회 및 횟수 제한을 적용한다.
이 변경으로 더 이상 사용하지 않는 `AuthRepository` 생성자 의존성/import, `buildFirstChargeSnapshot`, `ceil` import를 제거한다. `FIRST_CHARGE_METHOD`는 이 파일에서만 참조되며 제거 대상이다. 단, `FIRST_CHARGE` enum과 `methodSnapshot`을 이용하는 기존 작업 처리 및 `publishPaidNotification` 분기는 보존한다.
[`ChargeEventJob.kt`](../../src/main/kotlin/kr/co/vividnext/sodalive/v2/can/charge/event/ChargeEventJob.kt), [`ChargeEventJobRepository.kt`](../../src/main/kotlin/kr/co/vividnext/sodalive/v2/can/charge/event/ChargeEventJobRepository.kt), [`ChargeEventJobWorker.kt`](../../src/main/kotlin/kr/co/vividnext/sodalive/v2/can/charge/event/ChargeEventJobWorker.kt), [`AdminChargeEventJobService.kt`](../../src/main/kotlin/kr/co/vividnext/sodalive/v2/admin/event/charge/AdminChargeEventJobService.kt)와 결제 완료 경로는 수정 대상이 아니다. `ChargeEventService.applyChargeEvent`에는 현재 호출자가 없지만 이를 포함한 레거시 서비스는 이 작업에서 제거하지 않는다. 레거시가 참조하는 `AuthRepository` 및 `ChargeRepository` 공용 메서드도 유지한다.
## 5. 배포와 운영 경계
- 적용 기준은 구매 시작일이나 별도 cutoff 설정이 아니라, 새 작업을 만들지 않도록 갱신된 코드가 실제 실행되는 시점이다.
- 구버전 인스턴스가 남아 있는 rolling 배포 중에는 `FIRST_CHARGE` 작업이 더 생길 수 있다. 모든 구버전 생성 인스턴스가 drain된 뒤에야 신규 생성 중단이 완결된다.
- 배포 시점/일정은 이 문서에서 정하지 않는다.
- 배포 후 운영 확인 항목은 cutoff 이후 신규 `FIRST_CHARGE` 작업 부재와 기존 스냅샷 작업의 정상 지속 처리다. 이는 향후 확인 체크리스트이며, 실행된 운영 검증이 아니다.
## 6. 추적과 의사결정
| 요구사항 | 계획 Goal | 검증 |
|---|---|---|
| STOP-001, STOP-002 | `P1-T1` | `ChargeEventJobServiceTest` 신규 생성/활성 이벤트 회귀 |
| STOP-003, STOP-004 | `P1-T1`, `P1-GATE` | worker/admin 회귀, 충전 불변조건 테스트 |
| 날짜 | ID | 상태 | 결정 |
|---|---|---|---|
| 2026-10-19 | DEC-001 | 확정, 사용자 정책 | 첫 충전 보너스 신규 지급 중단, 생성된 작업은 기존대로 지급한다. |
| 2026-10-19 | DEC-002 | 기술 접근 | 신규 스냅샷 선택을 `buildActiveEventSnapshot`으로 단순화하고 기존 저장 작업 처리 경로는 유지한다. |
| 2026-10-19 | DEC-003 | 확정, 사용자 작업 조건 | worktree를 사용하지 않고 현재 `test` 브랜치에서 문서만 작성한다. |
| 2026-10-19 | DEC-004 | 정정, 사용자 구현 승인 | 문서대로 구현 진행 승인. `test` 브랜치/worktree 미사용 조건은 유지하며 신규 생성 분기와 관련 테스트만 변경한다. |
## 7. 성공 기준
- [x] 신규 작업 생성 테스트에서 `FIRST_CHARGE`가 생성되지 않는다.
- [x] 활성 이벤트가 있으면 신규 일반 이벤트 스냅샷만 생성되고, 이벤트 부재/한도 소진이면 작업 없이 종료한다.
- [x] PG, PAYVERSE, APPLE_IAP, GOOGLE_IAP의 기존 활성 이벤트 snapshot과 잔액/알림 계약이 유지된다.
- [x] 저장된 첫 충전 `PENDING`/`PROCESSING` 작업은 현재 방식대로 한 번 처리되고, `FAILED` 수동 재시도와 `DONE` 중복 방지가 유지된다.
- [x] 사용자 승인 이후 구현하고 focused 35개·전체 2,291개 테스트, build·ktlint와 격리 실행 QA 28개 시나리오를 통과했다. 운영 배포·실지급 확인은 별도다.