28 KiB
메인 홈 추천 UI와 API 연동 Plan / Task
For agentic workers: 구현 시
superpowers:subagent-driven-development또는superpowers:executing-plans를 사용해 task 단위로 진행한다. 각 단계는 체크박스(- [ ])로 추적하고, 완료 즉시- [x]로 갱신한다.
Goal: Figma home_001(24:5514) 기준 메인 홈 추천 화면을 HomeMainFragment에 구성하고, GET /api/v2/home/recommendations 및 모두 팔로우 API를 기존 XML View + v2 widget 패턴으로 연동한다.
Architecture: 신규 홈 추천 API, Repository, ViewModel, DTO/UI model/mapper는 kr.co.vividnext.sodalive.v2.main.home 하위에 둔다. 화면은 HomeMainFragment와 fragment_v2_main_home.xml을 확장하고, 기존 v2.widget 컴포넌트는 재사용하되 추천 화면에 필요한 최소 확장만 수행한다.
Tech Stack: Kotlin, Android XML Views, ViewBinding, RecyclerView, RxJava3, Retrofit, Gson, Koin, Coil, local unit test.
전제와 성공 기준
- PRD:
docs/20260601_메인_홈_추천_UI와_API_연동/prd.md - 기존
HomeApi에는 메서드를 추가하지 않고 신규HomeRecommendationApi를 만든다. - 신규 화면 관련 하위 코드는
kr.co.vividnext.sodalive.v2패키지 하위에 작성한다. 추천 필모그래피,또 다른 모습섹션은 만들지 않는다.- 각 API 리스트가 비어 있으면 해당 section-title과 목록을 숨긴다.
- 구현 완료 후 최소
./gradlew :app:testDebugUnitTest와./gradlew :app:ktlintCheck를 실행한다.
Phase 1: 기존 구조 확인과 구현 경계 고정
-
Task 1.1: 기존 홈/위젯/네트워크 패턴 확인
- 확인:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/HomeMainFragment.kt - 확인:
app/src/main/res/layout/fragment_v2_main_home.xml - 확인:
app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt - 확인:
app/src/main/java/kr/co/vividnext/sodalive/home/HomeApi.kt - 확인:
app/src/main/java/kr/co/vividnext/sodalive/common/ApiResponse.kt - 확인:
app/src/main/java/kr/co/vividnext/sodalive/extensions/ImageExtensions.kt - 검증:
HomeMainFragment는 현재 빈FrameLayout바인딩만 가지고 있고, 신규 API 등록은AppDI.kt의networkModule,repositoryModule,viewModelModule에 추가해야 함을 확인한다.
- 확인:
-
Task 1.2: 재사용 위젯과 신규 UI 범위 확정
- 확인:
app/src/main/java/kr/co/vividnext/sodalive/v2/widget/banner/BannerView.kt - 확인:
app/src/main/java/kr/co/vividnext/sodalive/v2/widget/livethumbnail/LiveThumbnailSimpleView.kt - 확인:
app/src/main/java/kr/co/vividnext/sodalive/v2/widget/AudioContentCardView.kt - 확인:
app/src/main/java/kr/co/vividnext/sodalive/v2/widget/characterchatthumbnail/CharacterChatThumbnailView.kt - 확인:
app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityView.kt - 확인:
app/src/main/res/layout/view_section_title.xml - 신규 필요 후보: 최근 활동 카드, 최근 데뷔 크리에이터 카드, 장르별/응원 크리에이터 profile grid, 모두 팔로우 버튼, 사업자 정보 접기 영역.
- 검증: PRD의 Section Mapping 표와 구현 대상/제외 대상이 일치하는지 문서 체크한다.
- 확인:
Phase 2: API DTO, Repository, DI 추가
-
Task 2.1: 홈 추천 API/DTO 파일 생성
- 생성:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/data/HomeRecommendationApi.kt - 생성:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/data/HomeRecommendationModels.kt - 구현 내용:
GET /api/v2/home/recommendationsPOST /api/v2/home/recommendations/creators/followFollowRecommendedCreatorsRequest(val creatorIds: List<Long>)HomeRecommendationResponse와 PRD의 모든 item DTO
- 주의: 서버 필드명은 임의 변경하지 않고 필요할 때만
@SerializedName을 추가한다. - 검증:
HomeRecommendationResponse필드가lives,banners,recentlyActiveCreators,recentDebutCreators,firstAudioContents,aiCharacters,genreCreators,cheerCreators,popularCommunityPosts를 모두 포함한다.
- 생성:
-
Task 2.2: Repository 생성
- 생성:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/data/HomeRecommendationRepository.kt - 구현 내용:
getRecommendations(token: String)followRecommendedCreators(request: FollowRecommendedCreatorsRequest, token: String)
- 검증: 기존 Repository처럼 Retrofit
Single<ApiResponse<...>>를 그대로 반환하고, token은 호출부에서"Bearer ${SharedPreferenceManager.token}"형태로 전달한다.
- 생성:
-
Task 2.3: Koin DI 등록
- 수정:
app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt - 구현 내용:
networkModule에HomeRecommendationApi등록repositoryModule에HomeRecommendationRepository등록- 이후 Phase 4에서 생성할
HomeRecommendationViewModel등록
- 검증 명령:
./gradlew :app:compileDebugKotlin - 기대 결과: 신규 API/Repository import 및 Koin 등록 컴파일 성공.
- 수정:
Phase 3: 순수 mapper와 unit test 작성
-
Task 3.1: activity type 표시 mapper 테스트 작성
- 생성:
app/src/test/java/kr/co/vividnext/sodalive/v2/main/home/RecommendedActivityTypeTest.kt - 대상:
LIVE,LIVE_REPLAY,AUDIO,COMMUNITY, 알 수 없는 code. - 기대:
LIVE,LIVE_REPLAY->R.string.home_recommendation_activity_liveAUDIO->R.string.home_recommendation_activity_audioCOMMUNITY->R.string.home_recommendation_activity_community- unknown -> null 또는 미표시 정책
- 검증 명령:
./gradlew :app:testDebugUnitTest --tests kr.co.vividnext.sodalive.v2.main.home.RecommendedActivityTypeTest - 기대 결과: mapper 구현 전 실패.
- 생성:
-
Task 3.2: activity type mapper 구현
- 생성:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/model/RecommendedActivityType.kt - 생성:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/model/HomeRecommendationMappers.kt - 구현 내용:
- 백엔드 code 문자열을 앱 enum으로 변환
- 표시 문자열은
@StringRes로 반환해 Fragment/ViewHolder에서getString()처리 - 알 수 없는 code는 크래시 없이 null 반환 후 UI에서 activity label 미표시
- 검증 명령:
./gradlew :app:testDebugUnitTest --tests kr.co.vividnext.sodalive.v2.main.home.RecommendedActivityTypeTest - 기대 결과: PASS.
- 생성:
-
Task 3.3: string resource 추가
- 수정:
app/src/main/res/values/strings.xml - 수정:
app/src/main/res/values-en/strings.xml - 수정:
app/src/main/res/values-ja/strings.xml - 추가 문자열:
- 추천/랭킹/팔로잉 tab
- 섹션 제목
라이브,오디오,커뮤니티모두 팔로우 하기,모두 팔로우 완료더보기,접기- 사업자 정보 텍스트
- 검증 명령:
./gradlew :app:mergeDebugResources - 기대 결과: resource merge 성공.
- 수정:
Phase 4: ViewModel과 화면 상태 구성
-
Task 4.1: UI model 정의
- 생성:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/model/HomeRecommendationUiState.kt - 생성:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/model/HomeRecommendationUiModels.kt - 구현 내용:
Loading,Content,Empty,Error상태- 섹션별 UI model 또는 adapter item
HomeFirstAudioContentItem->AudioContentTag.First,Point,Free조건 매핑HomeAiCharacterItem.originalWorkTitle == null이면 기존CharacterChatThumbnailView의shouldShowOriginalTitle = falseHomePopularCommunityPostItem의price,existOrdered기반 유료 상태 모델
- 검증: DTO를 Fragment/ViewHolder에 직접 노출하지 않는다.
- 생성:
-
Task 4.2: ViewModel 생성
- 생성:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/HomeRecommendationViewModel.kt - 구현 내용:
recommendationStateLiveDatatoastLiveDataisLoadingloadRecommendations()followCreators(sectionKey: String, creatorIds: List<Long>)- 빈
creatorIds면 API 미호출 - 모두 팔로우 success 후 해당 section/button 상태 완료 처리
- 검증:
ApiResponse.success == false,data == null, Throwable 상황에서 기존 패턴처럼 unknown error toast를 노출한다.
- 생성:
-
Task 4.3: ViewModel DI 등록 완료
- 수정:
app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt - 구현 내용:
viewModel { HomeRecommendationViewModel(get()) } - 검증 명령:
./gradlew :app:compileDebugKotlin - 기대 결과: Koin 등록 및 ViewModel 생성 컴파일 성공.
- 수정:
Phase 5: HomeMainFragment 레이아웃과 상단 UI 구현
-
Task 5.1: 홈 추천 화면 레이아웃 작성
- 수정:
app/src/main/res/layout/fragment_v2_main_home.xml - 포함:
include또는 직접 배치로view_title_bar_homeTextTabBarViewTextTabBarView아래 추천 content 전용 세로NestedScrollView또는 동등한 scroll container- 추천 content 내부 섹션별 컨테이너와 가로
RecyclerView - 추천 content 내부 사업자 정보 영역
- 제외:
ViewPager2FragmentStateAdapter랭킹,팔로잉용 별도 Fragment랭킹,팔로잉용 숨김 View를 미리 배치하는VISIBLE/GONE구조
- 검증: root background는 기존처럼
@color/black유지하고, 세로 스크롤 시 title-bar와TextTabBarView는 화면에 남으며 그 아래 추천 content만 스크롤된다.
- 수정:
-
Task 5.2: title bar와 tab bar 바인딩
- 수정:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/HomeMainFragment.kt - 확인:
app/src/main/res/layout/view_title_bar_home.xml - 확인:
app/src/main/java/kr/co/vividnext/sodalive/v2/widget/TextTabBarView.kt - 구현 내용:
- right icons 순서:
ic_bar_cash,ic_bar_search,ic_bar_bell - tabs 순서: 추천, 랭킹, 팔로잉
- 추천 tab selected 상태
- tab 전환은 글자 터치 callback으로만 처리
- 좌우 swipe 전환은 추가하지 않음
- 이번 범위에서는 추천 tab content만 바인딩하고
랭킹,팔로잉content는 생성하지 않음
- right icons 순서:
- 검증: 앱 실행 시 상단 bar와 tab이 표시되고 text resource가 적용된다. 좌우 swipe로 tab 전환이 발생하지 않는다.
- 수정:
Phase 6: 섹션 adapter와 재사용 위젯 바인딩
Phase 6까지는 실제 API/ViewModel 연동 전 단계이므로, 실제 기기에서 UI 배치와 섹션 표시 형태를 확인할 수 있도록 Fragment 또는 adapter 호출부에 샘플 데이터를 임시 주입할 수 있다. 샘플 데이터는 Phase 9의 실제
HomeRecommendationViewModelobserve/API 바인딩 전 제거하거나 실제 상태 바인딩으로 대체한다.
-
Task 6.1: 라이브, 배너 섹션 바인딩
- 생성 후보:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/ui/HomeLiveAdapter.kt - 생성 후보:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/ui/HomeBannerBinder.kt - 재사용:
LiveThumbnailSimpleView,BannerView - 구현 내용:
lives가 비면 라이브 섹션 숨김banners가 비면 배너 섹션 숨김- 이미지 로딩은
ImageView.loadUrl()또는 기존 widget adapter의 방식 사용
- 검증: 샘플
lives,banners데이터로 실제 기기에서 라이브 가로 목록과 배너 캐러셀이 의도한 위치/크기로 보인다. 빈 리스트일 때 title/RecyclerView가 함께GONE.
- 생성 후보:
-
Task 6.2: 최근 활동/최근 데뷔 크리에이터 UI 구현
- 생성 후보:
app/src/main/res/layout/item_home_recent_activity_creator.xml - 생성 후보:
app/src/main/res/layout/item_home_recent_debut_creator.xml - 생성 후보:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/ui/HomeRecentActivityCreatorAdapter.kt - 생성 후보:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/ui/HomeRecentDebutCreatorAdapter.kt - 구현 내용:
- 최근 활동 activity type label은 Phase 3 mapper 결과 사용
- unknown activity type은 label view 숨김
- 닉네임/제목은 기존 typography와 말줄임 정책 적용
- 검증: 샘플 creator 데이터로 실제 기기에서 최근 활동/최근 데뷔 카드 배치가 보인다.
LIVE_REPLAY도라이브로 표시.
- 생성 후보:
-
Task 6.3: 첫 오디오 콘텐츠와 AI 캐릭터 섹션 바인딩
- 생성 후보:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/ui/HomeFirstAudioAdapter.kt - 생성 후보:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/ui/HomeAiCharacterAdapter.kt - 재사용:
AudioContentCardView,CharacterChatThumbnailView - 구현 내용:
- 첫 오디오 콘텐츠는
AudioContentTag.First항상 포함 isPointAvailable == true면AudioContentTag.Pointprice == 0이면AudioContentTag.FreeAudioContentTag.Original은 포함하지 않음- AI character image는
profileImage사용
- 첫 오디오 콘텐츠는
- 검증: 샘플 audio/AI character 데이터로 실제 기기에서 카드 배치와 이미지/텍스트 영역이 보인다. 오디오 태그 조합이 PRD 조건과 일치.
- 생성 후보:
-
Task 6.4: 장르별/응원 크리에이터와 모두 팔로우 버튼 구현
- 생성 후보:
app/src/main/res/layout/item_home_creator_profile.xml - 생성 후보:
app/src/main/res/layout/view_home_follow_all_button.xml - 생성 후보:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/ui/HomeGenreCreatorAdapter.kt - 생성 후보:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/ui/HomeCheerCreatorAdapter.kt - 구현 내용:
cheerCreators.creatorId목록으로 모두 팔로우 API 호출genreCreators의 해당 그룹creators.creatorId목록으로 모두 팔로우 API 호출- success 후
모두 팔로우 완료,ic_new_following, click disabled - 실패 시 toast/error 표시
- 검증: 샘플 genre/cheer creator 데이터로 실제 기기에서 profile grid와 모두 팔로우 버튼 배치가 보인다. 빈 creator list에서는 API 호출하지 않고 버튼 상태 유지.
- 생성 후보:
Phase 7: FeedCommunityView 추천 페이지 확장
-
Task 7.1: FeedItem.Community 추천 필드 확장
- 수정:
app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedItem.kt - 추가 후보:
imageUrl: String?price: IntexistOrdered: BooleanshowKeyword: Boolean
- 주의: 기존 호출부 기본값을 제공해 기존 feed 사용처 영향 최소화.
- 검증 명령:
./gradlew :app:compileDebugKotlin
- 수정:
-
Task 7.2: 커뮤니티 이미지/유료 overlay 레이아웃 추가
- 수정:
app/src/main/res/layout/view_feed_community.xml - 수정:
app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityView.kt - 수정:
app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedAdapter.kt - 구현 내용:
- keyword는 추천 페이지에서 숨김
imageUrl != null이면346dp x 236dp, radius14dp, centerCrop 이미지 표시price > 0 && existOrdered == false면 blur/lock overlay와 가격 capsule 표시- 무료/구매 완료는 overlay와 가격 capsule 숨김
FeedImageViews.primary로 커뮤니티 이미지도 외부에서 로드 가능하게 노출
- 검증: 기존 Community variant는 기본값으로 keyword를 유지하고, 추천용 item만 keyword를 숨긴다.
- 수정:
-
Task 7.3: 인기 커뮤니티 섹션 바인딩
- 생성 후보:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/ui/HomePopularCommunityAdapter.kt - 재사용:
FeedAdapter또는FeedCommunityView - 구현 내용:
postId,creatorId,creatorNickname,creatorProfileImage,content,createdAt,likeCount,commentCount,imageUrl,price,existOrdered매핑audioUrl은 별도 플레이어 UI 없이 상세 이동 데이터로만 유지
- 검증: keyword 미노출, 이미지 null이면 이미지 영역
GONE.
- 생성 후보:
Phase 8: 사업자 정보 접기/더보기 구현
- Task 8.1: 사업자 정보 UI 구현
- 수정:
app/src/main/res/layout/fragment_v2_main_home.xml - 수정:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/HomeMainFragment.kt - 구현 내용:
- 기본
maxLines = 3,ellipsize = end 더보기클릭 시 전체 표시접기클릭 시 다시 3줄 말줄임- 3줄 이하 텍스트면 toggle 숨김
- 기본
- 검증: 외부 라이브러리 없이
TextView.post { lineCount }기반으로 toggle 노출 여부 결정.
- 수정:
Phase 9: 라우팅, empty/error/loading 정책 연결
-
Task 9.1: Fragment observe와 loading/toast 연결
- 수정:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/HomeMainFragment.kt - 구현 내용:
HomeRecommendationViewModel주입loadRecommendations()호출recommendationStateLiveDataobserve 후 각 섹션 bindisLoading은 기존LoadingDialog또는 홈 화면 패턴 확인 후 적용toastLiveData는BaseFragment.showToast()사용
- 검증: API 실패 시 앱 크래시 없이 toast/error 처리.
- 수정:
-
Task 9.2: 클릭 라우팅 연결
- 수정:
app/src/main/java/kr/co/vividnext/sodalive/v2/main/HomeMainFragment.kt - 확인: 기존 상세 화면 Activity/Fragment 라우팅 파일
- 구현 내용:
- 배너 type별 이동은 기존 딥링크/이동 정책 확인 후 연결
- live, creator, audio content, AI character, community post 클릭은 adapter callback으로 Fragment에 위임
- 확정되지 않은 목적지는 임시 주석으로 남기지 않고 no-op 또는 기존 정책 확인 후 최소 연결
- 검증: UI 컴포넌트 내부에서 목적지를 결정하지 않는다.
- 수정:
Phase 10: 최종 검증과 문서 기록
-
Task 10.1: 단위 테스트와 빌드 검증
- 실행:
./gradlew :app:testDebugUnitTest - 실행:
./gradlew :app:compileDebugKotlin - 실행:
./gradlew :app:mergeDebugResources - 실행:
./gradlew :app:ktlintCheck - 기대 결과: 모두 성공.
- 실행:
-
Task 10.2: 수동 확인
- 확인 항목:
- 추천 tab 선택 상태
- tab 전환은 글자 터치로만 동작하고 swipe 전환은 없음
- 세로 스크롤 시 title-bar와
TextTabBarView는 유지되고TextTabBarView아래 추천 content만 스크롤됨 - 섹션 순서가 PRD 도식과 일치
- 제외 섹션 미노출
- 빈 리스트 섹션 숨김
- 첫 오디오 태그 조건
- activity type 다국어 문자열
- 모두 팔로우 success 후 완료 상태
- 인기 커뮤니티 유료/무료/구매 완료 이미지 상태
- 사업자 정보 더보기/접기
- 기대 결과: PRD Metrics 항목 충족.
- 확인 항목:
-
Task 10.3: 검증 기록 누적
- 수정:
docs/20260601_메인_홈_추천_UI와_API_연동/plan-task.md - 수정:
docs/20260601_메인_홈_추천_UI와_API_연동/prd.md - 구현 내용: 실행 명령, 결과, 실패 시 원인과 후속 조치를 문서 하단
검증 기록에 누적한다. - 주의: 기존 검증 기록은 삭제하거나 덮어쓰지 않는다.
- 수정:
구현 중 확인 필요
- 배너
type별 이동 정책과 서버 code 목록. HomeLiveItem,HomeBannerItem,HomeActiveCreatorItem,HomeCreatorItem,HomeGenreCreatorGroupItem의 최종 서버 필드명.- 시간 표시 포맷:
activityAt,releaseDate,createdAt,beginDateTime에 기존 formatter를 재사용할 수 있는지 확인. - 모두 팔로우 API success response의
data형태.ApiResponse.success == true만으로 완료 처리 가능한지 백엔드 계약 확인. - 사업자 정보 텍스트를
strings.xml로 둘지 서버/설정값으로 받을지 운영 정책 확인.
검증 기록
- 2026-06-02:
docs/20260601_메인_홈_추천_UI와_API_연동/prd.md,docs/agent-guides/work-plan-docs.md를 확인해 계획 문서 위치와 phase/task 형식을 맞췄다. - 2026-06-02:
HomeMainFragment,fragment_v2_main_home.xml,HomeApi,HomeRepository,AppDI,ApiResponse, 주요 v2 widget 파일을 확인해 신규 API/Repository/ViewModel과 UI 작업 범위를 계획에 반영했다. - 2026-06-02: 사용자 추가 제공 정보에 따라
ViewPager2/swipe 전환과 tab별 Fragment 선행 생성을 제외하고,TextTabBarView아래 추천 content만 세로 스크롤되도록 Phase 5와 수동 확인 항목을 갱신했다. - 2026-06-02: Phase 1 파일과 PRD Section Mapping을 확인해
HomeMainFragment/fragment_v2_main_home.xml은 아직 빈 홈 v2 shell이고, Phase 1-3 범위에서는 UI/ViewModel/adapter를 만들지 않는 것으로 구현 경계를 고정했다. - 2026-06-02:
RecommendedActivityTypeTest를 먼저 추가하고./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.RecommendedActivityTypeTest"를 실행해model패키지, mapper 함수,home_recommendation_activity_*리소스 미존재로 실패하는 RED 상태를 확인했다. - 2026-06-02:
HomeRecommendationApi,HomeRecommendationModels,HomeRecommendationRepository를 추가하고AppDI.kt의networkModule/repositoryModule에 신규 API/Repository를 등록했다. Phase 4 대상인HomeRecommendationViewModel등록은 추가하지 않았다. - 2026-06-02:
RecommendedActivityType,HomeRecommendationMappers, 한국어/영어/일본어 string resource를 추가한 뒤 targeted test를 재실행해 PASS로 GREEN 전환을 확인했다. - 2026-06-02:
./gradlew :app:mergeDebugResources,./gradlew :app:compileDebugKotlin,./gradlew :app:testDebugUnitTest,./gradlew :app:ktlintCheck를 실행했고 모두 BUILD SUCCESSFUL을 확인했다.lsp_diagnostics는kotlin-lsp미설치로 실행되지 않아 Gradle compile/test/ktlint 결과로 보완했다. - 2026-06-02: 백엔드 activity type code가 대소문자와 무관하게 들어와도 매핑되도록
RecommendedActivityTypeTest에live,Live_RePlay케이스를 추가했다. 수정 전./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.RecommendedActivityTypeTest"에서 해당 2개 테스트 실패로 RED를 확인했다. - 2026-06-02:
RecommendedActivityType.from()의 code 비교를equals(ignoreCase = true)로 변경한 뒤./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.RecommendedActivityTypeTest",./gradlew :app:compileDebugKotlin을 실행했고 모두 BUILD SUCCESSFUL을 확인했다. - 2026-06-02: Phase 6까지 진행했을 때 실제 API/ViewModel 연동 전에도 UI 배치와 섹션 표시 형태를 확인할 수 있도록 샘플 데이터를 임시 주입하는 검증 방식을 Phase 6 설명과 섹션별 검증 항목에 추가했다. 샘플 데이터는 Phase 9 실제 상태 바인딩 전 제거하거나 대체해야 한다.
- 2026-06-02: Phase 4.1로
HomeRecommendationUiState,HomeRecommendationUiModels,HomeRecommendationResponse.toContent()와 섹션별 mapper를 추가했다. DTO를 Fragment/ViewHolder 계약으로 직접 노출하지 않고, 첫 오디오 태그(First/Point/Free), AI character original title 표시 여부, 인기 커뮤니티 유료 상태 모델을 UI model로 변환하도록 구성했다. - 2026-06-02: Phase 4.2로
HomeRecommendationViewModel을 추가해recommendationStateLiveData,toastLiveData,isLoading,loadRecommendations(),followCreators(sectionKey, creatorIds)를 구현했다. 추천 API 성공 시 Content/Empty 상태로 분기하고, 실패/data null/Throwable은 Error 상태와 unknown error toast를 노출하도록 했다. 빈 creatorIds에서는 모두 팔로우 API를 호출하지 않는다. - 2026-06-02: Phase 4.3으로
AppDI.kt에HomeRecommendationViewModelimport와viewModel { HomeRecommendationViewModel(get()) }등록을 추가했다.lsp_diagnostics는kotlin-lsp미설치로 실행되지 않아 Gradle 검증으로 보완할 예정이다. - 2026-06-02: Phase 4 검증으로
./gradlew :app:compileDebugKotlin --rerun-tasks,./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.*",./gradlew :app:testDebugUnitTest,./gradlew :app:ktlintCheck,./gradlew :app:compileDebugKotlin을 실행했고 모두 BUILD SUCCESSFUL을 확인했다. 최초 증분 컴파일에서recentContentModule,chatTalkRoomModuleunresolved가 발생했으나 해당 파일이 존재하고 tracked 상태임을 확인했으며,--rerun-tasks재실행 후 성공해 증분 캐시 문제로 분리했다. ktlint 최초 실행에서는HomeRecommendationMappers.kt의 긴 줄 2건이 실패해 줄바꿈 수정 후 재실행으로 성공했다. - 2026-06-02: Phase 5 RED 검증으로
HomeMainFragmentLayoutTest를 추가하고./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest"를 실행했다. 구현 전view_home_title_bar,text_tab_bar_home,nsv_home_recommendation_content, 섹션/RecyclerView/title icon ID가 없어 컴파일 실패하는 RED 상태를 확인했다. - 2026-06-02: Phase 5.1로
fragment_v2_main_home.xml을ConstraintLayout기반으로 구성해view_title_bar_home,view_text_tab_bar,NestedScrollView추천 content shell을 배치했다. title bar와 tab bar는 scroll container 밖에 두고, 추천 content 내부에 섹션별 container와 가로RecyclerView, 사업자 정보 영역만 추가했다.ViewPager2,FragmentStateAdapter, 랭킹/팔로잉 전용 content는 추가하지 않았다. - 2026-06-02: Phase 5.2로
view_title_bar_home.xml의 right icon을ic_bar_cash,ic_bar_search,ic_bar_bell순서로 확장하고,HomeMainFragment에서TextTabBarView메뉴를 추천/랭킹/팔로잉 순서와 selected index 0으로 바인딩했다. 좌우 swipe 전환은 추가하지 않았다. - 2026-06-02: Phase 5 GREEN/검증으로
./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest",./gradlew :app:mergeDebugResources,./gradlew :app:compileDebugKotlin,./gradlew :app:ktlintCheck를 실행했고 모두 BUILD SUCCESSFUL을 확인했다.lsp_diagnostics는kotlin-lsp미설치로 실행되지 않아 Gradle compile/test/ktlint 결과로 보완했다. - 2026-06-02: 홈 상단
TextTabBarView가 추천 화면 전용이 아니라 홈 탭 공용 탭(추천/랭킹/팔로잉)임을 반영해 string resource 이름을home_recommendation_tab_*에서screen_home_tab_*으로 변경했다. 구현 전HomeMainFragment참조만 먼저 바꾼./gradlew :app:compileDebugKotlin에서 새 string ID 미정의로 RED 실패를 확인했다. - 2026-06-02: 배너 아래 섹션 제목 요구사항을 반영해
최근 데뷔한 크리에이터,처음부터 함께 성장!,크리에이터와 이야기를 나눠요!에는view_section_title의 더보기 chevron을 표시하고,방금 활동한 크리에이터,최근 응원이 많은 크리에이터,인기 커뮤니티에는 chevron을 숨기도록HomeMainFragment에서 초기화했다. 장르 섹션은 백엔드 장르명 바인딩을 위해view_section_title을 쓰지 않고 별도 title row로 분리했으며 장르명 색상은@color/color_3bb9f1로 지정했다. 구현 전HomeMainFragmentLayoutTest에서 새 section title ID 미정의로 RED 실패를 확인했고, 이후./gradlew :app:compileDebugKotlin --rerun-tasks,./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest" --rerun-tasks,./gradlew :app:mergeDebugResources가 BUILD SUCCESSFUL임을 확인했다. 최초 병렬 Gradle 실행 중 KSP incremental cache 오류가 있었으나 순차 재실행으로 성공해 캐시 경합 문제로 분리했다.