본문으로 건너뛰기

홈 화면 정책 문서

(2026년 3월 11일 updated)

1. 문서 개요​

  • 목적: 홈 화면의 콘텐츠 노출 방식 및 동작 원칙 정의
  • 적용 화면: 앱 내 첫 진입 시 메인 홈 화면
  • 대상: 기획, 운영, 개발, QA 등 관련 부서

2. 콘텐츠 노출 정책​

  • 홈 화면은 운영 큐레이션 중심으로 구성되며, 운영자가 지정한 섹션/콘텐츠 순서에 따라 노출
  • 콘텐츠 수급 방식: 수동 등록(CMS)
  • 섹션 내 콘텐츠가 부족할 경우:
    • 5개 이하일 경우 해당 섹션 비노출 처리
    • 콘텐츠 없음 → 섹션 자체 미노출

2.1 종합 홈 API​

홈 화면 진입 시 단일 API를 통해 배너, 필터, 랭킹, 큐레이션 등 전체 데이터를 한번에 조회할 수 있다.

항목내용
엔드포인트GET /api/home/
뷰ComprehensiveHomeView
설명홈 화면에 필요한 모든 섹션 데이터를 종합적으로 반환
인증선택 (비로그인 시에도 기본 데이터 제공)

3. 필터 동작 정책​

3.1 필터 모델 (HomeFilter)​

홈 화면 필터는 HomeFilter 모델(TranslatableModel)을 기반으로 관리된다.

필드타입설명
filter_typeCharField필터 유형: tab, series, reading_level
nameTranslatedField다국어 필터 명칭
valueCharFieldAPI 쿼리에 사용되는 필터 값
codeCharField (unique)클라이언트 측 필터링용 고유 코드
display_orderIntegerField노출 순서
is_activeBooleanField활성화 여부

3.2 필터 유형 및 코드 체계​

filter_type설명code 예시
tab브랜드 탭 (디즈니/픽사)TAB_DISNEY, TAB_PIXAR
series시리즈(프랜차이즈) 필터시리즈별 고유 코드
reading_level읽기 단계 필터 (연령대, 렉사일)AGE_0_3, AGE_4_7, AGE_8_10, AGE_FAMILY, LEX_BR_200, LEX_200_500 등

3.3 필터 API​

항목내용
엔드포인트GET /api/home/filters/
설명활성화된 모든 홈 필터 목록 조회
정렬filter_type → display_order → id 순

3.4 필터 동작 방식​

  • 필터 종류:

    • 탭: 디즈니 / 픽사
    • 풀스크린 셀렉터 1: 시리즈 (프랜차이즈)
    • 풀스크린 셀렉터 2: 읽기 단계 (연령, 렉사일 지수)
  • 동작 방식:

    • 모든 필터는 AND 연산 (모든 조건을 만족하는 콘텐츠만 노출)
    • 필터 조작 시 즉시 반영됨 (Apply 버튼 없음)
    • 조합 결과가 0개일 경우 → "검색 결과가 없습니다" 안내
  • 초기 진입 시 기본값: 전체 노출 (필터 선택 없음)

  • 기준 메타데이터:

    • 운영에서 제공 > 드라이브 내 스프레드 시트 참조
  • 섹션 적용 여부: 모든 큐레이션 섹션에 필터 조건 적용됨

  • 연령 범위:

    • 0-3세 / 4-7세 / 8-10세 / 온가족
  • 렉사일 범위:

    • BR-200L / 200L-500L / 470L-620L / 590L-790L / 695L-910L

4. 배너 정책​

4.1 배너 모델 (Banner)​

배너는 Banner 모델(TranslatableModel)을 통해 관리되며, 다국어를 지원한다.

필드타입설명
titleTranslatedField다국어 배너 제목
image_urlTranslatedField (URL)다국어 배너 이미지 URL (CDN 또는 업로드)
link_urlTranslatedField (URL)다국어 링크 URL
target_typeTranslatedField언어별 콘텐츠 타입 (book, collection)
content_idTranslatedField (BigInteger)언어별 Book ID
curation_idTranslatedField (BigInteger)언어별 Curation ID
link_typeCharField링크 유형: book / external / none / collection
content_typeCharField콘텐츠 유형: book / event / collection
sequenceIntegerField노출 순서
is_activeBooleanField활성화 여부
start_dateDateTimeField배너 노출 시작일
end_dateDateTimeField (nullable)배너 노출 종료일

4.2 배너 API​

항목내용
엔드포인트GET /api/home/banners/
설명현재 활성화된 배너 목록 조회
정렬sequence 순
노출 조건is_active=True 이며, 현재 시각이 start_date ~ end_date 범위 내

4.3 배너 클릭 시 동작​

link_type동작
bookcontent_id에 해당하는 도서 상세로 이동
collectioncuration_id에 해당하는 큐레이션 모아보기로 이동
externallink_url 외부 브라우저 또는 인앱 브라우저로 이동
none클릭 불가 (정보형 배너)

5. 테마 큐레이션 정책​

5.1 큐레이션 모델 (Curation)​

큐레이션은 Curation 모델(TranslatableModel)을 통해 관리된다.

필드타입설명
titleTranslatedField다국어 큐레이션 제목
descriptionTranslatedField다국어 큐레이션 설명
curation_typeCharField큐레이션 유형: theme (테마) / collection (모아보기)
booksM2M (through CurationItem)큐레이션에 포함된 도서 목록
display_orderIntegerField노출 순서
is_activeBooleanField활성화 여부

5.2 큐레이션 아이템 (CurationItem)​

필드타입설명
curationForeignKey소속 큐레이션
bookForeignKey도서
display_orderIntegerField아이템 노출 순서 (기본값: 999)

5.3 큐레이션 API​

항목내용
개별 조회GET /api/home/curations/<id>/
설명특정 큐레이션의 상세 정보 및 포함 도서 목록 조회

5.4 섹션 노출 방식​

  • 노출 방식:

    • 가로 스크롤 카드 UI (무한 루프) / 갯수 제한 없음
    • 카드 수 5개 이하인 경우 메인 미노출 (단, 필터가 걸린 경우에는 카드수 1개도 노출. 0개일 때만 미노출)
  • 테마 예시:

    • 애니를 읽자!
    • 생활 속에서 배워요
    • 모험
    • 자연 놀이
    • 걸파워
    • 우정은 나의 힘
    • 신비한 마법 이야기
    • 따듯한 감동
    • 가족 이야기
    • 오늘 밤은 어떤 책?
    • 마음이 자라는 시간
    • 가을 이야기
  • 콘텐츠 선정 기준:

    • theme_tag 기반 또는 수동 선택 가능
    • 중복 도서 제거 여부는 운영에서 수동 설정
  • 정렬 기준: PV 점수 기반

    PV 기준​

    • PV 1회 = 1점
    • 집계 기준: UTC+9 기준 매일 00시부터 1일 1회 집계
    • PV 점수 기준으로 정렬
    • 동일 점수일 경우: 최신 콘텐츠 우선
  • 운영 제어 항목:

    • 섹션명 수정 / 도서 순서 조정 / 특정 도서 제외
  • 카드 클릭 시: 해당 도서 상세(홈) 이동

  • 필터 조건은 필터 동작 정책에 따라 적용됩니다.


6. 캐릭터 친구들 정책​

  • 진입 기준: character_tag 기반

  • 정렬: 기본 ABC 순, 운영 수동 설정 가능

  • 도서 수 부족 시: 1개 미만 → 캐릭터 미노출

  • 2단계 화면: 카드 그리드 뷰, 제한 없이 스크롤 가능

  • API: GET /api/home/characters/

  • 2단계 화면 정렬 기준: PV 점수 기반

    PV 기준​

    • PV 1회 = 1점
    • 집계 기준: UTC+9 기준 매일 00시부터 1일 1회 집계
    • PV 점수 기준으로 정렬
    • 동일 점수일 경우: 최신 콘텐츠 우선

7. 실시간 Top10 랭킹 정책​

(2026년 4월 20일 updated)

7.1 랭킹 모델 (RealtimeRanking)​

실시간 랭킹은 RealtimeRanking 모델을 통해 앱 언어별 / 시간별로 관리된다.

필드타입설명
bookForeignKey랭킹 대상 도서
language_codeCharField(5)앱 언어 코드 (ko, en, jp, es)
rankIntegerField (1~50)순위
previous_rankIntegerField (1~50, nullable)이전 시간대 순위
scoreFloatField다중 시그널 합산 점수
ranking_dateDateField랭킹 날짜
ranking_hourIntegerField랭킹 시간대 (0~23)

유니크: (book, language_code, ranking_date, ranking_hour) 저장 깊이: TOP_N = 50 (API는 상위 10개만 노출하지만 데이터는 50까지 저장 — 향후 기능 확장 여지)

7.2 순위 변동 표시 (rank_change)​

값조건설명
newprevious_rank가 null신규 진입
up현재 순위 < 이전 순위순위 상승
down현재 순위 > 이전 순위순위 하락
same현재 순위 = 이전 순위순위 유지

자정 처리: ranking_hour=0 계산 시 같은 날짜에 더 이전 시간이 없으므로 어제 마지막 시간(23 또는 가장 최근)에서 previous_rank를 가져온다.

7.3 랭킹 API​

항목내용
엔드포인트GET /api/home/rankings/
설명현재 시간대 기준 앱 언어별 Top10 랭킹 조회
fallback현재 시간대 슬롯이 비어 있으면 가장 최근 슬롯 사용

7.4 랭킹 점수 산정 방식​

다중 시그널을 가중 합산.

score = (
log10(1 + Book.views) * 5.0 # 누적 인기 (log 압축)
+ Book.pv_score * 0.3 # 기존 페이지뷰 점수 활용
+ bookmarks_7d * 2.0 # 강한 의도 신호
+ sticker_collections_7d * 0.5 # 최근 활동
+ reading_completions_7d * 1.0 # 실제 완독
+ new_book_decay_bonus(published_date) # 신간 부스트 (선형 감쇠)
)

가중치 (BookScoreConfig):

시그널가중치비고
VIEWS_LOG_WEIGHT5.0views=10K → 20점, 100만 → 30점
PV_SCORE_WEIGHT0.3기존 모델 필드
BOOKMARK_WEIGHT_7D2.0가장 강한 의도 신호
COLLECTION_WEIGHT_7D0.57일 합산
COMPLETER_WEIGHT_7D1.0ReadingHistory.is_completed
NEW_BOOK_MAX_BONUS5.0day 0 → +5
NEW_BOOK_DECAY_DAYS14day 14 → 0

신간 감쇠 공식:

new_book_decay_bonus = max(0, 5.0 * (1 - days_since_publish / 14))
  • day 0 → +5
  • day 7 → +2.5
  • day 14 → 0
  • 출시일 기반 자동 산정 (별도 운영자 토글 불필요)

언어 필터링: bookmarks_7d/collections_7d/completers_7d는 모두 user.viewer_languages에 해당 언어가 포함된 사용자만 카운트.

7.5 정렬 (tie-breaker)​

ORDER BY score DESC, pv_score DESC, views DESC, id ASC

결정적 정렬 — 같은 입력 → 같은 순서. 동점 시 pv_score → views → id 순으로 결정.

7.6 갱신 / 운영​

  • 집계 대상: 앱 언어 기준, 7일 윈도우
  • 갱신 주기: 1시간 단위 (cron calculate_realtime_rankings, 매 정시 +10분)
  • 동시 실행 방지: Redis 락 (home:realtime_ranking_calc_lock, TTL 600s)
  • 데이터 보관: 7일 이상 지난 슬롯은 매 cron 실행마다 자동 삭제
  • 운영 개입: Admin에서 row 편집 가능 (rank 1~50)

8. 섹션 구성 정책​

  • 섹션 구성 및 개수: 배너 1섹션, 실시간 Top10 1섹션, 캐릭터 친구들 1섹션, 테마 큐레이션 다수 (제한 없음)

  • 노출 순서: 운영에서 수동 조정 가능

  • 섹션 내 카드 수:

    • 실시간 Top10: 고정 10개
    • 테마, 캐릭터친구들: 개수 제한 없이 가능한 것 전체 노출
    • 단, 카드 수 5개 이하인 경우 섹션 미노출 (단, 필터가 걸린 경우에는 카드 수 1개여도 노출함. 0개일 때만 미노출)
  • 슬라이드 동작:

    • 가로 스크롤, 루프 안함.

9. 카드=표지​

  • 카드 구성 요소:

    • 표지 이미지 (제목 포함 / 도서 1권당 서비스 언어 수만큼 제작됨)
    • 배지 (BGM / OST 등 태그 기반 자동 노출, 확장 가능, 필수 아님)
  • 클릭 시: 작품 상세(홈) 이동

  • 배지 기준:

    • tag = BGM → "BGM"
    • tag = OST → "OST"

10. 예외 및 공백 처리​

  • 카드 이미지 로딩 실패: 기본 표지 이미지로 대체

11. 하단 GNB 정책​

  • 탭 구성: 홈 / 인기 / 이벤트 / 내 계정
  • 탭 이동 시: 홈 → 타 탭 → 홈 복귀 시 스크롤 초기화
  • depth 이동 시: 홈 → 뎁스 이동 → 홈 복귀 시 스크롤 위치 복원
  • GNB 고정 여부:
    • 1st depth(홈 화면): 상시 고정
    • 2nd depth(캐릭터 상세 등): 비노출

12. 로그 및 통계 정책​

  • 기록 대상:

    • 필터 선택 이벤트
    • 카드 클릭 이벤트
    • 캐릭터 진입/복귀 이벤트
    • 배너 클릭 이벤트
  • 통계 활용:

    • 실시간 인기 Top10 집계
    • 사용자 행동 기반 추천 개선 및 A/B 테스트 활용
  • 제니 코멘트:

    • 시간 내 개발 가능하다면(불가시 우선순위로 최대한 빠른 시간내 개발 부탁합니다) GNB부터 클릭이 가능한 상위 3rd-4th depth 메뉴들까지 모두 로그 트래킹 가능하면 좋겠습니다. user habit이 서비스 진입부터 작품/결제 랜딩까지 어느 플로우로 가는지 보일 수 있도록요. 어느 루트로 작품뷰어까지 진입, 어떤 루트(작품)에서 결제 전환 등.

13. API 요약​

API메서드설명
/api/home/GET종합 홈 데이터 (ComprehensiveHomeView)
/api/home/filters/GET홈 필터 목록
/api/home/banners/GET배너 목록
/api/home/rankings/GET실시간 Top10 랭킹
/api/home/curations/<id>/GET큐레이션 상세
/api/home/characters/GET캐릭터 친구들 목록