1. 목적
사용자에게 앱 내에서 표시되는 알림을 통해 콘텐츠 업데이트, 기능 추가, 이벤트, 문의 응답 등을 적시에 안내한다.
모든 인앱 알림은 앱 내 알림함에서 확인할 수 있다.
2. 알림 데이터 모델
2-1. Notification (알림 원본)
다국어 지원 모델(TranslatableModel)로 관리되며, 하나의 알림 원본이 다수의 사용자에게 전달된다.
| 필드 | 타입 | 설명 |
|---|
type | CharField | 알림 대분류 (user_content: 유저 소식, penta_news: 팬타 소식) |
subtype | CharField | 알림 소분류 (아래 표 참조) |
action_type | CharField | 클릭 시 이동 대상 (아래 표 참조) |
target_id | BigIntegerField | 이동 대상 ID (도서 ID, 이벤트 ID, 문의 ID 등) |
title (다국어) | CharField(500) | 알림 제목 |
message (다국어) | TextField | 알림 본문 메시지 |
created_at | DateTimeField | 알림 생성 시각 |
subtype 목록
| subtype | 표시명 | 대분류 |
|---|
sticker_release | 스티커 출시 | 유저 소식 |
inquiry_response | 1:1 문의 답변 | 유저 소식 |
feature_update | 기능 업데이트 | 팬타 소식 |
brand_news | 브랜드 뉴스 | 팬타 소식 |
event_promotion | 이벤트/프로모션 | 팬타 소식 |
action_type 목록
| action_type | 이동 대상 | 설명 |
|---|
book_detail | 도서 상세 | target_id = book_id |
event_news | 이벤트 > 소식 | target_id = event_id |
event_event | 이벤트 > 이벤트 | target_id = event_id |
inquiry_detail | 1:1 문의 상세 | target_id = inquiry_id |
2-2. UserNotification (사용자별 알림 수신)
| 필드 | 타입 | 설명 |
|---|
user | FK(User) | 수신 사용자 |
notification | FK(Notification) | 알림 원본 |
is_read | BooleanField | 읽음 여부 (기본값: false) |
received_at | DateTimeField | 수신 시각 |
user와 notification은 유니크 조합으로 관리되어 동일 알림이 같은 사용자에게 중복 전달되지 않는다.
3. 알림 노출 위치 및 동작
- 진입 위치: 상단 GNB의 알림 아이콘 클릭 시 진입
- 레드닷 표시 기준:
- 새 알림 존재 시 레드닷 표시
- 새 알림 없음 시 표시 없음
- 알림함 진입 후 상태:
- 미열람 알림은 배경에 색상 처리 (읽음 시 일반 배경으로 변경)
- 알림이 없을 경우 "새로운 알림이 없어요" 문구 노출
- 리스트 정렬: 최신순 (최신 알림이 가장 위에 위치)
4. 알림 유형 상세
A. 유저 소식 (user_content)
사용자가 북마크했거나 최근 14일 이내 열람한 콘텐츠를 기준으로 발송되는 알림이다.
발송 조건
- 해당 콘텐츠의 다음 회차 업로드
- 동일 시리즈 내 새로운 도서 업로드
- 북마크한 스티커 출시 (subtype:
sticker_release)
- "기다리던 [비비디 바비디 부 아카데미 4권]이 올라왔어요!"
- "최근 읽은 [스티치] 시리즈의 새 작품 [스티치의 발렌타인 데이]가 올라왔어요!"
- 클릭 시 해당 도서 상세(action_type:
book_detail)로 진입
- 뒤로가기 시 홈으로 복귀
B. 문의 응답 알림 (inquiry_response)
사용자가 등록한 1:1 문의에 관리자가 답변을 작성하면 자동 발송되는 알림이다.
| 항목 | 값 |
|---|
| type | user_content |
| subtype | inquiry_response |
| action_type | inquiry_detail |
| target_id | 해당 문의(Inquiry) ID |
- "문의하신 내용에 대한 답변이 등록되었어요."
- 클릭 시 1:1 문의 상세 화면으로 진입
- 뒤로가기 시 홈으로 복귀
C. 팬타 소식 (penta_news)
운영팀에서 직접 등록하는 서비스 관련 알림이다.
서브 유형별 이동 경로
| 서브 유형 | subtype | action_type | 이동 경로 | Back 동작 |
|---|
| 기능 업데이트 안내 | feature_update | event_news | 이벤트 > 소식 > 해당 글 | 홈 복귀 |
| 팬타 브랜드 소식 | brand_news | event_news | 이벤트 > 소식 > 해당 글 | 홈 복귀 |
| 이벤트/프로모션 | event_promotion | event_event | 이벤트 > 이벤트 > 해당 글 | 홈 복귀 |
- "앞으로는 오디오에 내 목소리를 녹음할 수 있게 되었어요!"
- "디즈니랜드 관람권에 응모하세요!"
- "2025 유교전에 팬타 부스에 참가합니다."
5. 알림 발송 정책
자동 발송: 유저 소식 (작품 알림)
- 트리거: 콘텐츠 업로드 시
- 대상자: 해당 콘텐츠를 북마크했거나 최근 14일 내 열람한 사용자
- 언어 기준: 앱 설정 언어 기준
- 중복 방지: 동일 콘텐츠 기준 하루 1회까지만 자동 발송
- 발송 타이밍: 콘텐츠 등록 후 5분 이내
자동 발송: 문의 응답 알림
- 트리거: 관리자가 1:1 문의에 답변 작성 시
- 대상자: 해당 문의를 등록한 사용자
- 발송 타이밍: 답변 등록 즉시
수동 발송: 팬타 소식 / 이벤트
- 운영 CMS에서 직접 등록
- 예약 발송 기능: 지원
- 언어별 발송: 각 언어 콘텐츠 별도 입력 필요 (미등록 시 해당 언어 사용자에겐 미노출)
6. API 엔드포인트
기본 경로: /api/notifications/
| 메서드 | 경로 | 설명 |
|---|
GET | /api/notifications/ | 사용자 알림 목록 조회 (최신순, 페이지네이션) |
POST | /api/notifications/mark-read/ | 특정 알림 읽음 처리 |
POST | /api/notifications/mark-all-read/ | 전체 알림 읽음 처리 |
GET | /api/notifications/unread-count/ | 미읽음 알림 개수 조회 |
GET | /api/notifications/red-dot/ | 레드닷 표시 여부 조회 (boolean) |
7. 알림 누적 및 관리 정책
- 알림 중복 발송 없음: 알림 1건은 사용자에게 1회만 발송
- 기존 알림은 사용자 알림함에 누적 저장
- 사용자 삭제 불가
- 미열람 알림은 최상단에 표시 및 색상 강조
- 보관 기한: 14일 후 자동 삭제 (읽음/미읽음 무관)
8. DB 인덱스
효율적인 조회를 위해 다음 인덱스가 설정되어 있다.
| 모델 | 인덱스 필드 | 용도 |
|---|
| Notification | -created_at | 최신순 정렬 |
| Notification | type, subtype | 유형별 필터링 |
| UserNotification | user, is_read, -received_at | 사용자별 미읽음 알림 조회 |