31 KiB
31 KiB
PRD: 메인 홈 추천 UI와 API 연동
1. Overview
Figma home_001 화면(24:5514)을 기준으로 메인 홈 추천 영역을 구성하고, 홈 추천 API 응답을 기존 v2 widget 중심으로 바인딩한다.
2. Problem
- 메인 홈 추천 화면은 라이브, 배너, 최근 활동, 신규 데뷔, 첫 오디오 콘텐츠, AI 캐릭터, 장르별 크리에이터, 응원 크리에이터, 인기 커뮤니티 등 여러 데이터 섹션을 한 화면에 표시해야 한다.
- Figma에는 이미
live,banner,section-title,contents,chat-thumbnail,profile,feed등 재사용 가능한 형태가 다수 포함되어 있으므로, 기존에 생성된 widget을 최대한 활용해야 한다. HomeActiveCreatorItem.activityType은 백엔드 enum code 그대로 표시하면 사용자에게 부자연스러우므로LIVE,LIVE_REPLAY,AUDIO,COMMUNITY를 다국어 처리 가능한 표시 문자열로 변환해야 한다.- 사업자 정보 섹션은 별도 외부 라이브러리 없이 최대 3줄 말줄임과 더보기/접기 토글을 제공해야 한다.
- Figma에 포함된 일부 섹션은 이번 범위에서 제외되어야 하므로 구현 범위를 명확히 분리해야 한다.
3. Goals
- 홈 추천 API 응답
HomeRecommendationResponse를 받아 Figma24:5514의 홈 추천 섹션 순서에 맞게 표시한다. - 기존
HomeApi에 메서드를 추가하지 않고, 메인 홈 추천 전용 신규 API 인터페이스/Repository 흐름을 만든다. - 추천 탭이 선택된
HomeMainFragment에 메인 홈 추천 UI를 구현한다. - Figma에서 기존 widget으로 대응 가능한 항목은 기존 v2 widget을 우선 재사용한다.
- 재사용이 어려운 영역만 최소 범위 신규 UI 또는 adapter item으로 정의한다.
추천 필모그래피,또 다른 모습섹션은 만들지 않는다.- 최하단 사업자 정보 섹션은 표시하되, 기본 최대 3줄 말줄임과
더보기/접기토글을 제공한다. HomeActiveCreatorItem.activityType은 백엔드 code를 앱 내부 enum 또는 mapper로 변환하고, 표시 문구는 string resource 기반 다국어 처리를 적용한다.- API DTO, 화면 상태, empty/error/loading 정책, click routing은 구현 계획에서 검증 가능하도록 정리한다.
4. Non-Goals
- 이번 PRD 작성 단계에서는 코드, 리소스, 레이아웃 파일을 구현하지 않는다.
추천 필모그래피섹션은 구현하지 않는다.또 다른 모습섹션은 구현하지 않는다.- 추천 알고리즘, API 응답 정렬 기준, 서버 필드명은 변경하지 않는다.
- 외부 라이브러리를 추가하지 않는다.
- Compose 화면으로 전환하지 않는다.
ViewPager또는 swipe 기반 tab 전환은 추가하지 않는다.- 이번 범위에서
랭킹,팔로잉용 별도 Fragment 또는 숨김 View를 미리 만들지 않는다. - 기존 레거시 홈 화면 전체 리팩터링은 포함하지 않는다.
- Figma에 없는 skeleton loading, shimmer, 임의 애니메이션, 추가 badge는 만들지 않는다.
5. Target Users
- 메인 홈에서 추천 라이브, 크리에이터, 오디오 콘텐츠, AI 캐릭터, 커뮤니티를 탐색하는 앱 사용자.
- 기존 XML Views와 v2 widget을 재사용해 홈 추천 화면을 구현/유지보수하는 Android 개발자.
6. User Stories
- 사용자는 홈에서 현재 라이브 중인 크리에이터와 추천 콘텐츠를 빠르게 탐색하고 싶다.
- 사용자는 배너를 스와이프하거나 터치해 관련 이벤트, 크리에이터, 시리즈, 외부 링크로 이동하고 싶다.
- 사용자는 최근 활동한 크리에이터의 활동 유형을
라이브,오디오,커뮤니티처럼 이해 가능한 문구로 보고 싶다. - 사용자는 인기 커뮤니티 글을 읽다가 사업자 정보가 길어도 홈 화면 탐색이 과도하게 방해받지 않기를 기대한다.
- 개발자는 기존 v2 widget을 최대한 재사용해 화면별 UI 중복과 스타일 차이를 줄이고 싶다.
7. Core Features
홈 추천 API 연동
메인 홈 추천 화면은 다음 응답을 단일 API 결과로 받아 섹션별 UI 모델로 변환한다.
Response Contract
data class HomeRecommendationResponse(
val lives: List<HomeLiveItem>,
val banners: List<HomeBannerItem>,
val recentlyActiveCreators: List<HomeActiveCreatorItem>,
val recentDebutCreators: List<HomeCreatorItem>,
val firstAudioContents: List<HomeFirstAudioContentItem>,
val aiCharacters: List<HomeAiCharacterItem>,
val genreCreators: List<HomeGenreCreatorGroupItem>,
val cheerCreators: List<HomeCreatorItem>,
val popularCommunityPosts: List<HomePopularCommunityPostItem>
)
Requirements
- API endpoint는
GET /api/v2/home/recommendations를 사용한다. - 기존
HomeApi에 추가하지 않고 홈 추천 전용 신규 API 인터페이스를 만든다. - Repository/ViewModel 위치는 구현 계획에서
HomeMainFragment와 기존 v2 홈 구조를 확인한 뒤 결정한다. - 응답 DTO는 서버 필드명을 임의 변경하지 않고, 필요한 경우
@SerializedName만 추가한다. - 화면 UI는 DTO를 직접 노출하지 않고 섹션별 UI model 또는 adapter item으로 변환한다.
- 각 리스트가 비어 있으면 해당 섹션은 숨기는 것을 기본 정책으로 한다.
- 전체 API 실패 시 기존 홈 화면의 error/toast/loading 패턴을 따른다.
- 이미지 URL이 null이면 호출부의 기존 placeholder 정책을 따른다.
Changed Item Contracts
data class HomeFirstAudioContentItem(
val contentId: Long,
val creatorId: Long,
val creatorNickname: String,
val creatorProfileImage: String?,
val title: String,
val price: Int,
val coverImage: String?,
val releaseDate: String,
val isPointAvailable: Boolean
)
data class HomeAiCharacterItem(
val characterId: Long,
val name: String,
val description: String,
val profileImage: String?,
val totalChatCount: Long,
val originalWorkTitle: String?
)
data class HomePopularCommunityPostItem(
val postId: Long,
val creatorId: Long,
val creatorNickname: String,
val creatorProfileImage: String?,
val imageUrl: String?,
val audioUrl: String?,
val content: String,
val price: Int,
val createdAt: String,
val likeCount: Long,
val commentCount: Long,
val existOrdered: Boolean
)
Changed Item Requirements
HomeFirstAudioContentItem.price는 첫 오디오 콘텐츠의 무료 여부 표시 정책에 사용한다.HomeFirstAudioContentItem.isPointAvailable은 첫 오디오 콘텐츠 카드 바인딩 시 포인트 사용 가능 표시 정책에 반영한다.HomeAiCharacterItem.profileImage는CharacterChatThumbnailView의 실제 이미지 URL로 사용한다.HomeAiCharacterItem.originalWorkTitle이 null이면 기존CharacterChatThumbnailView의 원작 없음 표시 정책에 맞춰 원작 영역을 유지하거나 숨기는 방식을 구현 계획에서 확정한다.HomePopularCommunityPostItem.postId는 커뮤니티 게시글 이동/식별 값으로 사용한다.HomePopularCommunityPostItem.price,existOrdered는 추천 페이지용FeedCommunityView의 유료 미구매 UI 판정에 사용한다.HomePopularCommunityPostItem.content,price,createdAt,likeCount,commentCount는 인기 커뮤니티 feed 표시 데이터로 사용한다.
Activity Type 다국어 표시
HomeActiveCreatorItem.activityType은 백엔드 enum code를 앱 표시용 enum으로 변환한다.
Backend Codes
enum class RecommendedActivityType(val code: String) {
LIVE("LIVE"),
AUDIO("AUDIO"),
COMMUNITY("COMMUNITY"),
LIVE_REPLAY("LIVE_REPLAY")
}
Requirements
LIVE,LIVE_REPLAY는 동일하게라이브로 표시한다.AUDIO는오디오로 표시한다.COMMUNITY는커뮤니티로 표시한다.- 표시 문구는
strings.xml,values-en/strings.xml등 string resource를 통해 다국어 처리한다. - 알 수 없는 code는 크래시시키지 않고 기본값 또는 미표시 정책을 구현 계획에서 확정한다.
- mapper 또는 enum 변환 로직은 local unit test로 검증한다.
사업자 정보 접기/더보기
Figma 최하단 사업자 정보 섹션(218:2058)은 외부 라이브러리 없이 TextView와 클릭 가능한 컨트롤로 구현한다.
Requirements
- 기본 상태는 최대 3줄, 끝 말줄임표로 표시한다.
- 기본 상태에서
더보기를 터치하면 전체 텍스트를 표시한다. - 펼침 상태에서
접기를 터치하면 다시 최대 3줄 말줄임 상태로 돌아간다. 더보기/접기표시 문구는 string resource로 관리한다.- 외부 라이브러리를 사용하지 않는다.
- 사업자 정보 텍스트는 하드코딩 여부를 구현 계획에서 확인하되, 다국어/운영 변경 가능성이 있으면 string resource 또는 서버/설정값 사용을 우선 검토한다.
- 텍스트가 3줄 이하인 경우
더보기를 표시하지 않는다.
상단 Bar와 추천 Tab
HomeMainFragment에서 추천 탭 선택 상태의 메인 홈 추천 페이지를 표시한다.
Requirements
- title-bar는 기존
view_title_bar_home을 사용한다. - title-bar 우측 아이콘은 왼쪽부터
ic_bar_cash,ic_bar_search,ic_bar_bell순서로 배치한다. - tab-bar는 기존
TextTabBarView를 사용한다. - tab 항목은
추천,랭킹,팔로잉순서로 구성한다. - 이 PRD의 화면은
추천tab이 선택되었을 때 표시되는 page다. - tab 표시 문구는 string resource로 관리한다.
- tab 전환은 글자 터치로만 처리하고, 좌우 swipe 또는
ViewPager기반 전환은 제공하지 않는다. TextTabBarView아래에는 이번 범위의 추천 page view만 구성한다.랭킹,팔로잉page는 이번 PRD에서 Fragment나VISIBLE/GONE대상 View로 미리 만들지 않는다.- 세로 스크롤 시 title-bar와
TextTabBarView는 화면에 유지하고,TextTabBarView아래 추천 content 영역만 스크롤되도록 구성한다.
모두 팔로우 하기
최근 응원이 많은 크리에이터, 장르별 크리에이터 섹션에는 모두 팔로우 버튼을 제공한다.
API Requirements
- API는
POST /api/v2/home/recommendations/creators/follow를 사용한다. - request body는
FollowRecommendedCreatorsRequest를 사용한다. - 기존 API에 추가하지 않고, 홈 추천 전용 신규 API 인터페이스에 포함한다.
- API 호출이 정상 완료되고 response가 success이면 버튼 상태를
모두 팔로우 완료로 변경한다. - 실패 시 기존 화면의 toast/error 표시 패턴을 따른다.
Request Contract
data class FollowRecommendedCreatorsRequest(
val creatorIds: List<Long>
)
Request Requirements
creatorIds에는 사용자가 터치한모두 팔로우 하기버튼이 속한 섹션의 크리에이터 id 목록을 전달한다.최근 응원이 많은 크리에이터섹션에서는cheerCreators.creatorId목록을 전달한다.장르별 크리에이터섹션에서는 해당 장르 그룹의creators.creatorId목록을 전달한다.creatorIds가 빈 리스트인 경우 API를 호출하지 않고 버튼 상태를 변경하지 않는다.
Button Requirements
- 기본 상태 버튼 문구는
모두 팔로우 하기다. - 기본 상태 아이콘은
ic_new_follow를 사용한다. - 완료 상태 버튼 문구는
모두 팔로우 완료다. - 완료 상태 아이콘은
ic_new_following을 사용한다. - 완료 상태 Figma reference: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=24-9092&m=dev
- 완료 상태 버튼은 Figma
24:9092기준 white background, capsule radius100dp, horizontal/vertical padding12dp, icon20dp, icon/text gap6dp, Pretendard Medium16sp, black text를 기준으로 한다. - 문구는 string resource로 관리한다.
- 버튼 상태는 API success 후 중복 호출되지 않도록 disabled 또는 click 무시 상태로 전환한다.
추천 페이지 위젯 수정
추천 페이지에 표시되는 기존 widget은 화면 요구사항에 맞춰 최소 범위로 확장한다. 별도 PRD로 분리하지 않고, 메인 홈 추천 UI의 표시 계약으로 이 문서에 함께 기록한다.
FeedCommunityView Requirements
- 추천 페이지의 인기 커뮤니티는
HomePopularCommunityPostItem을FeedCommunityView또는FeedAdapter의 Community variant로 매핑한다. - 기존 keyword 영역은 추천 페이지에서는 제거한다.
HomePopularCommunityPostItem.content는 본문 영역에 표시한다.HomePopularCommunityPostItem.imageUrl이 있으면 본문 아래 이미지 영역을 표시한다.- 이미지 영역은 Figma
309:19774,309:19775기준346dp x 236dp, radius14dp, centerCrop을 기준으로 한다. imageUrl이 null이면 이미지 영역은GONE처리한다.audioUrl은 이번 추천 카드에서 별도 플레이어 UI를 만들지 않고, 게시글 상세 이동 또는 후속 오디오 정책에서 사용한다.price > 0 && existOrdered == false이면 유료 미구매 커뮤니티 포스트로 판단한다.- 유료 미구매 커뮤니티 포스트는 Figma
309:19774기준으로 이미지 위에 blur/lock overlay와 가격 capsule을 표시한다. - 가격 capsule에는
HomePopularCommunityPostItem.price를 표시한다. price > 0 && existOrdered == true이면 유료 구매 완료 포스트로 판단한다.price == 0이면 무료 포스트로 판단한다.- 유료 구매 완료 포스트 또는 무료 포스트는 Figma
309:19775의 이미지 표시 상태를 기준으로 하되, Figma에 있는구매완료버튼/태그는 표시하지 않는다. - 댓글 수와 좋아요 수는 기존 reaction row를 유지한다.
- creator profile, creator name, createdAt, body, reaction row typography와 색상은 기존
FeedCommunityView기준을 유지한다.
FeedCommunityView Figma References
- 유료이고 구매하지 않은 UI: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=309-19774&m=dev
- 유료인데 구매함 또는 무료 UI: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=309-19775&m=dev
AudioContentCardView Requirements
- 첫 오디오 콘텐츠는
v2.widget.AudioContentCardView를 사용한다. HomeFirstAudioContentItem.isPointAvailable == true이면ic_content_tag_point를 쓰는ImageView를 표시한다.HomeFirstAudioContentItem에서는 오리지널 여부를 판단하지 않는다.- 오리지널 판단 변수가 없으므로
ic_content_tag_original을 쓰는ImageView는 항상GONE처리한다. HomeFirstAudioContentItem.price == 0이면 무료 콘텐츠로 판단하고무료TextView를VISIBLE로 표시한다.HomeFirstAudioContentItem.price > 0이면무료TextView를GONE처리한다.HomeFirstAudioContentItem으로 표시하는 아이템은 모두 크리에이터의 첫 콘텐츠이므로FIRST글자를 포함하는LinearLayout을 항상 표시한다.- 위 조건에 해당하지 않는 태그는 모두
GONE처리한다. - 기존
AudioContentCardView의AudioContentTag.Original,AudioContentTag.Point,AudioContentTag.First,AudioContentTag.Free계약을 우선 재사용한다. HomeFirstAudioContentItem응답에는 오리지널 여부 필드가 없으므로 오리지널 태그는 표시하지 않는다.
섹션 구성과 UI 재사용 도식
Figma 24:5514 기준 홈 추천 화면은 아래 순서로 배치한다. 제외 섹션은 구현하지 않는다.
HomeRecommendation 화면
├─ 상단 title-bar / tab-bar / nav
│ ├─ title-bar: view_title_bar_home
│ │ └─ right icons: ic_bar_cash, ic_bar_search, ic_bar_bell
│ └─ tab-bar: TextTabBarView(추천 selected, 랭킹, 팔로잉)
└─ 추천 content scroll area
├─ 라이브 가로 목록: lives
│ ├─ Figma instance: live, more
│ ├─ 재사용: v2.widget.livethumbnail.LiveThumbnailSimpleView
│ └─ 신규: 더보기 item 또는 기존 more UI 대응 adapter item 필요
├─ 배너 캐러셀: banners
│ ├─ Figma instance: banner
│ └─ 재사용: v2.widget.banner.BannerView
├─ 최근 활동한 크리에이터: recentlyActiveCreators
│ ├─ Figma instance: section-title, list-act
│ ├─ 재사용: view_section_title
│ └─ 신규: list-act 형태의 최근 활동 카드 UI 필요
├─ 최근 데뷔한 크리에이터: recentDebutCreators
│ ├─ Figma instance: section-title, creater
│ ├─ 재사용: view_section_title
│ └─ 신규: 최근 데뷔 크리에이터 카드 UI
├─ 첫 오디오 콘텐츠: firstAudioContents
│ ├─ Figma instance: contents, profile
│ ├─ 재사용: v2.widget.AudioContentCardView
│ └─ 신규: 카드 하단 profile 결합 adapter item 필요 여부 확인
├─ AI 캐릭터: aiCharacters
│ ├─ Figma instance: section-title, chat-thumbnail
│ ├─ 재사용: view_section_title
│ └─ 재사용: v2.widget.characterchatthumbnail.CharacterChatThumbnailView
├─ 장르별 크리에이터: genreCreators
│ ├─ Figma instance: section-title, profile, button-capsule
│ ├─ 재사용: view_section_title
│ └─ 신규: 장르 그룹 카드, 2행 profile grid, 모두 팔로우 버튼
├─ 추천 필모그래피
│ └─ 제외: 만들지 않음
├─ 최근 응원이 많은 크리에이터: cheerCreators
│ ├─ Figma instance: section-title, profile, button-capsule
│ ├─ 재사용: view_section_title
│ └─ 신규: profile grid, 모두 팔로우 버튼
├─ 또 다른 모습
│ └─ 제외: 만들지 않음
├─ 인기 커뮤니티: popularCommunityPosts
│ ├─ Figma instance: section-title, feed
│ └─ 재사용/수정: v2.widget.feed.FeedCommunityView 또는 FeedAdapter Community variant
└─ 사업자 정보
└─ 신규: 3줄 말줄임 + 더보기/접기 TextView 영역
Section Mapping
| API field | Figma node range | 표시 섹션 | 재사용 후보 | 신규 필요 여부 |
|---|---|---|---|---|
lives |
24:5516 |
라이브 가로 목록 | LiveThumbnailSimpleView |
more item 확인 필요 |
banners |
24:5525 |
배너 캐러셀 | BannerView |
없음 |
recentlyActiveCreators |
24:5529 |
방금 활동한 크리에이터 | view_section_title |
list-act 신규 필요 |
recentDebutCreators |
24:5534 |
최근 데뷔한 크리에이터 | view_section_title |
신규 카드 필요 |
firstAudioContents |
24:5539 |
첫 오디오 콘텐츠 | AudioContentCardView |
태그 조건 매핑 확인 필요 |
aiCharacters |
24:5551 |
AI 캐릭터 | view_section_title, CharacterChatThumbnailView |
DTO mapping 필요 |
genreCreators |
24:5611, 24:5636 후보 |
장르별 크리에이터 | view_section_title |
그룹 카드, 모두 팔로우 버튼 신규 필요 |
cheerCreators |
24:5636 후보 |
최근 응원이 많은 크리에이터 | view_section_title |
profile grid, 모두 팔로우 버튼 신규 필요 |
popularCommunityPosts |
24:5645, 309:19774, 309:19775 |
인기 커뮤니티 | view_section_title, FeedCommunityView |
이미지/유료 상태 UI 수정 필요 |
| 사업자 정보 | 218:2058 |
사업자 정보 | 없음 | 접기/더보기 신규 필요 |
제외 섹션
- Figma
24:5557근처의추천 필모그래피로 판단되는 카드형 시리즈/필모그래피 영역은 구현하지 않는다. - Figma
24:5602근처의또 다른 모습으로 판단되는 콘텐츠 grid 영역은 구현하지 않는다. - 제외 섹션과 연결되는 서버 필드가 현재 응답에 없으므로 adapter item도 만들지 않는다.
Edge Cases
- 모든 추천 리스트가 비어 있으면 홈 추천 영역은 비어 있는 섹션을 노출하지 않고, 기존 홈 화면 empty 정책을 따른다.
- 특정 섹션만 비어 있으면 해당 section-title과 목록 전체를 숨긴다.
- 긴 제목, 닉네임, 커뮤니티 본문은 각 widget의 말줄임 정책을 따른다.
HomeAiCharacterItem.profileImage가 null이면 호출부 이미지 로딩 정책에 따라 placeholder 또는 빈 상태를 표시한다.HomePopularCommunityPostItem.imageUrl또는audioUrl이 null이어도 커뮤니티 feed는 본문/반응 수 중심으로 표시 가능해야 한다.- 유료 미구매 포스트의 가격 capsule은
price값을 사용하고, 유료 구매 완료 또는 무료 포스트에는 가격 capsule을 표시하지 않는다. HomeBannerItem.type별 이동 정책은 서버 정의와 기존 딥링크/이동 정책을 확인한 뒤 구현한다.
8. UX / UI Expectations
- Figma
24:5514의 세로 순서, 좌우 여백, 가로 스크롤 형태를 유지한다. HomeMainFragment의 추천 tab page로 표시하며,TextTabBarView에서 추천 선택 상태가 명확해야 한다.ViewPager나 swipe로 tab을 넘기는 동작은 없어야 하며, tab 글자 터치로만 전환한다.- 세로 스크롤 중에도
TextTabBarView가 화면에 남아 있어야 하므로, 스크롤 컨테이너는TextTabBarView아래 content 영역에만 적용한다. - 상단 라이브 목록, 배너, 추천 카드들은 어두운 홈 배경 위에서 기존 v2 widget 색상/typography/radius를 유지한다.
- 각 섹션 제목은 기존
view_section_title을 사용한다. 최근 응원이 많은 크리에이터,장르별 크리에이터의 모두 팔로우 버튼은 success 전/후 상태가 명확히 구분되어야 한다.- 인기 커뮤니티는 keyword 없이 본문, 선택적 이미지, 유료 잠금 상태, reaction row를 보여야 한다.
- 유료 미구매 커뮤니티 이미지는 내용을 바로 읽을 수 없도록 blur/lock overlay가 적용되어야 한다.
- 유료 구매 완료 또는 무료 커뮤니티 이미지는 overlay 없이 표시하고,
구매완료태그는 표시하지 않는다. - 가로 목록은 화면 밖 다음 item이 일부 보이도록 Figma의 peek 느낌을 유지한다.
- 커뮤니티 본문과 사업자 정보는 긴 텍스트가 화면 폭을 밀어내지 않아야 한다.
- 사업자 정보는 기본 3줄만 보여 홈 탐색을 방해하지 않고, 사용자가 원할 때 전체 내용을 확인할 수 있어야 한다.
- 터치 동작은 UI 컴포넌트 내부에서 목적지를 결정하지 않고 화면/adapter callback으로 위임한다.
9. Technical Constraints
- 현재 프로젝트는 Android XML Views + Kotlin + ViewBinding 기반이므로 XML layout, RecyclerView/adapter, custom view 패턴을 우선한다.
- UI는 기존
kr.co.vividnext.sodalive.v2.main.HomeMainFragment에 구현한다. HomeMainFragment는 이번 범위에서 추천 content만 직접 구성하며,ViewPager2,FragmentStateAdapter, tab별 신규 Fragment 3개 구조는 도입하지 않는다.TextTabBarView아래 추천 content 영역만NestedScrollView또는 동등한 단일 세로 스크롤 컨테이너로 구성한다.- 신규 API/Repository/ViewModel 및 그와 연결된 하위 코드는
kr.co.vividnext.sodalive.v2패키지 하위에 작성한다. - 기존
kr.co.vividnext.sodalive.v2.widget.*컴포넌트를 우선 재사용한다. - 기존 API 인터페이스에 메서드를 추가하지 않고, 홈 추천 전용 신규 API 인터페이스를 만든다.
- 이미지 로딩 라이브러리를 새로 추가하지 않고 기존 호출부의 이미지 로딩 방식을 따른다.
- 외부 라이브러리를 추가하지 않는다.
- API 모델은 기존 네트워크 스택과 JSON 파서 규칙을 따른다.
- string resource 기반 다국어 처리를 적용하며, UI 표시 문자열을 Kotlin 코드에 직접 하드코딩하지 않는다.
- Figma에 있는 기존 widget과 다른 신규 UI는 구현 계획에서 파일 경로와 테스트 범위를 명시한 뒤 최소 범위로 작성한다.
- 신규 순수 변환 로직(activity type mapper, count/time formatter 등)은 가능하면 local unit test로 검증한다.
10. Metrics
- PRD와 구현 계획에 Figma 섹션 배치, 재사용 widget, 신규 필요 컴포넌트가 한눈에 확인 가능하게 정리된다.
HomeRecommendationResponse의 각 필드가 노출/제외/확인필요 중 하나로 분류된다.LIVE,LIVE_REPLAY,AUDIO,COMMUNITY표시 문자열이 string resource 기반으로 매핑된다.HomeMainFragment에서view_title_bar_home,TextTabBarView,view_section_title재사용이 확인된다.FeedCommunityView에서 keyword 영역이 추천 페이지에 노출되지 않고, 이미지와 유료 미구매 overlay가 표시된다.AudioContentCardView에서ic_content_tag_point,무료,FIRST태그가 조건에 맞게 표시되고,ic_content_tag_original은 표시되지 않는다.- 제외 대상인
추천 필모그래피,또 다른 모습섹션이 화면에 생성되지 않는다. - 모두 팔로우 API success 후 버튼이
모두 팔로우 완료와ic_new_following상태로 변경된다. - 사업자 정보는 기본 3줄 말줄임, 더보기 후 전체 표시, 접기 후 3줄 복귀가 동작한다.
- 기존 v2 widget 재사용 범위가 구현 diff에서 확인된다.
- 관련 unit test, resource merge,
./gradlew :app:testDebugUnitTest또는 구현 범위에 맞는 단일 테스트가 성공한다.
11. Open Questions
- 홈 추천 API endpoint는
/api/v2/home/recommendations로 확정됐다. HTTP method는GET으로 가정하되, 구현 전 백엔드 계약 또는 기존HomeApi패턴에서 최종 확인한다. - 모두 팔로우 API는
POST /api/v2/home/recommendations/creators/follow, request body는FollowRecommendedCreatorsRequest(creatorIds: List<Long>)로 확정됐다. - 인증 token 처리 방식은 아직 제공되지 않았다. 구현 전 기존
HomeApi확장 지점과 공통 인증 interceptor 사용 여부를 확인해야 한다. genreCreators와cheerCreators의 profile grid는 기존 profile widget이 저장소에 있는지 추가 확인 후 재사용/신규를 결정한다.- 배너
type별 이동 정책(eventId,creatorId,seriesId,link)은 기존 딥링크/화면 이동 규칙과 백엔드 code 목록 확인이 필요하다. activityAt,releaseDate,createdAt,beginDateTime의 표시 포맷은 기존 시간 formatter 재사용 여부를 구현 계획에서 확인한다.
12. 검증 기록
- 2026-06-01:
docs/prd/sample-prd.md와docs/agent-guides/work-plan-docs.md를 확인해 신규 문서 위치와 PRD 작성 형식을 맞췄다. - 2026-06-01: Figma
24:5514의 최상위 구조를 확인해live,banner,section-title,contents,chat-thumbnail,profile,feed, 사업자 정보 섹션의 배치와 제외 후보 섹션을 PRD에 반영했다. - 2026-06-01: 저장소의 기존 v2 widget 패키지(
banner,livethumbnail,characterchatthumbnail,feed,AudioContentCardView)와 관련 PRD를 확인해 재사용 후보를 문서화했다. - 2026-06-01: 사용자 추가 제공 정보에 따라 홈 추천 API URL을
GET /api/v2/home/recommendations로 PRD에 반영했다. - 2026-06-01: 사용자 추가 제공 정보에 따라 신규 API 인터페이스 방침,
HomeMainFragment구현 위치,view_title_bar_home,TextTabBarView,view_section_title재사용, 모두 팔로우 API/버튼 상태, 변경된HomeFirstAudioContentItem,HomeAiCharacterItem응답 계약을 PRD에 반영했다. - 2026-06-01: 저장소에서
HomeMainFragment,view_title_bar_home,view_section_title,TextTabBarView,ic_bar_cash,ic_bar_search,ic_bar_bell,ic_new_follow,ic_new_following존재를 확인했다. - 2026-06-01: Figma
24:9092를 확인해 모두 팔로우 완료 버튼의 white capsule,20dpicon,6dpgap,16spmedium text 요구사항을 PRD에 반영했다. - 2026-06-01: 사용자 추가 제공 정보에 따라 모두 팔로우 request body
FollowRecommendedCreatorsRequest(creatorIds: List<Long>?)와 섹션별creatorIds전달 정책을 PRD에 반영했다. - 2026-06-01: 사용자 추가 제공 정보에 따라 모두 팔로우 request body의
creatorIds를 nullable이 아닌List<Long>으로 변경하고 null 의미 확인 항목을 제거했다. - 2026-06-01: 사용자 추가 제공 정보에 따라 모두 팔로우 API HTTP method를
POST로 확정해 PRD에 반영했다. - 2026-06-01: 사용자 추가 제공 정보에 따라
HomeRecommendationResponse.popularCommunities를popularCommunityPosts로 변경하고,HomePopularCommunityPostItem응답 계약을 PRD에 반영했다. - 2026-06-01: 사용자 추가 제공 정보에 따라 추천 페이지의
FeedCommunityView수정 요구사항(keyword 제거, 이미지 추가, 유료 미구매 overlay, 구매완료 태그 제외)과AudioContentCardView태그 표시 정책을 PRD에 반영했다. - 2026-06-01: Figma
309:19774,309:19775의 design context와 screenshot을 확인해 유료 미구매/구매 또는 무료 커뮤니티 feed의 이미지, blur/lock overlay, reaction row 요구사항을 문서화했다. - 2026-06-01: 저장소에서
AudioContentCardView가AudioContentTag.Original,Point,First,Free와ic_content_tag_original,ic_content_tag_point를 이미 지원하는 것을 확인했다. - 2026-06-01: 사용자 추가 제공 정보에 따라
HomeFirstAudioContentItem으로 표시하는 모든 아이템은 첫 콘텐츠로 간주해FIRST태그를 항상 표시하도록 PRD에 반영했다. - 2026-06-01: 사용자 추가 제공 정보에 따라
HomePopularCommunityPostItem.content아래에price: Int를 추가하고, 유료 미구매 가격 capsule 표시값으로 사용하도록 PRD에 반영했다. - 2026-06-01: 사용자 추가 제공 정보에 따라
HomeFirstAudioContentItem.title아래에price: Int를 추가하고,price == 0이면 무료 태그를 표시하도록 PRD에 반영했다. - 2026-06-01: 사용자 추가 제공 정보에 따라
HomeFirstAudioContentItem에서는 오리지널 여부를 판단하지 않고, 오리지널 태그를 항상 숨기는 정책으로 PRD에 반영했다. - 2026-06-01: 사용자 추가 제공 정보에 따라
popularCommunityPosts.price와existOrdered조합으로 유료 미구매/유료 구매 완료/무료 포스트 UI를 판정하도록 PRD에 반영했다. - 2026-06-02: 사용자 추가 제공 정보에 따라
ViewPager/swipe tab 전환을 제외하고, tab 글자 터치 전환만 허용하며,TextTabBarView아래 추천 content 영역만 세로 스크롤되도록 요구사항을 반영했다.