diff --git a/docs/20260918_캔조회_회원2_강제통화제거/plan-task.md b/docs/20260918_캔조회_회원2_강제통화제거/plan-task.md new file mode 100644 index 00000000..ae26a949 --- /dev/null +++ b/docs/20260918_캔조회_회원2_강제통화제거/plan-task.md @@ -0,0 +1,62 @@ +# 캔 조회 회원 2 강제 통화 제거 구현 계획 + +- 상태: 구현 완료 +- 작성일: 2026-09-18 +- 요구사항: [prd.md](prd.md) +- 현재 Phase: 1 완료 +- 활성 Goal: 없음 +- 실행 순서: CAN-P1-T1 → CAN-P1-GATE + +### Phase 1: 회원 2의 기본 통화 적용과 회귀 확인 + +- [x] **Task 1.1: 회원 2의 강제 통화 제거** (`CAN-P1-T1`) + - Objective: 회원 2가 다른 일반 회원처럼 요청 국가에 따른 통화의 캔 상품을 조회한다. + - 시작 조건: PRD 확정, 기존 컨트롤러·서비스 및 테스트 확인 완료. + - 완료 증거: RED/GREEN 결과, 실제 컨트롤러·서비스·저장소 통합 테스트와 캔 패키지 회귀 통과. + - 범위 밖: 다른 회원 예외 제거, 국가 결정·API 스키마·서비스 리팩터링. + - 수정: `src/main/kotlin/kr/co/vividnext/sodalive/can/CanController.kt` + - 생성: `src/test/kotlin/kr/co/vividnext/sodalive/can/CanControllerIntegrationTest.kt` + - 확인: `src/main/kotlin/kr/co/vividnext/sodalive/can/CanService.kt`, `src/test/kotlin/kr/co/vividnext/sodalive/can/CanServiceTest.kt` + - [x] **RED:** 회원 2의 KRW/USD, 유지할 예외·일반 회원·비로그인·국가 누락 통합 테스트를 작성한다. + - [x] **RED 확인:** `./gradlew test --tests 'kr.co.vividnext.sodalive.can.CanControllerIntegrationTest'`로 회원 2의 JPY 반환 assertion 실패를 확인한다. + - [x] **GREEN:** 컨트롤러 조건에서 `member.id == 2L ||`만 제거한다. + - [x] **GREEN 확인:** 동일 focused test가 통과하는지 확인한다. + - [x] **REFACTOR:** 불필요한 정리 없이 `./gradlew test --tests 'kr.co.vividnext.sodalive.can.*'` 및 변경 파일 lint로 회귀를 확인한다. + +#### Task 검증 기록 +- 2026-09-18: 기존 `getCans` 및 `/can` 직접 테스트가 없음을 확인했다. 새 테스트는 `@SpringBootTest`와 H2, 요청 범위의 실제 CountryContext를 사용하고 트랜잭션 롤백으로 상품 데이터를 격리한다. +- 2026-09-18 RED: 테스트 작성 중 `Member.password` 필수 인자 누락을 수정한 뒤 production/test 컴파일이 통과했다. 이후 공통 JWT 기본 키의 길이 부족으로 발생한 컨텍스트 로딩 실패는 테스트 실행에만 임시 키를 제공하여 해결했다. 이 두 실패는 동작 RED에 포함하지 않았다. +- 2026-09-18 RED 확인: 아래 환경 설정 후 `./gradlew test --tests 'kr.co.vividnext.sodalive.can.CanControllerIntegrationTest' --console=plain` 실행. 13개 중 회원 2의 4개만 assertion 실패(exit 1): KR은 KRW, US/JP/국가 누락은 USD 기대였으나 실제 JPY. 나머지 9개 통과. +- 2026-09-18 GREEN 확인: 조건 제거 후 같은 focused 명령으로 13개 전부 통과(exit 0), production/test 컴파일 성공. +- 2026-09-18 회귀 확인: `./gradlew test --tests 'kr.co.vividnext.sodalive.can.*' --console=plain` 성공(exit 0). 신규 13개와 기존 14개, 총 5개 클래스 27개 테스트 통과(실패·오류·skip 0). 기존 테스트를 완화하거나 수정할 필요가 없었다. + +- [x] **Phase Gate: 변경 범위와 검증 기록 확인** (`CAN-P1-GATE`) + - Objective: 요구사항과 최소 변경, 검증 증거가 일치함을 확인한다. + - 시작 조건: CAN-P1-T1 완료. + - 완료 증거: 캔 패키지 테스트 통과, 문서 명령·diff 확인 및 PRD 체크박스 완료. + - 범위 밖: 전체 서비스 실행과 관련 없는 기능 수정. + - 확인 파일: 이 문서, `docs/20260918_캔조회_회원2_강제통화제거/prd.md`, 위 Task의 코드·테스트. + - TDD 예외 사유: 구현 없는 최종 검증 단계. + - 대체 검증 방법: `./gradlew tasks --all`, `git diff --check`, 변경 파일 대조. + +## 검증 범위 +- 단일 루트 프로젝트이며 변경은 컨트롤러의 조건 하나에 한정된다. 전체 회귀 실행 조건(공통 코드·여러 도메인 변경·영향 불명확 실패·사용자 명시 요청)이 발생하지 않으면 전체 테스트는 생략하고 캔 패키지 전체를 실행한다. +- 테스트 실행으로 production/test 컴파일을 함께 확인한다. 새 API나 실행 환경 변경이 없어 별도 애플리케이션 구동은 하지 않는다. + +## Progress +- 2026-09-18: 요구사항 및 TDD 계획 작성, CAN-P1-T1 준비. +- 2026-09-18: CAN-P1-T1 RED 확인 완료, 회원 2 조건 제거 진행. +- 2026-09-18: CAN-P1-T1 완료. 조건 한 항만 제거했고 신규 13개 및 기존 14개 테스트가 통과했다. +- 2026-09-18: CAN-P1-GATE 완료. API 스키마·다른 회원 예외가 유지되는 diff와 PRD 수용 기준, 검증 기록을 대조했다. 남은 작업 없음. + +## 공통 검증 기록 +- 셸에 기본 Java가 없어 기존 Gradle 캐시의 Java 17을 사용했다. 설정 파일은 변경하지 않았다. +- 테스트 JWT 기본값은 디코딩 후 키 길이가 부족하므로 실행 프로세스에만 임시 키를 전달했다. 키 값은 저장·출력하지 않는다. 아래 환경 설정 뒤 문서의 검증 명령을 실행한다. + +```bash +export JAVA_HOME=~/.gradle/jdks/eclipse_adoptium-17-x86_64-os_x.2/jdk-17.0.19+10/Contents/Home +export JWT_SECRET="$(openssl rand -base64 64 | tr -d '\n')" +``` + +- 2026-09-18: `./gradlew tasks --all --console=plain`, `git diff --check` 성공(exit 0). 변경 Kotlin 파일의 IDE 정적 검사에서 오류 없음. 신규 테스트는 경고도 없으며 기존 컨트롤러의 수정하지 않은 인증 SpEL 식에는 변수 해석 경고 8개가 있다. +- 2026-09-18: 전체 테스트·전체 ktlint 및 별도 서버 실행은 생략했다. 변경은 컨트롤러 조건 한 곳이고 다른 도메인·공통 코드·하위 모듈 변경이 없어 focused 통합 테스트, 캔 패키지 전체 회귀, 변경 파일 정적 검사로 검증했다. diff --git a/docs/20260918_캔조회_회원2_강제통화제거/prd.md b/docs/20260918_캔조회_회원2_강제통화제거/prd.md new file mode 100644 index 00000000..6a499db9 --- /dev/null +++ b/docs/20260918_캔조회_회원2_강제통화제거/prd.md @@ -0,0 +1,27 @@ +# 캔 조회 회원 2 강제 통화 제거 + +## 문서 정보 +- 상태: 구현 완료 +- 작성일: 2026-09-18 +- 관련 계획: [plan-task.md](plan-task.md) + +## 문제와 목표 +`GET /can`의 `getCans`는 회원 2·4·44144에게 JPY를 강제 적용한다. +사용자 요청에 따라 회원 2만 제외하여 기존 국가별 통화 선택을 따르게 한다. + +## 확정 요구사항과 수용 기준 +| ID | 요구사항 | 수용 기준 | Goal | +|---|---|---|---| +| CAN-CURRENCY-001 | 회원 2의 JPY 강제 조건 제거 | KR 요청은 KRW, 그 외 국가는 USD 상품 반환 | CAN-P1-T1 | +| CAN-CURRENCY-002 | 나머지 동작 유지 | 회원 4·44144는 JPY, 일반 회원·비로그인은 기존 국가별 통화 적용 | CAN-P1-T1 | +| CAN-CURRENCY-003 | 관련 테스트 검증 | 변경 전 실패 재현, 변경 후 캔 패키지 테스트 통과 | CAN-P1-GATE | + +## 범위 밖 +- 다른 진입점의 회원 ID 조건, 국가 판정 및 성인콘텐츠 정책 변경. +- 서비스의 KR → KRW / 그 외 → USD 정책 변경. +- 공개 API 요청·응답 스키마, 인증 및 상품 판매 상태 필터 변경. + +## 성공 기준 +- [x] 회원 2에 대한 회귀 테스트가 변경 전 실패하고 변경 후 통과한다. +- [x] 회원 4·44144, 일반 회원, 비로그인 및 국가 누락의 기존 동작이 유지된다. +- [x] 관련 기존 테스트가 통과하고 검증 결과를 계획 문서에 기록한다.