test #433

Merged
klaus merged 41 commits from test into main 2026-07-10 07:20:07 +00:00
2 changed files with 23 additions and 4 deletions
Showing only changes of commit c706c73b05 - Show all commits

View File

@@ -268,12 +268,31 @@
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/recommendation/application/HomeRecommendationQueryService.kt` - Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/recommendation/application/HomeRecommendationQueryService.kt`
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/recommendation/adapter/out/persistence/DefaultHomeRecommendationQueryRepository.kt` - Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/recommendation/adapter/out/persistence/DefaultHomeRecommendationQueryRepository.kt`
- Test: `src/test/kotlin/kr/co/vividnext/sodalive/v2/recommendation/application/HomeRecommendationQueryServiceTest.kt` - Test: `src/test/kotlin/kr/co/vividnext/sodalive/v2/recommendation/application/HomeRecommendationQueryServiceTest.kt`
- RED: 스냅샷 기준 AI 캐릭터 10개, AI 캐릭터 응답의 캐릭터 이름/소개/전체 채팅 수/오리지널 작품명 조건, 최근 응원 8명과 크리에이터 프로필 이미지/닉네임, 인기 커뮤니티 10개와 크리에이터 프로필 이미지/닉네임/UTC 시간/좋아요 수/댓글 수/커뮤니티 내용, 스냅샷 없음 빈 배열 테스트를 작성한다. - RED: 스냅샷 기준 AI 캐릭터 20개, AI 캐릭터 응답의 캐릭터 이름/소개/전체 채팅 수/오리지널 작품명 조건, 최근 응원 8명과 크리에이터 프로필 이미지/닉네임, 인기 커뮤니티 10개와 크리에이터 프로필 이미지/닉네임/UTC 시간/좋아요 수/댓글 수/커뮤니티 내용, 스냅샷 없음 빈 배열 테스트를 작성한다.
- 실패 확인: `./gradlew test --tests kr.co.vividnext.sodalive.v2.recommendation.application.HomeRecommendationQueryServiceTest` - 실패 확인: `./gradlew test --tests kr.co.vividnext.sodalive.v2.recommendation.application.HomeRecommendationQueryServiceTest`
- GREEN: `RecommendationSnapshotRepository`에서 최신 스냅샷을 읽고 대상 엔티티 상세 정보를 조립한다. AI 캐릭터 작품명은 오리지널 작품 캐릭터인 경우에만 채우고, 인기 커뮤니티는 스냅샷에 저장된 점수/랜덤 tie-breaker 순서를 유지한다. - GREEN: `RecommendationSnapshotRepository`에서 최신 스냅샷을 읽고 대상 엔티티 상세 정보를 조립한다. AI 캐릭터 작품명은 오리지널 작품 캐릭터인 경우에만 채우고, 인기 커뮤니티는 스냅샷에 저장된 점수/랜덤 tie-breaker 순서를 유지한다.
- REFACTOR: 비활성/노출 제한 캐릭터, 커뮤니티 비공개/유료/핀/성인 조건을 repository 조건으로 고정한다. - REFACTOR: 비활성/노출 제한 캐릭터, 커뮤니티 비공개/유료/핀/성인 조건을 repository 조건으로 고정한다.
- 기대 결과: AI 캐릭터 노출 필드가 PRD와 일치하고, 인기 커뮤니티는 크리에이터당 1개만 반환하며 동일 점수는 스냅샷 생성 시 저장한 랜덤 tie-breaker 기준으로 노출된다. - 기대 결과: AI 캐릭터 노출 필드가 PRD와 일치하고, 인기 커뮤니티는 크리에이터당 1개만 반환하며 동일 점수는 스냅샷 생성 시 저장한 랜덤 tie-breaker 기준으로 노출된다.
### Phase 9: AI 캐릭터 홈 노출 개수 20개 조정
- [x] **Task 9.1: 홈 추천 AI 캐릭터 기본 조회 개수 20개 적용**
- Files:
- Modify: `docs/20260529_메인_홈_추천_API/prd.md`
- Modify: `docs/20260529_메인_홈_추천_API/plan-task.md`
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/api/home/application/HomeRecommendationFacade.kt`
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/recommendation/application/HomeRecommendationQueryService.kt`
- Test: `src/test/kotlin/kr/co/vividnext/sodalive/v2/recommendation/application/HomeRecommendationQueryServiceTest.kt`
- RED: AI 캐릭터 추천 기본 조회가 최신 스냅샷 20개를 기준으로 상세 조회 id를 전달하는 테스트로 기존 10개 계약이 실패하도록 한다.
- 실패 확인: `./gradlew test --tests kr.co.vividnext.sodalive.v2.recommendation.application.HomeRecommendationQueryServiceTest`
- GREEN: 홈 통합 응답의 AI 캐릭터 limit과 service 기본 AI 캐릭터 limit을 20개로 변경한다. 스냅샷 저장 상한은 이미 20개이므로 변경하지 않는다.
- REFACTOR: PRD와 기존 Task 3.3의 AI 캐릭터 개수 문구를 20개로 맞추고, 전체보기 paging 기본 size 20 계약은 유지한다.
- 기대 결과: `GET /api/v2/home/recommendations``aiCharacters`가 최신 AI 캐릭터 스냅샷 기준 최대 20개까지 내려간다.
- 검증 기록:
- 2026-07-09: RED에서 `HomeRecommendationQueryServiceTest`의 AI 캐릭터 최신 스냅샷 기준 기대값을 20개로 변경했고, 기존 구현은 `DEFAULT_AI_CHARACTER_LIMIT = 10` 때문에 `HomeRecommendationQueryServiceTest > AI 캐릭터 추천은 최신 스냅샷 20개를 기준으로 순서를 유지해 상세를 조립한다`가 실패했다.
- 2026-07-09: GREEN에서 `HomeRecommendationFacade.HOME_AI_CHARACTER_LIMIT``HomeRecommendationQueryService.DEFAULT_AI_CHARACTER_LIMIT`를 20으로 변경하고, 홈 통합 응답이 AI 캐릭터를 최대 20개 반환하는 controller 테스트를 추가했다. `./gradlew test --tests kr.co.vividnext.sodalive.v2.recommendation.application.HomeRecommendationQueryServiceTest --tests kr.co.vividnext.sodalive.v2.api.home.HomeRecommendationControllerTest` 실행 결과 `BUILD SUCCESSFUL`로 통과했다.
- 2026-07-09: 회귀 검증으로 `./gradlew ktlintCheck``./gradlew tasks --all`을 실행해 모두 `BUILD SUCCESSFUL`로 통과했다. 두 명령은 최초 sandbox 실행에서 Gradle wrapper의 `~/.gradle` lock 파일 접근 권한 문제로 실패했고, 권한 상승 재실행으로 통과했다. `./gradlew :app:ktlintCheck`는 단일 루트 프로젝트에 `app` 프로젝트가 없어 실패했으며, 저장소 기준 명령인 `./gradlew ktlintCheck`로 대체 검증했다.
### Phase 4: 콘텐츠 조회 이력 기록 ### Phase 4: 콘텐츠 조회 이력 기록
- [x] **Task 4.1: 콘텐츠 조회 이력 엔티티/서비스 작성** - [x] **Task 4.1: 콘텐츠 조회 이력 엔티티/서비스 작성**

View File

@@ -72,7 +72,7 @@
- 방금 활동한 크리에이터: 10개 - 방금 활동한 크리에이터: 10개
- 최근 데뷔한 크리에이터: 10개 - 최근 데뷔한 크리에이터: 10개
- 처음부터 함께 성장: 10개 - 처음부터 함께 성장: 10개
- 크리에이터와 이야기를 나눠요: 10개 - 크리에이터와 이야기를 나눠요: 20개
- 장르의 크리에이터: 장르 최대 5개, 장르별 크리에이터 8명 - 장르의 크리에이터: 장르 최대 5개, 장르별 크리에이터 8명
- 최근 응원이 많은 크리에이터: 8명 - 최근 응원이 많은 크리에이터: 8명
- 인기 커뮤니티: 10개 - 인기 커뮤니티: 10개
@@ -162,7 +162,7 @@
#### Requirements #### Requirements
- AI 캐릭터 리스트를 조회한다. - AI 캐릭터 리스트를 조회한다.
- 홈 첫 화면은 10개를 조회한다. - 홈 첫 화면은 20개를 조회한다.
- 전체 리스트 API는 페이징으로 조회할 수 있어야 한다. - 전체 리스트 API는 페이징으로 조회할 수 있어야 한다.
- 노출 정보는 캐릭터 id, AI 캐릭터에 대응하는 creator id, 캐릭터 이름, 캐릭터 소개, 프로필 이미지, 작품명, 사용자들이 친 전체 채팅 수를 포함한다. - 노출 정보는 캐릭터 id, AI 캐릭터에 대응하는 creator id, 캐릭터 이름, 캐릭터 소개, 프로필 이미지, 작품명, 사용자들이 친 전체 채팅 수를 포함한다.
- AI 캐릭터에 대응하는 creator id는 `ChatCharacter.creatorMember.id`이며, 해당 Member는 `role = CREATOR`, `memberKind = AI_CHARACTER`인 내부 크리에이터 Member다. - AI 캐릭터에 대응하는 creator id는 `ChatCharacter.creatorMember.id`이며, 해당 Member는 `role = CREATOR`, `memberKind = AI_CHARACTER`인 내부 크리에이터 Member다.
@@ -279,7 +279,7 @@
- 일 1회 갱신 스냅샷은 후보를 application/service 메모리로 모두 불러와 점수를 계산하지 않는다. DB 조회에서 모든 적격 후보의 최종 점수와 랜덤 tie-breaker를 계산한 뒤 `score desc, randomTieBreaker asc` 기준으로 정렬하고, 그 이후에만 최종 저장 개수 limit을 적용한다. - 일 1회 갱신 스냅샷은 후보를 application/service 메모리로 모두 불러와 점수를 계산하지 않는다. DB 조회에서 모든 적격 후보의 최종 점수와 랜덤 tie-breaker를 계산한 뒤 `score desc, randomTieBreaker asc` 기준으로 정렬하고, 그 이후에만 최종 저장 개수 limit을 적용한다.
- 최종 점수 계산 전 candidate pre-limit, 랜덤 후보 컷오프, 임의 2배수 선제 제한은 정확한 top 후보를 누락할 수 있으므로 금지한다. - 최종 점수 계산 전 candidate pre-limit, 랜덤 후보 컷오프, 임의 2배수 선제 제한은 정확한 top 후보를 누락할 수 있으므로 금지한다.
- DB score expression과 Kotlin `RecommendationScorePolicy`는 동일한 `RecommendationScoreSpec`의 가중치/부스트 구간 상수를 공유해 산식 drift를 방지한다. - DB score expression과 Kotlin `RecommendationScorePolicy`는 동일한 `RecommendationScoreSpec`의 가중치/부스트 구간 상수를 공유해 산식 drift를 방지한다.
- 스냅샷 최종 저장 개수는 동점자 랜덤 노출 여지를 확보하기 위해 홈 첫 화면 노출 수의 2배인 AI 캐릭터 최대 20개, 최근 응원이 많은 크리에이터 최대 16개, 인기 커뮤니티 최대 20개로 한다. 단, 이 숫자는 최종 점수 계산과 동점 랜덤 정렬 이후 적용하는 저장 limit이며 candidate pre-limit가 아니다. - 스냅샷 최종 저장 개수는 AI 캐릭터 홈 첫 화면 20개 안정 노출을 위해 AI 캐릭터 최대 20개, 동점자 랜덤 노출 여지를 확보하기 위해 최근 응원이 많은 크리에이터 최대 16개, 인기 커뮤니티 최대 20개로 한다. 단, 이 숫자는 최종 점수 계산과 동점 랜덤 정렬 이후 적용하는 저장 limit이며 candidate pre-limit가 아니다.
- 공개 시간은 UTC 기준 응답을 원칙으로 한다. - 공개 시간은 UTC 기준 응답을 원칙으로 한다.
- 응답 DTO의 enum 값은 앱 다국어 처리를 위해 안정적인 영문 code로 내려준다. - 응답 DTO의 enum 값은 앱 다국어 처리를 위해 안정적인 영문 code로 내려준다.
- 기존 API 스키마는 변경하지 않고 신규 v2 endpoint로 분리한다. - 기존 API 스키마는 변경하지 않고 신규 v2 endpoint로 분리한다.