docs(home): 메인 홈 추천 스냅샷 요구사항을 보강한다
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
- 전체보기 요구가 있는 섹션은 별도 리스트 API로 페이징 조회할 수 있다.
|
||||
- 홈 배너는 기존 콘텐츠 홈 배너 데이터를 재활용한다.
|
||||
- 점수 기반 섹션은 요구된 산식, 기간, 신규 부스트를 반영한다.
|
||||
- 일 1회 갱신 섹션은 매일 00:00에 전날 23:59:59 기준 데이터로 계산된 결과를 사용한다.
|
||||
- 일 1회 갱신 섹션은 KST 매일 06:00에 전날 23:59:59 KST 기준 데이터로 계산된 결과를 사용한다. 서버 스케줄러 cron은 `Asia/Seoul` zone의 KST 06:00으로 등록한다.
|
||||
- 시간 응답은 UTC 기준으로 내려주고 앱에서 표시 포맷과 다국어를 처리한다.
|
||||
- 장르 기반 크리에이터 추천을 위해 콘텐츠 조회 이력 기록 방식을 도입한다.
|
||||
- 여러 크리에이터를 동시에 팔로우하는 API를 제공한다.
|
||||
@@ -167,10 +167,13 @@
|
||||
- 작품명은 오리지널 작품 캐릭터인 경우에만 내려준다.
|
||||
- 1차 정렬은 AI 채팅 추천 점수 내림차순이다.
|
||||
- 2차 정렬은 동일 점수인 경우 랜덤이다.
|
||||
- AI 채팅 추천 점수는 `((0.45 * 최근 발생한 AI 채팅 수) + (0.35 * 최근 활성 사용자 수) + (0.20 * 팔로우 증가량)) * 신규 부스트`로 계산한다.
|
||||
- 최근 발생한 AI 채팅 수, 최근 활성 사용자 수, 팔로우 증가량은 최근 7일 데이터 기반으로 계산한다.
|
||||
- AI 채팅 추천 점수는 이번 스프린트에서 `((0.45 * 최근 발생한 AI 채팅 수) + (0.35 * 최근 활성 사용자 수)) * 신규 부스트`로 계산한다.
|
||||
- 최근 발생한 AI 채팅 수와 최근 활성 사용자 수는 최근 7일 데이터 기반으로 계산한다.
|
||||
- 최근 발생한 AI 채팅 수는 AI 캐릭터가 발화한 채팅 메시지 수를 의미한다.
|
||||
- 최근 활성 사용자 수는 최근 7일 안에 해당 AI 캐릭터와 1회 이상 채팅한 중복 없는 사용자 수를 의미한다.
|
||||
- AI 캐릭터의 팔로우 증가량은 팔로우 대상/관계의 정확한 정의가 확정되지 않아 이번 스프린트 산식과 집계에서 제외한다. 추후 AI 캐릭터 팔로우 정의가 확정되면 별도 요구사항으로 재도입한다.
|
||||
- 신규 부스트는 캐릭터 생성일 기준 10일 이내 1.5, 20일 이내 1.3, 30일 이내 1.2, 그 외 1을 적용한다.
|
||||
- 점수는 매일 00:00에 전날 23:59:59 기준 데이터로 1회 갱신한다.
|
||||
- 점수는 KST 매일 06:00에 전날 23:59:59 KST 기준 데이터로 1회 갱신한다. 스케줄러는 `Asia/Seoul` zone의 KST 06:00 기준으로 실행한다.
|
||||
|
||||
#### Edge Cases
|
||||
- 비활성 또는 노출 제한 캐릭터는 제외한다.
|
||||
@@ -209,10 +212,12 @@
|
||||
- 응원 점수가 높은 크리에이터 8명을 조회한다.
|
||||
- 노출 정보는 크리에이터 프로필 이미지, 크리에이터 닉네임을 포함한다.
|
||||
- 응원 점수는 `((0.6 * 후원 금액) + (0.3 * 팬 Talk 수) + (0.1 * 후원 수)) * 신규 부스트`로 계산한다.
|
||||
- 후원 금액과 후원 수는 `CanUsage.CHANNEL_DONATION` 데이터만 대상으로 계산한다.
|
||||
- 팬톡은 기존 `CreatorCheers`를 의미한다.
|
||||
- 점수는 최근 7일 데이터를 기반으로 계산한다.
|
||||
- 신규 부스트는 데뷔 후 10일 이내 1.5, 20일 이내 1.3, 30일 이내 1.2, 그 외 1을 적용한다.
|
||||
- 점수는 매일 00:00에 전날 23:59:59 기준 데이터로 1회 갱신한다.
|
||||
- 신규 부스트의 데뷔일은 `Member.createdAt`이 아니라 콘텐츠를 처음 공개한 날과 라이브를 한 날 중 빠른 날짜로 계산한다.
|
||||
- 점수는 KST 매일 06:00에 전날 23:59:59 KST 기준 데이터로 1회 갱신한다. 스케줄러는 `Asia/Seoul` zone의 KST 06:00 기준으로 실행한다.
|
||||
|
||||
### Feature K. 인기 커뮤니티
|
||||
|
||||
@@ -225,11 +230,12 @@
|
||||
- 유료 커뮤니티 게시글은 제외한다.
|
||||
- 핀으로 고정한 커뮤니티 게시글은 제외한다.
|
||||
- 성인 속성을 가진 커뮤니티 게시글은 기존 노출 조건과 동일하게 `MemberContentPreference.isAdultContentVisible == true`인 회원에게만 노출한다.
|
||||
- 동일 점수의 경우 최근 게시글을 우선 노출한다.
|
||||
- 동일 점수의 경우 스냅샷 생성 시 저장한 랜덤 tie-breaker 기준으로 노출한다.
|
||||
- 커뮤니티 인기 점수는 `((0.5 * 좋아요 수) + (0.5 * 댓글 수) + (0.1 * 팔로우 수)) * 신규 부스트`로 계산한다.
|
||||
- 점수는 최근 7일 데이터를 기반으로 계산한다.
|
||||
- 신규 부스트는 데뷔 후 10일 이내 1.5, 20일 이내 1.3, 30일 이내 1.2, 그 외 1을 적용한다.
|
||||
- 점수는 매일 00:00에 전날 23:59:59 기준 데이터로 1회 갱신한다.
|
||||
- 신규 부스트의 데뷔일은 `Member.createdAt`이 아니라 콘텐츠를 처음 공개한 날과 라이브를 한 날 중 빠른 날짜로 계산한다.
|
||||
- 점수는 KST 매일 06:00에 전날 23:59:59 KST 기준 데이터로 1회 갱신한다. 스케줄러는 `Asia/Seoul` zone의 KST 06:00 기준으로 실행한다.
|
||||
|
||||
#### Edge Cases
|
||||
- 댓글 불가 게시글도 댓글 수 0으로 점수 계산 대상에 포함한다.
|
||||
@@ -254,6 +260,10 @@
|
||||
- 커뮤니티 게시글 조회에는 비공개 제외, 유료 글 제외, 핀 고정 글 제외, 성인 노출 조건(`MemberContentPreference.isAdultContentVisible`)을 공통 적용한다.
|
||||
- 일 1회 갱신 섹션은 조회 시점마다 무거운 집계를 하지 않도록 집계 테이블 또는 스냅샷 엔티티를 신규로 둔다.
|
||||
- 랜덤 정렬이 필요한 섹션은 성능을 고려해 후보군 축소 후 랜덤화하거나 스냅샷 생성 시 랜덤 tie-breaker 값을 저장한다.
|
||||
- 일 1회 갱신 스냅샷은 후보를 application/service 메모리로 모두 불러와 점수를 계산하지 않는다. DB 조회에서 모든 적격 후보의 최종 점수와 랜덤 tie-breaker를 계산한 뒤 `score desc, randomTieBreaker asc` 기준으로 정렬하고, 그 이후에만 최종 저장 개수 limit을 적용한다.
|
||||
- 최종 점수 계산 전 candidate pre-limit, 랜덤 후보 컷오프, 임의 2배수 선제 제한은 정확한 top 후보를 누락할 수 있으므로 금지한다.
|
||||
- DB score expression과 Kotlin `RecommendationScorePolicy`는 동일한 `RecommendationScoreSpec`의 가중치/부스트 구간 상수를 공유해 산식 drift를 방지한다.
|
||||
- 스냅샷 최종 저장 개수는 동점자 랜덤 노출 여지를 확보하기 위해 홈 첫 화면 노출 수의 2배인 AI 캐릭터 최대 20개, 최근 응원이 많은 크리에이터 최대 16개, 인기 커뮤니티 최대 20개로 한다. 단, 이 숫자는 최종 점수 계산과 동점 랜덤 정렬 이후 적용하는 저장 limit이며 candidate pre-limit가 아니다.
|
||||
- 공개 시간은 UTC 기준 응답을 원칙으로 한다.
|
||||
- 응답 DTO의 enum 값은 앱 다국어 처리를 위해 안정적인 영문 code로 내려준다.
|
||||
- 기존 API 스키마는 변경하지 않고 신규 v2 endpoint로 분리한다.
|
||||
@@ -272,8 +282,9 @@
|
||||
|
||||
---
|
||||
|
||||
## 10. Open Questions
|
||||
- 전체보기 API의 세부 URL과 페이지 방식은 구현 계획에서 확정한다.
|
||||
## 10. Decisions
|
||||
- 실제 데뷔일을 계산할 첫 공개 콘텐츠와 첫 라이브가 모두 없는 크리에이터는 Phase 2 스냅샷 후보에서 제외한다.
|
||||
- Phase 2 점수 기반 스냅샷은 DB-side exact scoring으로 계산한다. service는 기준 시각 계산과 snapshot replace만 담당하고, 최종 점수 산식/정렬/limit은 repository query에서 처리한다.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user