feat(home): 최근 활동 이동 식별자를 보강한다
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
- 시간 응답은 UTC 기준으로 내려주고 앱에서 표시 포맷과 다국어를 처리한다.
|
||||
- 장르 기반 크리에이터 추천을 위해 콘텐츠 조회 이력 기록 방식을 도입한다.
|
||||
- 여러 크리에이터를 동시에 팔로우하는 API를 제공한다.
|
||||
- 방금 활동한 크리에이터의 라이브가 진행 중이면 라이브로, 종료됐으면 해당 크리에이터 채널로 이동할 수 있는 식별자를 제공한다.
|
||||
|
||||
---
|
||||
|
||||
@@ -33,6 +34,8 @@
|
||||
- 추천 산식의 머신러닝 모델화, 개인화 가중치 학습, A/B 테스트 플랫폼은 이번 범위에 포함하지 않는다.
|
||||
- 관리자 화면 신규 개발은 포함하지 않는다.
|
||||
- 추천 결과 수동 편집 기능은 포함하지 않는다.
|
||||
- 방금 활동한 크리에이터 응답에 별도 `isOnAir`, `targetType`, 종료 전용 활동 타입을 추가하지 않는다.
|
||||
- 라이브 종료 시각을 새로 저장하거나 방금 활동한 크리에이터의 기존 활동 시간·정렬 기준을 변경하지 않는다.
|
||||
|
||||
---
|
||||
|
||||
@@ -46,7 +49,7 @@
|
||||
## 6. User Stories
|
||||
- 사용자는 메인 홈 진입 시 라이브 중인 방송 20개를 최신순으로 보고 싶다.
|
||||
- 사용자는 홈 배너를 최대 20개까지 정해진 노출 순서대로 보고 싶다.
|
||||
- 사용자는 방금 활동한 크리에이터와 활동 영역을 확인하고 해당 콘텐츠/커뮤니티로 이동하고 싶다.
|
||||
- 사용자는 방금 활동한 크리에이터와 활동 영역을 확인하고 해당 콘텐츠/커뮤니티로 이동하며, 라이브 활동은 진행 중이면 라이브로, 종료됐으면 해당 크리에이터 채널로 이동하고 싶다.
|
||||
- 사용자는 최근 데뷔한 크리에이터를 추천 점수순으로 보고 전체 리스트도 확인하고 싶다.
|
||||
- 사용자는 신규 크리에이터가 올린 첫 번째 오디오 콘텐츠를 발견하고 전체보기로 더 탐색하고 싶다.
|
||||
- 사용자는 AI 캐릭터를 추천 점수순으로 보고 채팅 화면으로 이동하고 싶다.
|
||||
@@ -115,15 +118,36 @@
|
||||
- 활동 타입 후보는 `LIVE`, `AUDIO`, `COMMUNITY`, `LIVE_REPLAY`로 한다.
|
||||
- 오디오는 콘텐츠를 업로드한 경우를 의미한다.
|
||||
- 커뮤니티는 커뮤니티 게시글을 등록한 경우를 의미한다.
|
||||
- 라이브는 라이브 진행 후 종료한 경우를 의미한다.
|
||||
- 라이브는 `live_room.channel_name`이 존재하고 빈 값이 아닌 진행 중 또는 종료된 라이브를 의미한다.
|
||||
- 라이브 다시듣기는 콘텐츠 업로드 시 `다시듣기` 테마로 올린 경우를 의미한다.
|
||||
- 노출 정보는 크리에이터 프로필 이미지, 닉네임, 활동 타입, UTC 기반 활동 시간, 이동 대상 id를 포함한다.
|
||||
- 라이브 활동은 별도 이동 대상 id가 필요하지 않다.
|
||||
- 노출 정보는 크리에이터 id, 프로필 이미지, 닉네임, 활동 타입, UTC 기반 활동 시간, 이동 대상 id를 포함한다.
|
||||
- `creatorId`는 모든 활동 item에 non-null로 제공하며, 활동을 등록한 `Member.id`를 사용한다.
|
||||
- 라이브 활동은 `live_room.is_active = true`이면 `targetId`로 `live_room.id`를 내려주고, `live_room.is_active = false`이면 `targetId`를 `null`로 내려준다.
|
||||
- 라이브 외 활동은 오디오/라이브 다시듣기 콘텐츠 id를 내려주며, 커뮤니티 활동은 `creator_community.id`를 내려준다.
|
||||
- 앱 클라이언트는 `activityType = LIVE`이면서 `targetId != null`이면 라이브로 이동하고, `targetId = null`이면 `creatorId`를 사용해 크리에이터 채널로 이동한다.
|
||||
- 크리에이터당 최신 활동 1개만 노출한다.
|
||||
- 라이브의 활동 시간은 기존과 같이 `live_room.begin_date_time`을 사용하며, 기존 최신 활동 선정과 정렬 기준을 변경하지 않는다.
|
||||
|
||||
#### Edge Cases
|
||||
- `다시듣기` 콘텐츠는 `AUDIO`가 아니라 `LIVE_REPLAY`로 분류한다.
|
||||
- 응답 조회 후 라이브 입장 전에 방송이 종료되어 라이브 진입에 실패하면 앱 클라이언트는 같은 item의 `creatorId`를 사용해 크리에이터 채널로 이동할 수 있다.
|
||||
|
||||
#### Response Contract
|
||||
|
||||
| 활동 상태 | `activityType` | `creatorId` | `targetId` | 이동 대상 |
|
||||
|---|---|---|---|---|
|
||||
| 진행 중 라이브 | `LIVE` | 크리에이터 `Member.id` | `live_room.id` | 라이브 |
|
||||
| 종료된 라이브 | `LIVE` | 크리에이터 `Member.id` | `null` | 크리에이터 채널 |
|
||||
| 오디오 | `AUDIO` | 크리에이터 `Member.id` | `content.id` | 오디오 콘텐츠 |
|
||||
| 라이브 다시듣기 | `LIVE_REPLAY` | 크리에이터 `Member.id` | `content.id` | 라이브 다시듣기 콘텐츠 |
|
||||
| 커뮤니티 | `COMMUNITY` | 크리에이터 `Member.id` | `creator_community.id` | 커뮤니티 게시글 |
|
||||
|
||||
#### Acceptance Criteria
|
||||
- 모든 `recentlyActiveCreators[]` item은 non-null `creatorId`를 반환한다.
|
||||
- 진행 중 라이브 item은 `activityType = LIVE`, `targetId = live_room.id`를 반환한다.
|
||||
- 종료된 라이브 item은 `activityType = LIVE`, `targetId = null`을 반환한다.
|
||||
- 오디오, 라이브 다시듣기, 커뮤니티의 `activityType`과 `targetId` 의미는 변경하지 않는다.
|
||||
- `creatorId` 추가는 additive schema 변경으로 처리하고, `isOnAir`, `targetType`, 신규 활동 타입은 추가하지 않는다.
|
||||
|
||||
### Feature E. 최근 데뷔한 크리에이터
|
||||
|
||||
@@ -267,6 +291,8 @@
|
||||
- Controller는 `adapter.in.web`, application service/use case는 `application`, repository/cache/scheduler 구현은 `adapter.out.*`, application이 외부 조회/저장 구현에 의존하는 계약은 `port.out`에 둔다.
|
||||
- `port.in`은 여러 adapter에서 같은 use case를 재사용하거나 진입 계약을 명확히 해야 할 때만 둔다.
|
||||
- 홈 추천 AI 캐릭터 응답의 `creatorId` 추가는 기존 `characterId` 의미를 변경하지 않는 additive schema 변경으로만 처리한다.
|
||||
- 방금 활동한 크리에이터 응답의 `creatorId` 추가는 기존 필드를 제거하거나 이름을 변경하지 않는 additive schema 변경으로 처리한다.
|
||||
- 방금 활동한 크리에이터의 `LIVE` `targetId`는 `live_room.is_active`에 따라 `live_room.id` 또는 `null`로 결정하고, 다른 활동 타입의 `targetId` 의미는 유지한다.
|
||||
- 정책, 점수 계산, 노출 조건, 스냅샷 모델처럼 인프라 의존이 없는 코드는 `domain`에 둔다.
|
||||
- `kr.co.vividnext.sodalive.v2` 외부 코드는 엔티티만 재활용하고, Controller/Service/Repository/DTO는 신규 작성한다.
|
||||
- 기존 엔티티 후보는 `Member`, `LiveRoom`, `AudioContent`, `AudioContentBanner`, `CreatorFollowing`, `CreatorCommunity`, `CreatorCommunityLike`, `CreatorCommunityComment`, `CreatorCheers`, `ChannelDonationMessage`, `AudioContentComment`, `AudioContentLike`, `ChatCharacter` 등이다.
|
||||
@@ -306,6 +332,7 @@
|
||||
- 실제 데뷔일을 계산할 첫 공개 콘텐츠와 첫 라이브가 모두 없는 크리에이터는 Phase 2 스냅샷 후보에서 제외한다.
|
||||
- Phase 2 점수 기반 스냅샷은 DB-side exact scoring으로 계산한다. service는 기준 시각 계산과 snapshot replace만 담당하고, 최종 점수 산식/정렬/limit은 repository query에서 처리한다.
|
||||
- 조회 구현은 JPA/QueryDSL 우선, native SQL 제한 사용의 하이브리드 전략으로 진행한다. native SQL은 SQL 고급 기능이 필요한 추천/랭킹/스냅샷 산정에 한정하고, 단순 상세 조회와 대상 활성 조건은 가능하면 QueryDSL/JPA 조건으로 표현한다.
|
||||
- 2026-07-30: 방금 활동한 크리에이터 item은 `creatorId`를 항상 제공한다. `LIVE`의 `targetId`는 진행 중이면 `live_room.id`, 종료됐으면 `null`로 제공하며, 종료된 라이브는 `creatorId`로 크리에이터 채널에 이동한다. 별도 `isOnAir`, `targetType`, 종료 전용 활동 타입은 추가하지 않는다.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user