From 4d7695840927a679813237e8fb68d1fc3e279071 Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 24 Jun 2026 16:24:00 +0900 Subject: [PATCH] =?UTF-8?q?docs(content-ranking):=20=EB=9E=AD=ED=82=B9=20?= =?UTF-8?q?=EC=8A=A4=EB=83=85=EC=83=B7=20=EC=9A=94=EA=B5=AC=EC=82=AC?= =?UTF-8?q?=ED=95=AD=EC=9D=84=20=EA=B0=B1=EC=8B=A0=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/20260623_메인_콘텐츠_랭킹_탭_API/prd.md | 23 ++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/20260623_메인_콘텐츠_랭킹_탭_API/prd.md b/docs/20260623_메인_콘텐츠_랭킹_탭_API/prd.md index a96f627f..6b2cce8e 100644 --- a/docs/20260623_메인_콘텐츠_랭킹_탭_API/prd.md +++ b/docs/20260623_메인_콘텐츠_랭킹_탭_API/prd.md @@ -8,9 +8,9 @@ --- ## 2. Problem -- 기존 콘텐츠 랭킹 조회는 `RankingService.getContentRanking` 기반의 정렬 조회를 제공하지만, 신규 랭킹 탭은 `rank`, `rankChange`, `isNew`를 크리에이터 랭킹과 같은 의미로 내려줘야 한다. +- 기존 콘텐츠 랭킹 조회는 `RankingService.getContentRanking` 기반의 정렬 조회를 제공하지만, 신규 랭킹 탭은 v2 스냅샷 기준으로 `rank`, `rankChange`, `isNew`를 크리에이터 랭킹과 같은 의미로 내려줘야 한다. - `주간 인기`와 `지금 뜨는 중`은 신규 점수 산식, 유료/무료 콘텐츠별 정규화, 주간 스냅샷 갱신, fallback 실행 기록이 필요하다. -- `매출`, `판매량`, `댓글 수`, `좋아요`는 기존 랭킹 산식을 재사용할 수 있지만, 순위 변화와 신규 진입 여부를 안정적으로 계산하려면 최신 완료 주차와 직전 완료 주차의 결과가 필요하다. +- `매출`, `판매량`, `댓글 수`, `좋아요`는 기존 랭킹과 동일한 원천 지표를 사용하되, 순위 변화와 신규 진입 여부를 안정적으로 계산하려면 v2 스냅샷 생성 시점에 완료 주차 기준으로 직접 집계해야 한다. - 조회 시마다 모든 랭킹 타입의 원천 데이터를 집계하면 응답 지연과 계산 중복이 커지고, 운영 서버와 테스트 환경에서 같은 기준의 결과를 재현하기 어렵다. - 기존 v2 패키지에 크리에이터 랭킹 스냅샷/작업 이력/fallback 패턴과 콘텐츠 추천 탭의 API 조립 계층/도메인 조회 계층 분리 패턴이 있으므로 이를 우선 재사용해야 한다. @@ -35,7 +35,7 @@ ## 4. Non-Goals - 기존 공개 API 스키마를 임의 변경하지 않는다. -- 기존 `RankingService.getContentRanking`의 정렬 산식을 이번 작업에서 재정의하지 않는다. +- 기존 공개 API의 `RankingService.getContentRanking` 동작과 정렬 산식은 이번 작업에서 변경하지 않는다. - 관리자 화면, 수동 보정 기능, 랭킹 결과 고정/제외 기능은 포함하지 않는다. - 개인화 랭킹, A/B 테스트, 머신러닝 기반 점수 산정은 포함하지 않는다. - 20위 이후 전체보기/페이징 API는 이번 요구사항에 포함하지 않는다. @@ -174,22 +174,23 @@ ### Feature E. 매출, 판매량, 댓글 수, 좋아요 랭킹 #### Requirements -- `REVENUE`, `SALES_COUNT`, `COMMENT_COUNT`, `LIKE_COUNT`는 기존 `RankingService.getContentRanking` 및 `ContentRankingSortType`의 정렬 기준을 재사용한다. -- 신규 v2 도메인 조회 계층에서는 기존 서비스를 직접 노출하지 않고 adapter 또는 port 경계를 통해 필요한 결과만 가져온다. +- `REVENUE`, `SALES_COUNT`, `COMMENT_COUNT`, `LIKE_COUNT`는 v2 스냅샷 생성 계층에서 완료 주차 기준으로 직접 집계한다. +- 각 타입의 최종 점수는 원천 지표를 그대로 사용한다. `REVENUE`는 매출 can 합계, `SALES_COUNT`는 판매 건수, `COMMENT_COUNT`는 활성 댓글 수, `LIKE_COUNT`는 활성 좋아요 수다. - 각 랭킹 타입도 스냅샷으로 저장한다. -- 스냅샷 생성 시 기존 정렬 결과를 기반으로 최대 20개 콘텐츠의 순위와 표시 정보를 저장한다. -- 동점자는 `releaseDate desc`, `contentId desc` 순으로 정렬되도록 기존 쿼리 또는 v2 adapter에서 보강한다. +- 스냅샷 생성 시 v2 집계 결과를 기반으로 전체 기준 상위 20개와 비성인 콘텐츠 기준 상위 20개의 합집합 후보를 저장한다. +- 공개 응답은 조회자의 성인 콘텐츠 열람 가능 여부를 적용한 뒤 최대 20개 콘텐츠를 반환한다. +- 동점자는 `releaseDate desc`, `contentId desc` 순으로 정렬한다. - 최종 응답의 `rank`, `rankChange`, `isNew` 계산은 `주간 인기`, `지금 뜨는 중`과 동일한 공통 로직을 사용한다. #### 스냅샷 저장 판단 - 이번 PRD의 기준안은 모든 랭킹 타입을 스냅샷으로 저장하는 것이다. - 이유는 `rankChange`와 `isNew`가 모든 응답 item에 필요하고, 이 값은 최신 완료 주차와 직전 완료 주차의 같은 랭킹 타입 결과를 비교해야 안정적으로 계산할 수 있기 때문이다. - `주간 인기`와 `지금 뜨는 중`만 스냅샷으로 저장하면 `매출`, `판매량`, `댓글 수`, `좋아요`는 조회 때마다 최신/직전 주차를 동적으로 재계산해야 하며, 계산 비용과 late update에 따른 순위 흔들림이 생긴다. -- 기존 산식을 재사용하는 4개 랭킹도 스냅샷 생성 시점에는 기존 `RankingService.getContentRanking`을 활용할 수 있으므로 구현 부담은 낮고, 조회 API는 모든 랭킹 타입에 동일한 경로를 사용할 수 있다. +- 기존 랭킹과 같은 원천 지표를 사용하는 4개 랭킹도 v2 스냅샷 생성 시점에 직접 집계해, legacy 조회 조건과 v2 공개/제외 조건이 섞이지 않도록 한다. #### Edge Cases -- 기존 랭킹 조회 결과가 20개 미만이면 해당 개수만 스냅샷으로 저장한다. -- 기존 랭킹 조회에서 최소 개수 확보를 위해 과거 기간으로 조회 기간을 확장하는 로직이 있다면, 스냅샷 생성 기준에서는 이번 랭킹 탭의 완료 주차 기준과 충돌하지 않는지 구현 계획 단계에서 확인한다. +- v2 집계 결과 또는 조회자에게 노출 가능한 후보가 20개 미만이면 해당 개수만 저장/응답한다. +- legacy 랭킹 조회의 최소 개수 확보용 기간 확장 로직은 v2 스냅샷 생성에 적용하지 않는다. ### Feature F. 랭킹 스냅샷 및 작업 이력 @@ -250,7 +251,7 @@ - 주간 기간 계산, UTC 변환, Redisson lock은 `v2/ranking/domain/CreatorRankingPeriodPolicy`와 크리에이터 랭킹 스냅샷 job 구조를 재사용하거나 콘텐츠 랭킹용으로 동일 패턴을 만든다. - 상세 페이지 조회수는 `v2/recommendation/adapter/out/persistence/CreatorContentViewHistory`와 관련 port/repository를 재사용 후보로 검토한다. - CDN URL 조립은 `v2/common/domain/CdnUrlExtensions.kt`의 `toCdnUrl` 패턴을 우선 사용한다. -- `REVENUE`, `SALES_COUNT`, `COMMENT_COUNT`, `LIKE_COUNT`는 기존 `RankingService.getContentRanking`을 legacy adapter로 감싸 재사용하는 방향을 우선 검토한다. +- `REVENUE`, `SALES_COUNT`, `COMMENT_COUNT`, `LIKE_COUNT`는 legacy adapter를 사용하지 않고 v2 집계 repository에서 직접 후보를 만든다. ---