fix(main): 추천 홈 후속 검증을 보완한다
This commit is contained in:
@@ -7,14 +7,15 @@
|
||||
|
||||
## 2. Problem
|
||||
- 추천 탭 전용 데이터가 기존 홈 API와 섞이면 응답/화면 책임이 커지고 회귀 위험이 커진다.
|
||||
- Figma 추천 탭은 라이브, 배너, 최근 활동, 최근 데뷔, AI 캐릭터, 장르 크리에이터, 응원 크리에이터, 인기 커뮤니티, 사업자 정보 등 여러 독립 섹션으로 구성된다.
|
||||
- Figma 추천 탭은 라이브, 배너, 최근 활동, 최근 데뷔, AI 캐릭터, 응원 크리에이터, 인기 커뮤니티, 사업자 정보 등 여러 독립 섹션으로 구성된다.
|
||||
- 섹션별 UI가 많으므로 한 화면 파일에 직접 구현하면 유지보수와 검증이 어려워진다.
|
||||
- `FeedCommunityView`는 추천 탭 요구에 맞춰 키워드 영역 제거, 이미지 표시, 오디오 재생, 유료/구매 상태 UI가 필요하다.
|
||||
- 사업자 정보는 외부 라이브러리 없이 최대 3줄 말줄임표, 더보기, 접기 동작을 제공해야 한다.
|
||||
- `모두 팔로우하기`는 한 번의 요청으로 여러 크리에이터를 팔로우하지만 현재 버튼 터치 즉시 API를 호출하므로, 사용자가 대상을 충분히 확인하지 못한 상태에서 의도하지 않은 크리에이터까지 팔로우할 수 있다.
|
||||
|
||||
## 3. Goals
|
||||
- `추천` 탭 진입 시 `GET /api/v2/home/recommendations`를 호출하고 응답 데이터로 화면을 구성한다.
|
||||
- 기존 API에 추천 endpoint를 추가하지 않고 신규 `MainHomeApi`, Repository, ViewModel 계층을 만든다.
|
||||
- 기존 API에 추천 endpoint를 추가하지 않고 신규 `MainHomeRecommendationApi`, Repository, ViewModel 계층을 만든다.
|
||||
- Figma 확인 시 이미 생성된 widget이나 기존 V2 공용 컴포넌트로 처리 가능한 부분은 재사용한다.
|
||||
- `MainHomeView`를 추천/랭킹/팔로잉 탭 shell로 유지하고, 추천 탭 콘텐츠는 `MainHomeRecommendationView`에서 조립한다.
|
||||
- 랭킹/팔로잉 탭은 `MainHomeRankingView`, `MainHomeFollowingView`로 별도 파일/폴더를 준비해 이후 구현이 MainHome shell에 누적되지 않게 한다.
|
||||
@@ -23,6 +24,7 @@
|
||||
- 빈 데이터 섹션은 제목과 컨테이너를 표시하지 않는다.
|
||||
- 사업자 정보 섹션은 화면 width를 채우고, 기본 3줄 말줄임표와 더보기/접기 전환을 지원한다.
|
||||
- `FeedCommunityView`는 추천 탭 요구에 맞게 세로 피드형 이미지/오디오/유료 커뮤니티 포스트 UI를 지원한다.
|
||||
- 추천 탭의 모든 `모두 팔로우하기` 진입점은 로그인 사용자에게 확인 Dialog를 먼저 표시하고, 명시적으로 확인한 경우에만 기존 모두 팔로우 API를 호출한다.
|
||||
|
||||
## 4. Non-Goals
|
||||
- `추천 필모그래피` 섹션은 만들지 않는다.
|
||||
@@ -32,6 +34,9 @@
|
||||
- Figma 로컬 asset URL 또는 Figma 웹 URL을 앱 코드에 직접 사용하지 않는다.
|
||||
- 서버 응답 스펙에 없는 개별 팔로우 상태, 페이지네이션, 정렬/필터 기능은 이번 범위에 포함하지 않는다.
|
||||
- Figma `node-id=309-19775`의 `구매완료` 버튼은 구현하지 않는다.
|
||||
- 장르 크리에이터 섹션은 현재 추천 탭에 노출하지 않는다. 단, API 디코딩을 위해 `genreCreators` 응답 모델 필드는 유지한다.
|
||||
- 개별 크리에이터 팔로우/언팔로우 흐름에는 이번 Confirm Dialog를 적용하지 않는다.
|
||||
- 기존 모두 팔로우 API의 endpoint, request/response 계약과 서버 동작은 변경하지 않는다.
|
||||
|
||||
## 5. Target Users
|
||||
- 앱 홈에서 추천 라이브, 크리에이터, 콘텐츠, 커뮤니티를 빠르게 탐색하는 사용자
|
||||
@@ -44,6 +49,7 @@
|
||||
- 사용자는 이미지가 포함된 커뮤니티 포스트와 유료/구매 상태를 카드에서 구분하고 싶다.
|
||||
- 사용자는 사업자 정보를 기본적으로 짧게 보고, 필요할 때 더보기/접기로 전환하고 싶다.
|
||||
- 사용자는 로그인이 필요하거나 민감 콘텐츠 제한이 필요한 상세 화면에 진입할 때 기존 홈과 같은 로그인/본인인증/콘텐츠 보기 설정 안내를 받고 싶다.
|
||||
- 사용자는 여러 크리에이터를 한 번에 팔로우하기 전에 영향을 확인하고, 원하지 않으면 API 요청 없이 취소하고 싶다.
|
||||
|
||||
## 7. Core Requirements
|
||||
|
||||
@@ -104,6 +110,7 @@ data class HomeGenreCreatorGroupItem(
|
||||
val genreName: String,
|
||||
val creators: List<HomeCreatorItem>
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -124,6 +131,8 @@ data class RecommendationBannerResponse(
|
||||
- `seriesId` -> 시리즈 상세
|
||||
- `link` -> 외부 URL 열기
|
||||
|
||||
#### HomePopularCommunityPostItem
|
||||
```kotlin
|
||||
data class HomePopularCommunityPostItem(
|
||||
val postId: Long,
|
||||
val creatorId: Long,
|
||||
@@ -230,7 +239,32 @@ enum class RecommendedActivityType(val code: String) {
|
||||
구현 방향:
|
||||
- SwiftUI `Text`와 `lineLimit(isExpanded ? nil : 3)` 기반으로 구현한다.
|
||||
- 줄 수 판정은 제한/무제한 높이 비교 또는 Geometry 기반 측정 방식을 사용한다.
|
||||
- 사업자 정보 wrapper는 `MainHomeBusinessInfoSection`, 재사용 가능한 텍스트 UI는 `ExpandableTextView`로 분리한다.
|
||||
- 사업자 정보 wrapper는 `MainHomeBusinessInfoSection`, 재사용 가능한 텍스트 UI는 `V2ExpandableTextView`로 분리한다.
|
||||
|
||||
### 7.6 모두 팔로우 확인 Dialog
|
||||
|
||||
적용 범위:
|
||||
- 메인 홈 추천 탭에서 공통 `onTapFollowAll` 흐름을 사용하는 모든 `모두 팔로우하기` 진입점에 적용한다.
|
||||
- 현재 화면에 노출되는 `최근 응원이 많은 크리에이터` 섹션뿐 아니라, 같은 공통 흐름에 연결되는 다른 모두 팔로우 진입점도 동일한 확인 절차를 사용한다.
|
||||
- 현재 미노출 상태인 장르 크리에이터 섹션을 다시 노출하는 작업은 이번 범위에 포함하지 않는다.
|
||||
|
||||
로그인 및 확인 흐름:
|
||||
1. 비로그인 사용자가 `모두 팔로우하기`를 터치하면 기존 동작과 동일하게 확인 Dialog 없이 로그인 화면으로 이동한다.
|
||||
2. 로그인 사용자가 `모두 팔로우하기`를 터치하면 기존 `SodaV2ActionModal`을 사용한 Confirm Dialog를 표시한다.
|
||||
3. Dialog가 표시된 시점에는 `POST /api/v2/home/recommendations/creators/follow`를 호출하지 않는다.
|
||||
4. 사용자가 `팔로우 하기`를 터치하면 Dialog를 닫고 선택한 섹션의 기존 모두 팔로우 action을 한 번 실행한다.
|
||||
5. 사용자가 `취소` 또는 dimmed 영역을 터치하면 Dialog를 닫고 보류한 action을 폐기하며 API를 호출하지 않는다.
|
||||
6. 로그인 화면에서 돌아온 뒤 모두 팔로우를 자동 실행하지 않는다. 사용자가 버튼을 다시 터치하면 확인 Dialog부터 새로 진행한다.
|
||||
7. 기존 모두 팔로우 완료, 호출 중, 오류 toast와 중복 호출 방지 동작은 유지한다.
|
||||
|
||||
다국어 문구:
|
||||
|
||||
| 용도 | ko | en | ja |
|
||||
|---|---|---|---|
|
||||
| 제목 | `모두 팔로우할까요?` | `Follow all creators?` | `すべてのクリエイターをフォローしますか?` |
|
||||
| 설명 | `추천된 크리에이터를 모두 팔로우합니다.` | `You’ll follow all recommended creators.` | `おすすめのクリエイターをすべてフォローします。` |
|
||||
| 확인 | `팔로우 하기` | `Follow` | `フォローする` |
|
||||
| 취소 | `I18n.Common.cancel` 재사용 | `I18n.Common.cancel` 재사용 | `I18n.Common.cancel` 재사용 |
|
||||
|
||||
## 8. UX / UI Expectations
|
||||
|
||||
@@ -256,7 +290,6 @@ MainHomeView
|
||||
│ ├─ 최근 활동 크리에이터 섹션
|
||||
│ ├─ 최근 데뷔한 크리에이터 섹션
|
||||
│ ├─ AI 캐릭터 섹션
|
||||
│ ├─ 장르의 크리에이터 섹션
|
||||
│ ├─ 최근 응원이 많은 크리에이터 섹션
|
||||
│ ├─ 인기 커뮤니티 섹션
|
||||
│ └─ 사업자 정보 섹션
|
||||
@@ -273,7 +306,7 @@ MainHomeView
|
||||
- `SodaLive/Sources/V2/Component/Card/CommunityPostCard.swift`
|
||||
- `SodaLive/Sources/V2/Component/Creator/CreatorProfileGrid.swift`
|
||||
- `SodaLive/Sources/V2/Component/Creator/CreatorProfileItem.swift`
|
||||
- `SodaLive/Sources/V2/Component/Text/ExpandableTextView.swift`
|
||||
- `SodaLive/Sources/V2/Component/Text/V2ExpandableTextView.swift`
|
||||
|
||||
이미 존재하는 컴포넌트가 Figma 요구를 일부만 충족하면 새 컴포넌트를 중복 생성하지 않고 필요한 범위만 보완한다.
|
||||
|
||||
@@ -296,6 +329,8 @@ MainHomeView
|
||||
- 인증 헤더는 기존 `UserDefaultsKey.token` 기반 패턴을 따른다.
|
||||
- 서버 `Long` 값은 Swift에서 기존 라우팅/모델 관례와 맞는 `Int` 또는 `Int64`로 사용한다.
|
||||
- 사용자 노출 문구는 가능한 `I18n`에 추가한다.
|
||||
- 모두 팔로우 Confirm Dialog는 기존 `SodaV2ActionModal`과 `I18n.Common.cancel`을 재사용하고 새 Dialog 컴포넌트 또는 외부 의존성을 추가하지 않는다.
|
||||
- 모두 팔로우 API/Repository/ViewModel 계약은 유지하고, 공통 callback에서 API action 실행 시점만 확인 이후로 지연한다.
|
||||
- 상세 진입 guard는 `MainHomeView` 내부에 인증 UI를 중복 구현하지 않고, V2 `MainView`의 기존 인증/민감 콘텐츠 guard 인프라를 재사용한다.
|
||||
- `MainHomeView`에는 추천 탭의 섹션 조립을 직접 누적하지 않고, 탭별 콘텐츠 View를 조합하는 역할만 둔다.
|
||||
- Open Questions에 남긴 항목은 임의 구현하지 않고 확인 후 반영한다.
|
||||
@@ -315,6 +350,11 @@ MainHomeView
|
||||
- 최근 활동 크리에이터의 `COMMUNITY` 활동과 인기 커뮤니티 섹션의 게시물은 커뮤니티 게시물 상세 페이지로 이동한다.
|
||||
- `MainHomeView`는 추천/랭킹/팔로잉 탭 shell 역할만 하고, 추천 탭 섹션 조립은 `MainHomeRecommendationView`에 분리되어 있다.
|
||||
- 반복 UI는 기존 widget 또는 공용 컴포넌트를 재사용하고 불필요하게 중복 구현하지 않는다.
|
||||
- 로그인 사용자가 추천 탭의 `모두 팔로우하기`를 터치하면 Confirm Dialog가 표시되고, 확인 전에는 모두 팔로우 API 요청이 발생하지 않는다.
|
||||
- Dialog에서 `팔로우 하기`를 한 번 터치하면 해당 섹션의 기존 모두 팔로우 API가 한 번 호출된다.
|
||||
- Dialog에서 `취소` 또는 dimmed 영역을 터치하면 모두 팔로우 API 요청이 발생하지 않는다.
|
||||
- 비로그인 사용자는 기존처럼 로그인 화면으로 이동하며, 확인 Dialog 또는 로그인 완료 후 자동 팔로우가 실행되지 않는다.
|
||||
- 모두 팔로우 Dialog의 제목, 설명, 확인 버튼은 ko/en/ja로 표시되고 취소 버튼은 기존 공통 I18n을 재사용한다.
|
||||
- 빌드가 성공하고, 가능하면 ViewModel 디코딩/상태 전환 검증을 수행한다.
|
||||
|
||||
## 11. Open Questions
|
||||
@@ -323,9 +363,22 @@ MainHomeView
|
||||
- `HomeLiveItem`에 민감/성인 라이브 여부를 판단할 `isAdult` 또는 동등한 필드가 추가되는지, 아니면 서버에서 추천 라이브를 사전 필터링하는지 확인이 필요하다.
|
||||
- 커뮤니티 `audioUrl`을 추천 탭 카드에서 표시/재생해야 하는지 확인이 필요하다.
|
||||
- 각 카드 터치 시 상세 이동 대상이 모두 정의되어 있는지 확인이 필요하다. 단, 최근 활동 `LIVE`, `LIVE_REPLAY`, `COMMUNITY`, 인기 커뮤니티 게시물의 이동 규칙은 확정한다.
|
||||
- 모두 팔로우 확인 Dialog의 적용 범위, 로그인 순서, 취소 동작, 문구와 다국어에는 열린 질문이 없다.
|
||||
|
||||
## 12. Verification Plan
|
||||
- 문서 검증: API URL, 응답 모델, 제외 섹션, FeedCommunityView, 사업자 정보 요구가 PRD와 계획 문서에 반영되었는지 확인한다.
|
||||
- 정적 검증: 신규 추천 API가 기존 `HomeApi`에 추가되지 않았고, Figma URL이 앱 코드에 직접 포함되지 않았는지 확인한다.
|
||||
- 빌드 검증: `docs/agent-guides/build-test-verification.md` 기준으로 가능한 iOS 빌드 또는 최소 정적 검증을 실행한다.
|
||||
- 기능 검증: 추천 API 성공/실패, 빈 섹션, 활동 타입 I18n, 상세 진입 guard, 최근 활동 `LIVE`의 `targetId` 유무별 이동, `creatorId` 양수 검사, `LIVE_REPLAY`의 콘텐츠 상세 이동, 다른 활동 타입의 회귀 여부, 커뮤니티 카드 상태, 사업자 정보 더보기/접기를 확인한다.
|
||||
- 모두 팔로우 기능 검증: 로그인/비로그인 상태를 구분해 Dialog 표시 여부를 확인하고, 확인 전·취소·dimmed 영역 터치에는 API 요청이 0회이며 `팔로우 하기` 선택 시에만 요청이 1회인지 확인한다.
|
||||
- 다국어 검증: 앱 언어를 ko/en/ja로 전환해 모두 팔로우 Dialog의 제목, 설명, 확인, 취소 문구를 확인한다.
|
||||
|
||||
## 13. Decision Log
|
||||
|
||||
### 2026-07-30 모두 팔로우 확인 Dialog 인터뷰
|
||||
|
||||
- 메인 홈 추천 탭의 모든 `모두 팔로우하기` 진입점에 공통 확인 Dialog를 적용한다.
|
||||
- 비로그인 사용자는 기존처럼 로그인 화면으로 바로 이동하고, 로그인 후 자동 팔로우하지 않는다.
|
||||
- 로그인 사용자는 `팔로우 하기`를 명시적으로 선택한 경우에만 API를 호출한다.
|
||||
- `취소`와 dimmed 영역 터치는 모두 보류 action 폐기 및 API 미호출로 처리한다.
|
||||
- Dialog 문구는 7.6의 ko/en/ja 문구로 확정하며 관련 열린 질문은 없다.
|
||||
|
||||
Reference in New Issue
Block a user