본문으로 건너뛰기

인기 정책 문서

(2026년 4월 20일 updated)

1. 목적​

사용자의 콘텐츠 소비 데이터를 기반으로 가장 인기 있는 도서를 스티커 리워드 기반으로 보여주는 '인기' 탭의 구성과 동작 방식을 정의한다. 인기 콘텐츠, 개인화된 미보유 스티커, 향후 공개될 스티커 정보를 한 화면에서 제공하여 탐색 경험과 리워드 동기를 강화한다.


2. 진입 및 기본 구성​

  • 진입 위치: 하단 GNB의 [인기] 탭 클릭 시

  • 기본 구조: 3개의 스티커 기반 서브탭으로 구성된 세로 스크롤 화면

    • 인기 스티커
    • 나만 없는 스티커
    • 공개 예정 스티커
  • 탭 전환 방식: 사용자가 스크롤을 내리면 순차적으로 자동 전환되는 앵커 기반 구조, 자동 전환시 햅틱 피드백 제공

  • 탭 이동 기준: 각 영역 진입 시점 (스크롤 위치 기준 자동 전환)


3. 스티커 기본 모델​

3.1 Sticker 모델​

필드타입설명
nameTranslatedField다국어 스티커 이름
episodeOneToOneField연결된 에피소드 (1:1)
image_urlURLField스티커 이미지 URL
base_scoreFloatField사전 계산된 기본 점수 (크론 업데이트)
score_updated_atDateTimeField점수 최종 업데이트 시각

3.2 스티커 기본 점수 산정 (base_score)​

스티커의 기본 점수는 다음 요소를 합산하여 크론 작업(매 5분, precalculate_sticker_scores)으로 갱신된다.

요소가중치 / 공식설명
신규 스티커max(0, 3.0 × (1 − days_since_created/30))출시일 기준 30일 선형 감쇠
최근 7일 수집+0.5 × count_7d즉각 트렌딩 신호 (raw count)
최근 30일 인기도log10(1 + collectors_30d) × 3트렌딩 윈도우 인기 (log 압축)
캠페인 연계+2 (StickerCampaign.priority_boost)활성 캠페인에 포함 시 (선택, 모델 도입 시)
어제 노출 패널티−2 (StickerExposure 7일 내)다양성 확보용 (선택, 모델 도입 시)

산정 공식:

base_score = (
new_decay_bonus(created_at, 30d, max=3.0) # 신규 부스트 (선형 감쇠)
+ recent_7d_collections * 0.5 # 즉각 트렌딩
+ log10(1 + collectors_30d) * 3.0 # 트렌딩 인기도 (log 압축)
)

가중치 (StickerScoreConfig):

상수값비고
NEW_STICKER_MAX_BONUS3.0day 0 → +3
NEW_STICKER_DECAY_DAYS30day 30 → 0
RECENT_COLLECTION_WEIGHT0.57일 raw count
RECENT_COLLECTION_DAYS7
TRENDING_LOG_WEIGHT3.0log 가중치
TRENDING_WINDOW_DAYS30트렌딩 윈도우

4. 탭별 정책​

4.1 인기 스티커​

4.1.1 노출 데이터 소스​

Sticker.base_score 컬럼(매 5분 cron 갱신)을 직접 정렬 기준으로 사용한다.

출처 필드타입설명
Sticker.base_scoreFloatField (db_index)사전 계산된 점수 (3.2 산정 공식)
Sticker.score_updated_atDateTimeField점수 최종 갱신 시각
UserSticker.earned_atDateTimeField정렬 tie-breaker (30일 윈도우 collectors)

period(daily/weekly/monthly) 또는 country별 분리 노출이 필요해지면 별도 StickersPopular 사전 집계 테이블 도입.

4.1.2 정렬 및 노출​

  • 정의: base_score(3.2 공식)가 가장 높은 스티커 상위 10개 도서 노출
  • 정렬 기준 (결정적):
    ORDER BY base_score DESC, collectors_30d DESC, created_at DESC, id ASC
    • 1차: base_score
    • 2차: 최근 30일 collectors
    • 3차: 최신 콘텐츠 우선
    • 4차: id
  • 갱신 주기: 매 5분 cron (precalculate_sticker_scores)
  • 노출 개수: 최대 10개 (Top 3 도서는 가로 와이드 카드 강조, 이후 4~10번은 카드 그리드형)

4.1.3 API​

항목내용
목록 조회GET /api/stickers/popular/
디버그 조회GET /api/stickers/popular/debug/<id>/
설명기간별/국가별 인기 스티커 목록 및 개별 점수 상세 확인

4.1.4 UI 구성​

  • 카드 전체 클릭 시 도서 상세 이동
  • CTA 버튼은 없이, 배지로 상태 표현
    • 스티커 받기 가능
    • 획득 완료

4.2 나만 없는 스티커​

4.2.1 모델 (StickersMissing)​

필드타입설명
userForeignKey대상 사용자
stickerForeignKey미보유 스티커
positionIntegerField노출 순서

4.2.2 노출 패널티 (StickerExposure) — 미구현​

사용자에게 이미 노출된 스티커에 대해 점수를 감산하여 다양한 스티커가 노출되도록 한다.

필드타입설명
userForeignKey대상 사용자
stickerForeignKey노출된 스티커
exposure_typeCharField노출 영역: popular / missing
exposed_atDateTimeField노출 시각
  • 패널티 규칙: 최근 7일 내 Popular/Missing 영역에서 노출된 스티커에 -2점 적용
  • 유니크 조건: 동일 유저-스티커-타입 조합은 하나만 유지 (exposed_at만 갱신)

4.2.3 정렬 및 노출​

  • 정의: 사용자가 아직 수집하지 못한 스티커 중 인기 콘텐츠를 선별해 제공
  • 정렬 기준:
    • 인기 스티커 Top 10 제외
    • 사용자 미보유 스티커 중 최근 열람/찜 기록 기반 테마 우선 정렬
  • 노출 개수: 최대 6개 (2열 카드형)
  • 카드 구조 및 배지 정책: 인기 스티커와 동일
  • 중복 콘텐츠 회피: 인기 탭에서 이미 본 제외되며, 그래도 동일 도서가 나올 경우 우선순위 후순위 배치

4.2.4 테마 정렬 우선순위: 테마 기반 개인화 정렬 정책​

아래 항목을 조합하여 **개인화 테마 점수(score)**를 계산하고, 이를 기준으로 우선 정렬함.

우선 항목기준점수 예시
최근 열람 도서의 테마 태그최근 7일 내 열람 도서가 포함한 theme_tag+3점
최근 북마크 도서의 테마 태그최근 30일 내 찜한 도서가 포함한 theme_tag+5점
최근 완독 도서의 테마 태그최근 30일 내 완독한 도서의 theme_tag+3점
전체 열람 비율이 높은 테마전체 열람 도서 중 반복적으로 등장하는 테마+2점 (누적 가능)
  • 점수 총합이 높은 theme_tag 우선 정렬
  • 동일 점수일 경우, 최근 출간일 기준 오름차순

4.2.5 API​

항목내용
엔드포인트GET /api/stickers/missing/
설명사용자 미보유 스티커 중 추천 목록 조회

4.3 공개 예정 스티커​

4.3.1 모델 (StickersUpcoming)​

필드타입설명
stickerForeignKey대상 스티커
positionIntegerField노출 순서
release_dateDateTimeField공개 예정일
is_featuredBooleanField피처드(강조) 여부

4.3.2 위시리스트 (StickerWishlist)​

사용자가 관심 있는 공개 예정 스티커를 저장할 수 있다.

필드타입설명
userForeignKey사용자
stickerForeignKey관심 스티커
created_atDateTimeField등록 시각

4.3.3 노출 정책​

  • 갱신 주기: 매주 월요일 오전 6시 (UTC+9) 기준으로 자동 갱신
  • 노출 기준: 사용자의 접속 국가 또는 앱 설정 언어에 따라 해당 국가의 다음 주 공개 예정 도서 목록 노출
  • 갱신 내용: 다음 주 동안 공개 예정인 도서에 연결된 스티커 미리보기 (영업일 기준 매일 1권, 총 5권/ 토-일 제외)
  • 운영 기준: 각 국가별 콘텐츠 일정은 운영 CMS에 사전 등록되어야 하며, 미등록 시 기본 콘텐츠를 노출

예시:

  • 한국 사용자는 KST 기준 월요일 오전 6시에 한국어 콘텐츠 목록 갱신
  • 일본 사용자는 JST 기준, 스페인 사용자는 CET 기준으로 갱신됨

4.3.4 API​

항목내용
목록 조회GET /api/stickers/upcoming/
위시리스트 등록POST /api/stickers/wishlist/
위시리스트 삭제DELETE /api/stickers/wishlist/<sticker_id>/

4.3.5 UI 구성​

  • 공개 예정일 표기
  • 대표 도서 썸네일 또는 시리즈 아이콘 노출
  • 클릭 시 작품 상세로 이동

5. 스티커 캠페인 (선택 — 미구현)​

5.1 모델 (StickerCampaign)​

이벤트/캠페인과 스티커를 연결하여 특정 기간 동안 해당 스티커의 노출 우선순위를 높인다.

필드타입설명
stickerForeignKey대상 스티커
eventForeignKey (nullable)연계 이벤트
campaign_nameCharField캠페인 명칭
is_activeBooleanField활성화 여부
priority_boostIntegerField가산 점수 (기본 +2)
start_dateDateTimeField캠페인 시작일
end_dateDateTimeField (nullable)캠페인 종료일

5.2 캠페인 진행 판정​

캠페인은 다음 조건을 모두 만족할 때 진행 중으로 판정된다:

  • is_active = True
  • 현재 시각이 start_date 이후
  • end_date가 null이거나, 현재 시각이 end_date 이전

5.3 점수 반영​

  • 진행 중인 캠페인에 포함된 스티커에 priority_boost(기본 +2점) 가산
  • 기본 점수 산정 시 캠페인 점수가 자동 합산됨

6. 스티커 통계​

6.1 모델 (StickerStats)​

각 스티커의 수집자 통계를 사전 집계하여 관리한다.

필드타입설명
stickerOneToOneField대상 스티커 (1:1)
total_collectorsIntegerField전체 누적 수집자 수
daily_collectorsIntegerField일간 수집자 수
weekly_collectorsIntegerField주간 수집자 수
monthly_collectorsIntegerField월간 수집자 수
last_updatedDateTimeField통계 최종 갱신 시각

6.2 API​

항목내용
엔드포인트GET /api/stickers/stats/
설명스티커별 수집자 통계 조회

7. 공통 UI 정책​

  • 스크롤 전환 방식: 스크롤에 따라 자연스럽게 다음 탭으로 이동 (자동 전환 및 햅틱 피드백)

  • 배지 표현:

    • 스티커 받기 가능 → 아직 읽지 않은 도서
    • 획득 완료 → 이미 완독하여 보상 수령 완료
  • 찜 아이콘: 각 카드 우상단에 항상 노출

  • 디자인 계층화: 인기 Top 3 강조 카드 / 나머지 기본 카드형 구분


8. 통계 및 로그 수집 항목​

  • 탭 진입 로그 (인기/나만 없는/공개 예정)
  • 개별 카드 클릭 로그
  • 카드별 스티커 상태(획득/미획득) 비율 집계
  • 탭별 체류 시간
  • 자동 스크롤 전환 발생 위치

9. 예외 및 공백 처리​

  • 스티커 조건에 맞는 도서가 하나도 없을 경우 해당 탭은 미노출
  • 네트워크 오류 시 기본 안내 문구 및 재시도 버튼 노출

10. API 요약​

API메서드설명
/api/stickers/popular/GET인기 스티커 목록 (기간별/국가별)
/api/stickers/popular/debug/<id>/GET인기 스티커 점수 디버그 상세
/api/stickers/missing/GET나만 없는 스티커 목록
/api/stickers/upcoming/GET공개 예정 스티커 목록
/api/stickers/wishlist/POST위시리스트 등록
/api/stickers/wishlist/<sticker_id>/DELETE위시리스트 삭제
/api/stickers/stats/GET스티커 통계 조회
/api/stickers/GET사용자 수집 스티커 목록
/api/stickers/earn/<episode_id>/POST스티커 획득