From 638aa26789d3c2a0691f242e4b97d0b96c596d6d Mon Sep 17 00:00:00 2001 From: Yu Sung Date: Mon, 29 Jun 2026 17:41:11 +0900 Subject: [PATCH] =?UTF-8?q?docs(home):=20=EC=A0=9C=EC=99=B8=20=EC=84=B9?= =?UTF-8?q?=EC=85=98=20=EB=AC=B8=EC=84=9C=EB=A5=BC=20=EC=A0=95=EB=A6=AC?= =?UTF-8?q?=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plan-task.md | 90 +++++++++---------- docs/20260602_메인_홈_추천_UI_API_연동/prd.md | 42 +-------- 2 files changed, 46 insertions(+), 86 deletions(-) diff --git a/docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md b/docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md index 0955cf22..1c91fa2c 100644 --- a/docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md +++ b/docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md @@ -31,7 +31,6 @@ - `SodaLive/Sources/V2/Main/Home/Recommendation/Repository/MainHomeRecommendationApi.swift` - `SodaLive/Sources/V2/Main/Home/Recommendation/Repository/MainHomeRecommendationRepository.swift` - `SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationViewModel.swift` -- `SodaLive/Sources/V2/Component/AudioContentCard.swift` - `SodaLive/Sources/V2/Component/Card/CommunityPostCard.swift` - `SodaLive/Sources/V2/Component/Text/ExpandableTextView.swift` - `SodaLive/Sources/I18n/I18n.swift` @@ -47,7 +46,6 @@ - `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeBannerSection.swift` - `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeActiveCreatorSection.swift` - `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeRecentDebutCreatorSection.swift` -- `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeFirstAudioContentSection.swift` - `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeAiCharacterSection.swift` - `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeGenreCreatorSection.swift` - `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeCheerCreatorSection.swift` @@ -111,10 +109,10 @@ - `HomeRecommendationResponse` 필드를 PRD와 맞춘다. - 추천 응답 모델은 `Recommendation/Models` 아래에 둔다. - `banners` 타입은 `RecommendationBannerResponse` 또는 Swift 대응 타입으로 명확히 한다. - - `HomeLiveItem.roomId`, `creatorProfileImage`, `HomeActiveCreatorItem.targetId`, `HomeFirstAudioContentItem.price`, `coverImage`, `isPointAvailable`, `HomeAiCharacterItem.totalChatCount`, `originalWorkTitle`, `HomePopularCommunityPostItem.audioUrl` 누락 여부를 확인한다. + - `HomeLiveItem.roomId`, `creatorProfileImage`, `HomeActiveCreatorItem.targetId`, `HomeAiCharacterItem.totalChatCount`, `originalWorkTitle`, `HomePopularCommunityPostItem.audioUrl` 누락 여부를 확인한다. - 과거 추정 필드는 실제 사용 경로가 없으면 제거하거나 호환 필요 시 명확히 분리한다. - 검증 기준: - - 실행 명령: `rg "roomId|creatorProfileImage|targetId|price|coverImage|isPointAvailable|totalChatCount|originalWorkTitle|audioUrl" SodaLive/Sources/V2/Main/Home/Recommendation/Models/MainHomeRecommendationResponse.swift` + - 실행 명령: `rg "roomId|creatorProfileImage|targetId|totalChatCount|originalWorkTitle|audioUrl" SodaLive/Sources/V2/Main/Home/Recommendation/Models/MainHomeRecommendationResponse.swift` - 기대 결과: PRD 핵심 필드가 모델에 반영되어야 한다. ### Phase 3: 활동 타입과 I18n @@ -335,26 +333,9 @@ - 실행 명령: `rg "MainHomeRecentDebutCreatorSection|CreatorProfileGrid|CreatorProfileItem|creatorProfileImage" SodaLive/Sources/V2/Main/Home/Recommendation SodaLive/Sources/V2/Component/Creator` - 기대 결과: 최근 데뷔 섹션이 공용 Creator widget을 재사용한다. -### Phase 12: 처음 만나는 오디오 섹션 UI +### Phase 12: AI 캐릭터 섹션 UI -- [ ] **Task 12.1: AudioContentCardView 조건부 태그 보완** - - 대상 파일: - - 확인/보완: `SodaLive/Sources/V2/Component/AudioContentCard.swift` - - 생성/보완: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeFirstAudioContentSection.swift` - - 작업 내용: - - `HomeFirstAudioContentItem.isPointAvailable == true`이면 `ic_content_tag_point` 시각요소를 표시한다. - - 오리지널 작품이면 `ic_content_tag_original` 시각요소를 표시한다. - - `price == 0`이면 `무료` 텍스트를 표시한다. - - 크리에이터의 첫 번째 콘텐츠이면 `FIRST` 표시를 보여준다. - - 조건에 해당하지 않는 요소는 렌더링하지 않는다. - - 오리지널/첫 콘텐츠 판단 필드가 응답에 없으면 임의 추정하지 않고 Open Question으로 유지한다. - - 검증 기준: - - 실행 명령: `rg "ic_content_tag_point|ic_content_tag_original|isPointAvailable|무료|FIRST|MainHomeFirstAudioContentSection" SodaLive/Sources/V2` - - 기대 결과: 오디오 카드 조건부 시각요소와 섹션 조합이 확인된다. - -### Phase 13: AI 캐릭터 섹션 UI - -- [ ] **Task 13.1: AI 캐릭터 섹션 작성/보완** +- [ ] **Task 12.1: AI 캐릭터 섹션 작성/보완** - 대상 파일: - 생성/보완: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeAiCharacterSection.swift` - 확인/보완: `SodaLive/Sources/V2/Component/Card/AiCharacterCard.swift` @@ -366,9 +347,9 @@ - 실행 명령: `rg "MainHomeAiCharacterSection|AiCharacterCard|totalChatCount|originalWorkTitle|profileImage" SodaLive/Sources/V2` - 기대 결과: AI 캐릭터 섹션이 신규 응답 필드를 기준으로 구성된다. -### Phase 14: 장르의 크리에이터 섹션 UI +### Phase 13: 장르의 크리에이터 섹션 UI -- [ ] **Task 14.1: 장르 크리에이터 그룹 섹션 작성/보완** +- [ ] **Task 13.1: 장르 크리에이터 그룹 섹션 작성/보완** - 대상 파일: - 생성/보완: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeGenreCreatorSection.swift` - 생성/보완: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeCreatorGroupSection.swift` @@ -382,9 +363,9 @@ - 실행 명령: `rg "MainHomeGenreCreatorSection|MainHomeCreatorGroupSection|genreName|creators|followAll" SodaLive/Sources/V2/Main/Home/Recommendation` - 기대 결과: 장르 그룹 섹션과 그룹 재사용 구조가 확인된다. -### Phase 15: 최근 응원이 많은 크리에이터 섹션 UI +### Phase 14: 최근 응원이 많은 크리에이터 섹션 UI -- [ ] **Task 15.1: 응원 크리에이터 섹션 작성/보완** +- [ ] **Task 14.1: 응원 크리에이터 섹션 작성/보완** - 대상 파일: - 생성/보완: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeCheerCreatorSection.swift` - 확인/보완: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeCreatorGroupSection.swift` @@ -398,9 +379,9 @@ - 실행 명령: `rg "MainHomeCheerCreatorSection|cheerCreators|MainHomeCreatorGroupSection|CreatorProfileGrid" SodaLive/Sources/V2/Main/Home/Recommendation` - 기대 결과: 응원 섹션이 장르 그룹 UI를 재사용한다. -### Phase 16: 인기 커뮤니티 섹션 UI와 FeedCommunityView +### Phase 15: 인기 커뮤니티 섹션 UI와 FeedCommunityView -- [ ] **Task 16.1: FeedCommunityView/CommunityPostCard 요구 보완** +- [ ] **Task 15.1: FeedCommunityView/CommunityPostCard 요구 보완** - 대상 파일: - 확인/보완: `SodaLive/Sources/V2/Component/Card/CommunityPostCard.swift` - 생성/보완: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomePopularCommunitySection.swift` @@ -416,9 +397,9 @@ - 실행 명령: `rg "MainHomePopularCommunitySection|CommunityPostCard|imageUrl|audioUrl|existOrdered|구매완료" SodaLive/Sources/V2` - 기대 결과: 커뮤니티 섹션과 카드 조건 분기가 확인되고 `구매완료` 표시 구현은 없어야 한다. -### Phase 17: 사업자 정보 섹션 UI +### Phase 16: 사업자 정보 섹션 UI -- [ ] **Task 17.1: 사업자 정보 더보기/접기 섹션 작성/보완** +- [ ] **Task 16.1: 사업자 정보 더보기/접기 섹션 작성/보완** - 대상 파일: - 생성/보완: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeBusinessInfoSection.swift` - 확인/보완: `SodaLive/Sources/V2/Component/Text/ExpandableTextView.swift` @@ -432,22 +413,22 @@ - 실행 명령: `rg "MainHomeBusinessInfoSection|ExpandableTextView|lineLimit|더보기|접기" SodaLive/Sources/V2` - 기대 결과: 사업자 정보 섹션과 확장 텍스트 구현이 확인된다. -### Phase 18: 섹션 조립 순서와 빈 섹션 처리 +### Phase 17: 섹션 조립 순서와 빈 섹션 처리 -- [ ] **Task 18.1: MainHomeRecommendationView에 섹션 순서 반영** +- [ ] **Task 17.1: MainHomeRecommendationView에 섹션 순서 반영** - 대상 파일: - 확인/보완: `SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift` - 작업 내용: - 섹션 순서를 PRD와 맞춘다. - - 현재 라이브, 배너, 최근 활동, 최근 데뷔, 처음 만나는 오디오, AI 캐릭터, 장르, 응원, 인기 커뮤니티, 사업자 정보 순서로 배치한다. + - 현재 라이브, 배너, 최근 활동, 최근 데뷔, AI 캐릭터, 장르, 응원, 인기 커뮤니티, 사업자 정보 순서로 배치한다. - 각 데이터 배열이 비어 있으면 섹션 제목과 컨테이너까지 숨긴다. - 검증 기준: - - 실행 명령: `rg "MainHomeLiveSection|MainHomeBannerSection|MainHomeActiveCreatorSection|MainHomeRecentDebutCreatorSection|MainHomeFirstAudioContentSection|MainHomeAiCharacterSection|MainHomeGenreCreatorSection|MainHomeCheerCreatorSection|MainHomePopularCommunitySection|MainHomeBusinessInfoSection" SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift` + - 실행 명령: `rg "MainHomeLiveSection|MainHomeBannerSection|MainHomeActiveCreatorSection|MainHomeRecentDebutCreatorSection|MainHomeAiCharacterSection|MainHomeGenreCreatorSection|MainHomeCheerCreatorSection|MainHomePopularCommunitySection|MainHomeBusinessInfoSection" SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift` - 기대 결과: 모든 구현 대상 섹션이 올바른 순서로 조립된다. -### Phase 19: 최종 프로젝트 포함과 빌드 검증 +### Phase 18: 최종 프로젝트 포함과 빌드 검증 -- [ ] **Task 19.1: Xcode 프로젝트 포함 여부 확인** +- [ ] **Task 18.1: Xcode 프로젝트 포함 여부 확인** - 대상 파일: - 확인/보완: `SodaLive.xcodeproj/project.pbxproj` - 확인: `SodaLive/Sources/V2/Main/Home/**` @@ -460,7 +441,7 @@ - 실행 명령: `plutil -lint SodaLive.xcodeproj/project.pbxproj` - 기대 결과: `OK` -- [ ] **Task 19.2: 정적 점검과 빌드** +- [ ] **Task 18.2: 정적 점검과 빌드** - 대상 파일: - 확인: `SodaLive/Sources/V2/Main/Home/**` - 확인: `SodaLive/Sources/V2/Component/**` @@ -480,14 +461,14 @@ - 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build` - 기대 결과: `BUILD SUCCEEDED` -### Phase 20: 문서와 검증 기록 갱신 +### Phase 19: 문서와 검증 기록 갱신 -- [ ] **Task 20.1: PRD/계획 문서 갱신** +- [ ] **Task 19.1: PRD/계획 문서 갱신** - 대상 파일: - 수정: `docs/20260602_메인_홈_추천_UI_API_연동/prd.md` - 수정: `docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md` - 작업 내용: - - 구현 중 확정된 배너 이동 규칙, 표시 개수, 오디오 태그 판단 필드, 커뮤니티 `audioUrl` 표시 여부가 있으면 PRD를 먼저 갱신한다. + - 구현 중 확정된 배너 이동 규칙, 표시 개수, 커뮤니티 `audioUrl` 표시 여부가 있으면 PRD를 먼저 갱신한다. - 완료한 task 체크박스를 실제 상태에 맞게 갱신한다. - 실행한 검증 명령과 결과를 이 문서 하단 검증 기록에 누적한다. - 검증 기준: @@ -496,6 +477,19 @@ ## 검증 기록 +### 2026-06-29 Phase 12 제외 섹션 반영 + +- 목적: 요구사항 변경에 따라 제외된 추천 섹션 UI 구현 범위를 PRD와 계획 문서에서 제거 +- 수행 내용: + - `prd.md`에서 제외 섹션의 응답 모델, UI 요구, 검증 항목을 제거 + - `plan-task.md`에서 기존 Phase 12 Task를 제거하고, 이후 Phase 13~20을 Phase 12~19로 한 단계씩 재번호 지정 + - 섹션 조립 순서와 검증 명령에서 제외 섹션 참조를 제거 +- 검증: + - 제외 섹션 관련 키워드 검색 결과가 남지 않음을 확인 + - 최종 Phase/Task 번호 검색 결과, 제거 전 마지막 번호가 남지 않음을 확인 + - `rg "### Phase [0-9]+:|- \[[ x]\] \*\*Task [0-9]+\.[0-9]+:" docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md` 실행, Phase/Task 형식 확인 + - `git diff --check -- docs/20260602_메인_홈_추천_UI_API_연동/prd.md docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md` 실행, 출력 없이 성공 확인 + ### 2026-06-29 Phase 11 최근 데뷔 크리에이터 섹션 구현 완료 - 목적: V2 Main Home 추천 탭에 Figma `24:5534`, `24:5537` 기준 최근 데뷔한 크리에이터 섹션을 연결 @@ -604,11 +598,11 @@ - 목적: PRD의 "서버 nullable 필드는 Swift optional" 기준에 맞춰 `MainHomeRecommendationResponse.swift` 모델 optionality를 정리 - 수행 내용: - PRD 응답 스펙에서 `?`가 없는 필드를 Swift non-optional로 변경 - - `targetId`, `coverImage`, `profileImage`, `originalWorkTitle`, `creatorProfileImage`, `imageUrl`, `audioUrl` 등 PRD nullable 필드는 optional 유지 + - `targetId`, `profileImage`, `originalWorkTitle`, `creatorProfileImage`, `imageUrl`, `audioUrl` 등 PRD nullable 필드는 optional 유지 - `RecommendationBannerResponse`는 백엔드 변경 스펙에 맞춰 `imageUrl`, `eventItem`, `creatorId`, `seriesId`, `link` 기준으로 정렬 - `HomeLiveItem.creatorNickname`, `creatorProfileImage`가 non-optional이 되면서 라이브 섹션의 불필요한 nil fallback 제거 - 검증: - - `rg -n "let (roomId|activityType|activityAt|contentId|isPointAvailable|characterId|totalChatCount|genreName|creators|postId|createdAt|likeCount|commentCount|existOrdered): .*\\?" SodaLive/Sources/V2/Main/Home/Recommendation/Models/MainHomeRecommendationResponse.swift` 실행, 검색 결과 없음 확인 예정 + - `rg -n "let (roomId|activityType|activityAt|characterId|totalChatCount|genreName|creators|postId|createdAt|likeCount|commentCount|existOrdered): .*\\?" SodaLive/Sources/V2/Main/Home/Recommendation/Models/MainHomeRecommendationResponse.swift` 실행, 검색 결과 없음 확인 예정 - `rg -n "\\?\\? \"\"" SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeLiveSection.swift` 실행, 검색 결과 없음 확인 예정 - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build` 실행 예정 @@ -679,14 +673,14 @@ - PRD와 현재 `SodaLive/Sources/V2/Main/Home`, `SodaLive/Sources/V2/Component` 구현 상태를 비교해 Phase 1 기준점과 제외 범위 확인 - 추천 API/Repository를 `SodaLive/Sources/V2/Main/Home/Recommendation/Repository` 아래로 이동하고 `MainHomeRecommendationApi`, `MainHomeRecommendationRepository`로 이름 정리 - 추천 응답 모델과 활동 타입을 `SodaLive/Sources/V2/Main/Home/Recommendation/Models` 아래로 이동 - - `HomeRecommendationResponse.banners` 타입을 `RecommendationBannerResponse`로 명확히 하고 PRD 핵심 필드(`roomId`, `creatorProfileImage`, `targetId`, `price`, `coverImage`, `isPointAvailable`, `totalChatCount`, `originalWorkTitle`, `audioUrl`) 반영 + - `HomeRecommendationResponse.banners` 타입을 `RecommendationBannerResponse`로 명확히 하고 PRD 핵심 필드(`roomId`, `creatorProfileImage`, `targetId`, `totalChatCount`, `originalWorkTitle`, `audioUrl`) 반영 - `RecommendedActivityType`의 `LIVE`, `LIVE_REPLAY`, `AUDIO`, `COMMUNITY` 변환과 `I18n.HomeRecommendation` ko/en/ja 문구 유지 확인 - `SodaLive.xcodeproj/project.pbxproj`의 이동/이름 변경된 Swift 파일 참조 갱신 - 검증: - `rg --files SodaLive/Sources/V2/Main/Home SodaLive/Sources/V2/Component SodaLive/Sources/Home SodaLive/Sources/I18n | sort` 실행, V2 홈/공용 컴포넌트 및 기존 홈 파일 목록 확인 - `rg "추천 필모그래피|또 다른 모습|figma.com|localhost:3845" SodaLive/Sources/V2/Main/Home SodaLive/Sources/V2/Component` 실행, 검색 결과 없음 확인 - `rg "/api/v2/home/recommendations|getRecommendations" SodaLive/Sources/V2/Main/Home/Recommendation/Repository SodaLive/Sources/Home` 실행, 신규 추천 endpoint가 `Recommendation/Repository`에서만 검색되고 기존 `SodaLive/Sources/Home`에는 없음 확인 - - `rg "roomId|creatorProfileImage|targetId|price|coverImage|isPointAvailable|totalChatCount|originalWorkTitle|audioUrl" SodaLive/Sources/V2/Main/Home/Recommendation/Models/MainHomeRecommendationResponse.swift` 실행, PRD 핵심 필드 반영 확인 + - `rg "roomId|creatorProfileImage|targetId|totalChatCount|originalWorkTitle|audioUrl" SodaLive/Sources/V2/Main/Home/Recommendation/Models/MainHomeRecommendationResponse.swift` 실행, PRD 핵심 필드 반영 확인 - `rg "LIVE_REPLAY|activityLive|activityAudio|activityCommunity|ライブ|オーディオ|コミュニティ" SodaLive/Sources/V2/Main/Home/Recommendation/Models/RecommendedActivityType.swift SodaLive/Sources/I18n/I18n.swift` 실행, 활동 타입 변환과 I18n 문구 확인 - `plutil -lint SodaLive.xcodeproj/project.pbxproj` 실행, `OK` 확인 - `git diff --check` 실행, 출력 없이 성공 확인 @@ -720,14 +714,14 @@ ### 2026-06-26 PRD/계획 문서 재분류 -- 목적: 신규 API 응답 스펙, FeedCommunityView, AudioContentCardView, 사업자 정보 요구사항을 PRD와 계획 문서에 반영하고, 기존 Phase를 섹션 단위 Phase로 재분류 +- 목적: 신규 API 응답 스펙, FeedCommunityView, 사업자 정보 요구사항을 PRD와 계획 문서에 반영하고, 기존 Phase를 섹션 단위 Phase로 재분류 - 수행 내용: - `prd.md`를 신규 응답 스펙 기준으로 갱신 - `plan-task.md`의 기존 Phase/완료 상태를 새 작업 분류 기준으로 재작성 - - UI 작업은 현재 라이브, 배너, 최근 활동, 최근 데뷔, 처음 만나는 오디오, AI 캐릭터, 장르, 응원, 인기 커뮤니티, 사업자 정보 섹션별 Phase로 분리 + - UI 작업은 현재 라이브, 배너, 최근 활동, 최근 데뷔, AI 캐릭터, 장르, 응원, 인기 커뮤니티, 사업자 정보 섹션별 Phase로 분리 - 기존 검증 기록은 아래에 보존 - 검증: - - `rg "GET /api/v2/home/recommendations|RecommendationBannerResponse|FeedCommunityView|AudioContentCardView|추천 필모그래피|또 다른 모습|node-id=309-19774|node-id=309-19775" docs/20260602_메인_홈_추천_UI_API_연동/prd.md docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md` 실행, 신규 API/응답 타입/FeedCommunityView/AudioContentCardView/제외 섹션/Figma 노드 반영 확인 + - `rg "GET /api/v2/home/recommendations|RecommendationBannerResponse|FeedCommunityView|추천 필모그래피|또 다른 모습|node-id=309-19774|node-id=309-19775" docs/20260602_메인_홈_추천_UI_API_연동/prd.md docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md` 실행, 신규 API/응답 타입/FeedCommunityView/제외 섹션/Figma 노드 반영 확인 - `rg "### Phase [0-9]+:|- \\[[ x]\\] \\*\\*Task [0-9]+\\.[0-9]+:" docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md` 실행, Phase heading과 Task 체크박스 형식 확인 - `git diff --check -- docs/20260602_메인_홈_추천_UI_API_연동/prd.md docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md` 실행, 출력 없이 성공 확인 diff --git a/docs/20260602_메인_홈_추천_UI_API_연동/prd.md b/docs/20260602_메인_홈_추천_UI_API_연동/prd.md index 1dd3a5f2..f3cabd69 100644 --- a/docs/20260602_메인_홈_추천_UI_API_연동/prd.md +++ b/docs/20260602_메인_홈_추천_UI_API_연동/prd.md @@ -7,10 +7,9 @@ ## 2. Problem - 추천 탭 전용 데이터가 기존 홈 API와 섞이면 응답/화면 책임이 커지고 회귀 위험이 커진다. -- Figma 추천 탭은 라이브, 배너, 최근 활동, 최근 데뷔, 첫 오디오, AI 캐릭터, 장르 크리에이터, 응원 크리에이터, 인기 커뮤니티, 사업자 정보 등 여러 독립 섹션으로 구성된다. +- Figma 추천 탭은 라이브, 배너, 최근 활동, 최근 데뷔, AI 캐릭터, 장르 크리에이터, 응원 크리에이터, 인기 커뮤니티, 사업자 정보 등 여러 독립 섹션으로 구성된다. - 섹션별 UI가 많으므로 한 화면 파일에 직접 구현하면 유지보수와 검증이 어려워진다. - `FeedCommunityView`는 추천 탭 요구에 맞춰 키워드 영역 제거, 이미지 표시, 유료/구매 상태 UI가 필요하다. -- `AudioContentCardView`는 첫 오디오 콘텐츠 응답의 `isPointAvailable`와 콘텐츠 상태에 따라 태그 표시 조건을 명확히 분기해야 한다. - 사업자 정보는 외부 라이브러리 없이 최대 3줄 말줄임표, 더보기, 접기 동작을 제공해야 한다. ## 3. Goals @@ -24,7 +23,6 @@ - 빈 데이터 섹션은 제목과 컨테이너를 표시하지 않는다. - 사업자 정보 섹션은 화면 width를 채우고, 기본 3줄 말줄임표와 더보기/접기 전환을 지원한다. - `FeedCommunityView`는 추천 탭 요구에 맞게 이미지와 유료 커뮤니티 포스트 UI를 지원한다. -- `AudioContentCardView`는 point/original/free/FIRST 시각요소를 조건에 맞게 표시하고 그 외 상태는 숨긴다. ## 4. Non-Goals - `추천 필모그래피` 섹션은 만들지 않는다. @@ -44,7 +42,6 @@ - 사용자는 홈 `추천` 탭에서 현재 라이브 중인 크리에이터와 추천 콘텐츠를 한 화면에서 보고 싶다. - 사용자는 최근 활동한 크리에이터의 활동 타입을 `라이브`, `오디오`, `커뮤니티`처럼 이해 가능한 문구로 보고 싶다. - 사용자는 이미지가 포함된 커뮤니티 포스트와 유료/구매 상태를 카드에서 구분하고 싶다. -- 사용자는 첫 오디오 콘텐츠 카드에서 포인트 가능 여부, 오리지널 작품, 무료 여부, 첫 콘텐츠 여부를 시각적으로 구분하고 싶다. - 사용자는 사업자 정보를 기본적으로 짧게 보고, 필요할 때 더보기/접기로 전환하고 싶다. - 사용자는 로그인이 필요하거나 민감 콘텐츠 제한이 필요한 상세 화면에 진입할 때 기존 홈과 같은 로그인/본인인증/콘텐츠 보기 설정 안내를 받고 싶다. @@ -66,7 +63,6 @@ data class HomeRecommendationResponse( val banners: List, val recentlyActiveCreators: List, val recentDebutCreators: List, - val firstAudioContents: List, val aiCharacters: List, val genreCreators: List, val cheerCreators: List, @@ -93,18 +89,6 @@ data class HomeCreatorItem( val creatorProfileImage: String ) -data class HomeFirstAudioContentItem( - val contentId: Long, - val creatorId: Long, - val creatorNickname: String, - val creatorProfileImage: String, - val title: String, - val price: Int, - val coverImage: String?, - @JsonProperty("isPointAvailable") - val isPointAvailable: Boolean -) - data class HomeAiCharacterItem( val characterId: Long, val creatorId: Long, @@ -216,21 +200,7 @@ enum class RecommendedActivityType(val code: String) { - 작성자, 본문, 생성 시간, 좋아요 수, 댓글 수를 표시한다. - `audioUrl`은 이번 추천 탭 카드에서 표시 대상이 확정되지 않았으므로 재생 UI를 추가하지 않는다. -### 7.5 AudioContentCardView - -`HomeFirstAudioContentItem` 기반 표시 조건: -- `isPointAvailable == true`이면 `ic_content_tag_point`를 쓰는 `ImageView`를 표시한다. -- 오리지널 작품이면 `ic_content_tag_original`를 쓰는 `ImageView`를 표시한다. -- `price == 0`이면 `무료` `TextView`를 표시한다. -- 크리에이터의 첫 번째 콘텐츠이면 `FIRST` 글자를 포함하는 `LinearLayout`을 표시한다. -- 위 조건에 해당하지 않는 시각요소는 모두 `GONE` 처리한다. - -구현 메모: -- iOS 구현 시 기존 `AudioContentCard` 또는 `AudioContentCardView`가 있으면 우선 재사용/확장한다. -- Android 용어인 `ImageView`, `TextView`, `LinearLayout`, `GONE`은 iOS에서는 각각 SwiftUI `Image`, `Text`, 컨테이너 View, 조건부 미렌더링으로 해석한다. -- 오리지널 작품/첫 번째 콘텐츠 여부가 현재 응답에 명시되어 있지 않으면 서버 필드 확인 전까지 임의 추정하지 않는다. - -### 7.6 사업자 정보 더보기/접기 +### 7.5 사업자 정보 더보기/접기 요구사항: - UI 가장 마지막에 사업자 정보 섹션을 배치한다. @@ -269,7 +239,6 @@ MainHomeView │ ├─ 배너 섹션 │ ├─ 최근 활동 크리에이터 섹션 │ ├─ 최근 데뷔한 크리에이터 섹션 - │ ├─ 처음 만나는 오디오 섹션 │ ├─ AI 캐릭터 섹션 │ ├─ 장르의 크리에이터 섹션 │ ├─ 최근 응원이 많은 크리에이터 섹션 @@ -283,7 +252,6 @@ MainHomeView ### 8.3 재사용 컴포넌트 후보 - `SodaLive/Sources/V2/Component/HomeTitleBar.swift` - `SodaLive/Sources/V2/Component/SectionTitle.swift` -- `SodaLive/Sources/V2/Component/AudioContentCard.swift` - `SodaLive/Sources/V2/Component/Banner/BannerCarousel.swift` - `SodaLive/Sources/V2/Component/Card/AiCharacterCard.swift` - `SodaLive/Sources/V2/Component/Card/CommunityPostCard.swift` @@ -323,7 +291,6 @@ MainHomeView - `LIVE`, `LIVE_REPLAY`, `AUDIO`, `COMMUNITY` 활동 타입이 I18n 문구로 표시된다. - `FeedCommunityView`에서 키워드 영역이 제거되고, 이미지/유료 미구매/유료 구매함 또는 무료 상태가 조건에 맞게 표시된다. - `FeedCommunityView`에 `구매완료` 버튼이 표시되지 않는다. -- `AudioContentCardView`에서 point/original/free/FIRST 시각요소가 조건에 맞게 표시되고 그 외에는 숨겨진다. - 사업자 정보는 마지막 섹션에서 화면 width를 채우고, 기본 3줄 말줄임표, 더보기, 전체 표시, 접기 전환이 동작한다. - 상세 진입 탭 액션은 기존 홈과 같은 로그인, 한국 사용자 본인인증, 민감 콘텐츠 보기 설정 guard를 통과한 뒤에만 실행된다. - `MainHomeView`는 추천/랭킹/팔로잉 탭 shell 역할만 하고, 추천 탭 섹션 조립은 `MainHomeRecommendationView`에 분리되어 있다. @@ -333,13 +300,12 @@ MainHomeView ## 11. Open Questions - `RecommendationBannerResponse`는 변경된 백엔드 스펙 기준으로 `eventItem`, `creatorId`, `seriesId`, `link` 순서의 이동 규칙을 사용한다. - 각 섹션별 최대 표시 개수와 가로/세로 스크롤 정책이 Figma 기준 그대로인지, 서버 응답 전체를 모두 표시해야 하는지 확인이 필요하다. -- `HomeFirstAudioContentItem`에서 오리지널 작품 여부와 크리에이터의 첫 번째 콘텐츠 여부를 판단할 서버 필드가 추가되는지 확인이 필요하다. - `HomeLiveItem`에 민감/성인 라이브 여부를 판단할 `isAdult` 또는 동등한 필드가 추가되는지, 아니면 서버에서 추천 라이브를 사전 필터링하는지 확인이 필요하다. - 커뮤니티 `audioUrl`을 추천 탭 카드에서 표시/재생해야 하는지 확인이 필요하다. - 각 카드 터치 시 상세 이동 대상이 모두 정의되어 있는지 확인이 필요하다. ## 12. Verification Plan -- 문서 검증: API URL, 응답 모델, 제외 섹션, FeedCommunityView, AudioContentCardView, 사업자 정보 요구가 PRD와 계획 문서에 반영되었는지 확인한다. +- 문서 검증: API URL, 응답 모델, 제외 섹션, FeedCommunityView, 사업자 정보 요구가 PRD와 계획 문서에 반영되었는지 확인한다. - 정적 검증: 신규 추천 API가 기존 `HomeApi`에 추가되지 않았고, Figma URL이 앱 코드에 직접 포함되지 않았는지 확인한다. - 빌드 검증: `docs/agent-guides/build-test-verification.md` 기준으로 가능한 iOS 빌드 또는 최소 정적 검증을 실행한다. -- 기능 검증: 추천 API 성공/실패, 빈 섹션, 활동 타입 I18n, 상세 진입 guard, 커뮤니티 카드 상태, 오디오 카드 태그 상태, 사업자 정보 더보기/접기를 확인한다. +- 기능 검증: 추천 API 성공/실패, 빈 섹션, 활동 타입 I18n, 상세 진입 guard, 커뮤니티 카드 상태, 사업자 정보 더보기/접기를 확인한다.