feat(home): 팔로잉 전체 버튼을 고정한다

This commit is contained in:
Yu Sung
2026-08-18 13:59:03 +09:00
parent 9339a22a7d
commit b1cdbfe013
4 changed files with 199 additions and 33 deletions

View File

@@ -16,6 +16,7 @@ struct MainHomeFollowingCreatorSection: View {
} }
var body: some View { var body: some View {
HStack(alignment: .top, spacing: SodaSpacing.s12) {
ScrollView(.horizontal, showsIndicators: false) { ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(alignment: .top, spacing: SodaSpacing.s12) { LazyHStack(alignment: .top, spacing: SodaSpacing.s12) {
ForEach(followingCreators) { creator in ForEach(followingCreators) { creator in
@@ -29,21 +30,20 @@ struct MainHomeFollowingCreatorSection: View {
} }
.frame(width: 72) .frame(width: 72)
} }
}
.padding(.leading, SodaSpacing.s20)
}
.frame(maxWidth: .infinity, alignment: .leading)
Button(action: onTapAll) { Button(action: onTapAll) {
Text(I18n.HomeFollowing.allButtonTitle) Text(I18n.HomeFollowing.allButtonTitle)
.appFont(.body4) .appFont(.body5)
.foregroundColor(Color.soda400) .foregroundColor(Color.soda400)
.padding(.horizontal, 16) .frame(width: 70, height: 102, alignment: .center)
.frame(height: allButtonHeight)
} }
.buttonStyle(.plain) .buttonStyle(.plain)
} }
.padding(.horizontal, SodaSpacing.s20)
} }
}
private var allButtonHeight: CGFloat { 72 + SodaSpacing.s8 + 20 }
} }
struct MainHomeFollowingCreatorSection_Previews: PreviewProvider { struct MainHomeFollowingCreatorSection_Previews: PreviewProvider {

View File

@@ -20,6 +20,7 @@
- 팔로잉 탭 전체 empty 문구는 `팔로잉 소식이 아직 없어요.\n관심 있는 크리에이터를 팔로우해 보세요.`를 사용하고 `I18n.HomeFollowing.emptyStateMessage`로 다국어 처리한다. - 팔로잉 탭 전체 empty 문구는 `팔로잉 소식이 아직 없어요.\n관심 있는 크리에이터를 팔로우해 보세요.`를 사용하고 `I18n.HomeFollowing.emptyStateMessage`로 다국어 처리한다.
- API 실패 문구는 `팔로잉 정보를 불러오지 못했습니다.\n잠시 후 다시 시도해 주세요.`를 사용한다. - API 실패 문구는 `팔로잉 정보를 불러오지 못했습니다.\n잠시 후 다시 시도해 주세요.`를 사용한다.
- 섹션별 배열이 비어 있으면 해당 섹션은 숨긴다. 팔로잉 크리에이터 섹션도 예외 없이 `followingCreators`가 비어 있으면 `전체` 버튼까지 함께 숨긴다. - 섹션별 배열이 비어 있으면 해당 섹션은 숨긴다. 팔로잉 크리에이터 섹션도 예외 없이 `followingCreators`가 비어 있으면 `전체` 버튼까지 함께 숨긴다.
- 팔로잉 크리에이터 목록만 가로로 스크롤하고 `전체` 버튼은 추천 탭 현재 라이브 섹션과 동일한 배치와 스타일로 오른쪽 끝에 고정한다.
- 모든 뷰의 루트 container와 섹션 container에는 불필요한 고정 숫자 width/height를 사용하지 않는다. - 모든 뷰의 루트 container와 섹션 container에는 불필요한 고정 숫자 width/height를 사용하지 않는다.
- 프로필 이미지, 썸네일, 아이콘, tag, 최소 터치 영역처럼 UI 의미상 크기가 정해진 요소에만 고정 크기를 사용한다. - 프로필 이미지, 썸네일, 아이콘, tag, 최소 터치 영역처럼 UI 의미상 크기가 정해진 요소에만 고정 크기를 사용한다.
- 외부 라이브러리는 추가하지 않는다. - 외부 라이브러리는 추가하지 않는다.
@@ -532,6 +533,54 @@
- 실행 명령: `rg "if !response\\.followingCreators\\.isEmpty|MainHomeFollowingCreatorSection" SodaLive/Sources/V2/Main/Home/Following/MainHomeFollowingView.swift` - 실행 명령: `rg "if !response\\.followingCreators\\.isEmpty|MainHomeFollowingCreatorSection" SodaLive/Sources/V2/Main/Home/Following/MainHomeFollowingView.swift`
- 기대 결과: empty 문구의 ko/en/ja 다국어 처리와 팔로잉 크리에이터 빈 배열 시 섹션 렌더링 차단이 확인된다. - 기대 결과: empty 문구의 ko/en/ja 다국어 처리와 팔로잉 크리에이터 빈 배열 시 섹션 렌더링 차단이 확인된다.
### Phase 15: 팔로잉 크리에이터 전체 아이템 고정 및 스타일 통일
**Phase 결과:** 팔로잉 크리에이터 목록만 가로로 스크롤하고 `전체` 아이템은 추천 탭 현재 라이브 섹션과 동일한 배치와 스타일로 오른쪽 끝에 고정된다.
**선행조건:** `DEC-015` 확정 및 Phase 14 완료.
#### Task 15.1: 전체 아이템 배치와 스타일 통일
**Goal 실행 `P15-T1`:** 팔로잉 크리에이터 `전체` 아이템을 추천 라이브 `전체` 아이템과 동일하게 고정 표시한다.
- **시작 조건:** PRD §7.3, §12와 `DEC-015` 확인.
- **완료 증거:** 정적 구조 확인, 시뮬레이터 빌드 성공, 수동 스크롤 확인.
- **범위 밖:** 크리에이터 아이템 스타일, 전체 목록 라우팅, 추천 라이브 섹션 수정, 공용 컴포넌트 추출.
- **TDD 예외 사유:** 테스트 타깃이 없는 SwiftUI 단일 레이아웃·스타일 변경이다.
- **대체 검증 방법:** 소스 구조 검색, 시뮬레이터 빌드, 팔로잉 크리에이터 목록 스크롤 전후 화면 확인을 사용한다.
**Files:**
- Modify: `SodaLive/Sources/V2/Main/Home/Following/Components/MainHomeFollowingCreatorSection.swift`
- Reference: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeLiveSection.swift`
- [x] 루트에 `HStack(alignment: .top, spacing: SodaSpacing.s12)`을 두고 가로 `ScrollView``전체` 버튼을 형제로 분리한다.
- [x] 가로 `ScrollView``LazyHStack`에는 `followingCreators` 아이템만 두고 `.padding(.leading, SodaSpacing.s20)``.frame(maxWidth: .infinity, alignment: .leading)`을 적용한다.
- [x] `전체` 버튼은 스크롤 밖에서 `.appFont(.body5)`, `Color.soda400`, `.frame(width: 70, height: 102, alignment: .center)`, `.buttonStyle(.plain)`을 사용한다.
- [x] `전체` 버튼에 별도 오른쪽 padding을 두지 않고 기존 `onTapAll()` 및 크리에이터 `onTapCreator` 동작을 유지한다.
- [x] `followingCreators`가 비어 있을 때 섹션 전체가 숨겨지는 상위 분기와 `.followingList` 라우팅을 변경하지 않는다.
검증 기준:
```bash
rg -n "HStack\(alignment: \.top, spacing: SodaSpacing\.s12\)|ScrollView\(\.horizontal|padding\(\.leading, SodaSpacing\.s20\)|frame\(maxWidth: \.infinity, alignment: \.leading\)|appFont\(\.body5\)|frame\(width: 70, height: 102, alignment: \.center\)|buttonStyle\(\.plain\)" SodaLive/Sources/V2/Main/Home/Following/Components/MainHomeFollowingCreatorSection.swift
xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug -destination "generic/platform=iOS Simulator" CODE_SIGNING_ALLOWED=NO build
```
**Expected:** 정적 검색에서 추천 라이브와 동일한 분리 배치 및 `전체` 스타일이 확인되고 빌드가 성공한다.
수동 검증:
- [x] 크리에이터 목록을 좌우로 스크롤해도 `전체` 아이템이 화면 오른쪽 끝에 유지된다.
- [x] `전체` 아이템의 글꼴, 색상, 크기, 중앙 정렬과 우측 여백이 추천 탭 현재 라이브 섹션과 동일하다.
- [x] 크리에이터와 `전체` 아이템 탭 동작이 기존과 동일하다.
### Phase 15 완료 조건
- [x] `P15-T1` 체크박스와 완료 증거가 모두 충족됐다.
- [x] PRD §7.3, §12 및 `DEC-015`와 구현 차이가 없다.
- [x] 검증 결과가 아래 검증 기록에 누적됐다.
## 검증 기록 ## 검증 기록
- 2026-06-30: `docs/agent-guides/documentation-policy.md`, `build-test-verification.md`, `code-style.md`를 확인해 계획 문서 경로, Phase/checklist 형식, 검증 명령 기준을 반영했다. - 2026-06-30: `docs/agent-guides/documentation-policy.md`, `build-test-verification.md`, `code-style.md`를 확인해 계획 문서 경로, Phase/checklist 형식, 검증 명령 기준을 반영했다.
@@ -632,3 +681,11 @@
- 2026-07-13: PRD와 plan-task의 기존 “크리에이터가 없어도 `전체` 버튼 표시” 요구사항을 “크리에이터가 있을 때만 섹션과 `전체` 버튼 표시”로 갱신했다. - 2026-07-13: PRD와 plan-task의 기존 “크리에이터가 없어도 `전체` 버튼 표시” 요구사항을 “크리에이터가 있을 때만 섹션과 `전체` 버튼 표시”로 갱신했다.
- 2026-07-13: `git diff --check -- SodaLive/Sources/V2/Main/Home/Following/MainHomeFollowingView.swift docs/20260630_메인_홈_팔로잉_탭/prd.md docs/20260630_메인_홈_팔로잉_탭/plan-task.md` 실행 결과 출력 없이 종료되어 변경 파일 공백 오류가 없음을 확인했다. - 2026-07-13: `git diff --check -- SodaLive/Sources/V2/Main/Home/Following/MainHomeFollowingView.swift docs/20260630_메인_홈_팔로잉_탭/prd.md docs/20260630_메인_홈_팔로잉_탭/plan-task.md` 실행 결과 출력 없이 종료되어 변경 파일 공백 오류가 없음을 확인했다.
- 2026-07-13: 샌드박스 안의 `xcodebuild`는 Xcode/CoreSimulator/DerivedData/SwiftPM 캐시 접근 제한으로 실패했으나, 승인 후 샌드박스 밖에서 `xcodebuild -workspace SodaLive.xcworkspace -scheme SodaLive -configuration Debug -destination generic/platform=iOS\ Simulator -derivedDataPath /private/tmp/SodaLiveDerivedDataFollowingEmpty CODE_SIGNING_ALLOWED=NO build`를 실행해 `BUILD SUCCEEDED`를 확인했다. 기존 duplicate build file/dependency scan warning과 `LiveRoomViewModel`의 unused variable warning은 남아 있으나 컴파일 오류는 없었다. - 2026-07-13: 샌드박스 안의 `xcodebuild`는 Xcode/CoreSimulator/DerivedData/SwiftPM 캐시 접근 제한으로 실패했으나, 승인 후 샌드박스 밖에서 `xcodebuild -workspace SodaLive.xcworkspace -scheme SodaLive -configuration Debug -destination generic/platform=iOS\ Simulator -derivedDataPath /private/tmp/SodaLiveDerivedDataFollowingEmpty CODE_SIGNING_ALLOWED=NO build`를 실행해 `BUILD SUCCEEDED`를 확인했다. 기존 duplicate build file/dependency scan warning과 `LiveRoomViewModel`의 unused variable warning은 남아 있으나 컴파일 오류는 없었다.
- 2026-08-18: 사용자 인터뷰로 팔로잉 크리에이터 `전체` 아이템의 배치와 스타일을 추천 탭 현재 라이브 섹션과 모두 통일하기로 확정하고 Phase 15를 추가했다. 이번 작업은 문서 작성만 수행하며 `P15-T1` 구현 체크박스는 미완료로 유지한다.
- 2026-08-18: `git diff --check -- docs/20260630_메인_홈_팔로잉_탭/prd.md docs/20260630_메인_홈_팔로잉_탭/plan-task.md`는 출력 없이 성공했고, `git diff --name-only`에서 위 두 문서만 변경된 것을 확인했다.
- 2026-08-18: `P15-T1` 구현으로 `MainHomeFollowingCreatorSection`의 가로 `ScrollView`에는 크리에이터 아이템만 남기고, `전체` 버튼을 루트 `HStack`의 우측 형제로 분리했다. `전체` 스타일은 추천 라이브와 동일한 `.body5`, `Color.soda400`, `70x102pt`, 중앙 정렬, 별도 우측 여백 없음으로 변경했다.
- 2026-08-18: Phase 15 정적 `rg` 검증에서 `HStack`, 가로 `ScrollView`, leading 20pt, 최대 너비, `.body5`, `70x102pt`, plain button 패턴을 모두 확인했고 `git diff --check`는 출력 없이 성공했다.
- 2026-08-18: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug -destination "generic/platform=iOS Simulator" CODE_SIGNING_ALLOWED=NO build`를 실행해 `BUILD SUCCEEDED`를 확인했다. 기존 Crashlytics dSYM, AppIntents metadata, Alamofire dependency scan warning은 남아 있으나 컴파일 오류는 없었다.
- 2026-08-18: 사용자 요청에 따라 visual-qa는 수행하지 않았다. 크리에이터 목록 스크롤 중 `전체` 고정, 추천 라이브와의 스타일 일치, 크리에이터/전체 탭 동작은 사용자 수동 검증 대기로 남긴다.
- 2026-08-18: `reviews/phase15-following-creator-all-item.md`에 Phase 15 리뷰 결과를 기록했다. 1차 리뷰의 PRD 이전 표현 3곳을 정정하고 Oracle 재검토 승인을 받았으며, 남은 항목은 사용자 수동 UI 검증이다.
- 2026-08-18: 사용자가 Phase 15 수동 테스트 완료를 확인했다. 스크롤 중 `전체` 우측 고정, 추천 라이브와의 스타일 일치, 크리에이터/`전체` 탭 동작 확인 항목을 완료 처리하고 `P15-T1` 및 Phase 15 완료 조건을 충족 상태로 갱신했다.

View File

@@ -26,7 +26,7 @@ Figma 전체 화면 기준 섹션 순서는 아래를 따른다.
- 기존 V2 공용 컴포넌트와 추천/랭킹 탭 패턴을 우선 재사용한다. - 기존 V2 공용 컴포넌트와 추천/랭킹 탭 패턴을 우선 재사용한다.
- 홈 상단 `팔로잉` 탭 터치 시 로그인 guard를 먼저 적용해 로그인된 사용자만 탭으로 이동한다. - 홈 상단 `팔로잉` 탭 터치 시 로그인 guard를 먼저 적용해 로그인된 사용자만 탭으로 이동한다.
- `isLoginRequired == true`이면 팔로잉 기반 콘텐츠 대신 로그인 필요 상태를 표시하고, 사용자가 로그인 화면으로 이동할 수 있어야 한다. - `isLoginRequired == true`이면 팔로잉 기반 콘텐츠 대신 로그인 필요 상태를 표시하고, 사용자가 로그인 화면으로 이동할 수 있어야 한다.
- 팔로잉 크리에이터가 있을 때만 팔로잉 크리에이터 섹션을 표시하고, 가로 목록 마지막 item에는 `전체` 버튼을 추가한다. - 팔로잉 크리에이터가 있을 때만 팔로잉 크리에이터 섹션을 표시하고, 가로 목록과 분리된 `전체` 버튼을 섹션 오른쪽 끝에 고정한다.
- 최근 소식은 `FollowingNewsType`별로 다른 View를 표시한다. - 최근 소식은 `FollowingNewsType`별로 다른 View를 표시한다.
- 각 섹션은 이후 `plan-task.md` 작성 시 Figma Design 기준 섹션당 1개의 Phase로 나눌 수 있도록 요구사항을 분리한다. - 각 섹션은 이후 `plan-task.md` 작성 시 Figma Design 기준 섹션당 1개의 Phase로 나눌 수 있도록 요구사항을 분리한다.
- 뷰 전체는 반드시 필요한 경우를 제외하고 고정 숫자 width/height를 갖지 않는다. - 뷰 전체는 반드시 필요한 경우를 제외하고 고정 숫자 width/height를 갖지 않는다.
@@ -46,7 +46,7 @@ Figma 전체 화면 기준 섹션 순서는 아래를 따른다.
## 6. User Stories ## 6. User Stories
- 사용자는 홈 `팔로잉` 탭에서 내가 팔로우한 크리에이터 목록을 보고 싶다. - 사용자는 홈 `팔로잉` 탭에서 내가 팔로우한 크리에이터 목록을 보고 싶다.
- 사용자는 팔로잉 크리에이터 목록 끝의 `전체` 버튼으로 전체 팔로잉 목록을 보고 싶다. - 사용자는 팔로잉 크리에이터 섹션 오른쪽 끝에 고정된 `전체` 버튼으로 전체 팔로잉 목록을 보고 싶다.
- 사용자는 팔로우한 크리에이터가 라이브 중이면 `On Air` 섹션에서 바로 진입하고 싶다. - 사용자는 팔로우한 크리에이터가 라이브 중이면 `On Air` 섹션에서 바로 진입하고 싶다.
- 사용자는 최근 대화 섹션에서 최근 채팅방을 확인하고 이어서 대화하고 싶다. - 사용자는 최근 대화 섹션에서 최근 채팅방을 확인하고 이어서 대화하고 싶다.
- 사용자는 이달의 스케줄에서 예정된 라이브/콘텐츠와 On Air 여부를 확인하고 싶다. - 사용자는 이달의 스케줄에서 예정된 라이브/콘텐츠와 On Air 여부를 확인하고 싶다.
@@ -351,11 +351,9 @@ Figma 참조:
- 각 item은 프로필 이미지와 크리에이터 닉네임을 표시한다. - 각 item은 프로필 이미지와 크리에이터 닉네임을 표시한다.
- 크리에이터 item 탭 시 `creatorId`로 기존 크리에이터 상세 화면에 진입한다. - 크리에이터 item 탭 시 `creatorId`로 기존 크리에이터 상세 화면에 진입한다.
- `followingCreators`가 비어 있으면 팔로잉 크리에이터 섹션을 표시하지 않는다. - `followingCreators`가 비어 있으면 팔로잉 크리에이터 섹션을 표시하지 않는다.
- 목록 마지막 item에는 `followingCreators`가 있을 때만 `전체` 버튼을 추가한다. - `followingCreators` 목록만 가로로 스크롤하고 `전체` 버튼은 스크롤 위치와 관계없이 섹션 오른쪽 끝에 고정한다.
- `전체` 버튼의 width는 버튼이 차지하는 콘텐츠 크기 기준으로 잡고, 고정 화면 width를 강제하지 않는다. - `전체` 버튼은 추천 탭 현재 라이브 섹션의 `MainHomeLiveAllItemView`와 동일하게 `.appFont(.body5)`, `Color.soda400`, `70x102pt`, 중앙 정렬을 사용한다.
- `전체` 버튼 height는 크리에이터 item 높이와 동일하게 표시한다. - `전체` 버튼에는 별도 오른쪽 여백을 적용하지 않는다.
- `전체` 버튼은 `paddingHorizontal = 16`을 적용한다.
- `전체` 버튼 text color는 `Soda/400`이며, 코드에서는 `Color.soda400`을 사용한다.
- `전체` 버튼 탭 시 기존에 만들어진 전체 팔로잉 목록 화면으로 이동한다. - `전체` 버튼 탭 시 기존에 만들어진 전체 팔로잉 목록 화면으로 이동한다.
### 7.4 On Air 섹션 ### 7.4 On Air 섹션
@@ -458,7 +456,7 @@ Figma 참조:
- 홈 공통 title bar - 홈 공통 title bar
- 홈 상단 `추천`/`랭킹`/`팔로잉` Text tab bar - 홈 상단 `추천`/`랭킹`/`팔로잉` Text tab bar
- 선택된 `팔로잉` 탭 콘텐츠 - 선택된 `팔로잉` 탭 콘텐츠
- 팔로잉 크리에이터 가로 목록과 마지막 `전체` 버튼 - 팔로잉 크리에이터 가로 목록과 오른쪽 끝에 고정된 `전체` 버튼
- `On Air` 가로 라이브 목록 - `On Air` 가로 라이브 목록
- 최근 대화 목록 - 최근 대화 목록
- 이달의 스케줄 목록 - 이달의 스케줄 목록
@@ -541,9 +539,9 @@ Figma 참조:
- `isLoginRequired == false`이면 Figma 순서대로 팔로잉 크리에이터, On Air, 최근 대화, 이달의 스케줄, 최근 소식 섹션이 표시된다. - `isLoginRequired == false`이면 Figma 순서대로 팔로잉 크리에이터, On Air, 최근 대화, 이달의 스케줄, 최근 소식 섹션이 표시된다.
- 비어 있는 섹션은 표시되지 않는다. - 비어 있는 섹션은 표시되지 않는다.
- 모든 섹션 데이터가 비어 있으면 전체 empty state가 표시된다. - 모든 섹션 데이터가 비어 있으면 전체 empty state가 표시된다.
- 팔로잉 크리에이터가 있으면 가로 목록 마지막에 `전체` 버튼이 표시된다. - 팔로잉 크리에이터가 있으면 크리에이터 목록만 가로로 스크롤되고 `전체` 버튼은 섹션 오른쪽 끝에 고정된다.
- 팔로잉 크리에이터가 없으면 팔로잉 크리에이터 섹션과 `전체` 버튼은 표시되지 않는다. - 팔로잉 크리에이터가 없으면 팔로잉 크리에이터 섹션과 `전체` 버튼은 표시되지 않는다.
- `전체` 버튼은 크리에이터 item 높이와 동일하고, horizontal padding 16, `Color.soda400` 텍스트를 사용한다. - `전체` 버튼은 추천 탭 현재 라이브 섹션과 동일한 `.body5`, `70x102pt`, `Color.soda400`, 중앙 정렬 스타일을 사용하고 별도 오른쪽 여백을 두지 않는다.
- 최근 소식의 `CREATOR_RANKING``creatorRanking` payload로 랭킹 소식 카드가 표시된다. - 최근 소식의 `CREATOR_RANKING``creatorRanking` payload로 랭킹 소식 카드가 표시된다.
- 최근 소식의 `CONTENT_RANKING``contentRanking` payload로 랭킹 소식 카드가 표시된다. - 최근 소식의 `CONTENT_RANKING``contentRanking` payload로 랭킹 소식 카드가 표시된다.
- 최근 소식의 `COMMUNITY_POST``communityPost` payload로 기존 커뮤니티 Feed View 또는 표시 전용 variant가 표시된다. - 최근 소식의 `COMMUNITY_POST``communityPost` payload로 기존 커뮤니티 Feed View 또는 표시 전용 variant가 표시된다.
@@ -571,3 +569,10 @@ Figma 참조:
- 사용자 답변을 반영해 `ChatRoomListItemResponse`, `CreatorActivityType`, nested 최근 소식 response 구조, `visibleFromAtUtc` 시간 표시 기준, 기존 전체 팔로잉 목록 화면 재사용, 팔로잉 탭 선택 시 로그인 guard 정책을 확정 요구사항으로 이동했다. - 사용자 답변을 반영해 `ChatRoomListItemResponse`, `CreatorActivityType`, nested 최근 소식 response 구조, `visibleFromAtUtc` 시간 표시 기준, 기존 전체 팔로잉 목록 화면 재사용, 팔로잉 탭 선택 시 로그인 guard 정책을 확정 요구사항으로 이동했다.
- empty state 문구를 `팔로잉 소식이 아직 없어요.\n관심 있는 크리에이터를 팔로우해 보세요.`, API 실패 문구를 `팔로잉 정보를 불러오지 못했습니다.\n잠시 후 다시 시도해 주세요.`로 확정했다. - empty state 문구를 `팔로잉 소식이 아직 없어요.\n관심 있는 크리에이터를 팔로우해 보세요.`, API 실패 문구를 `팔로잉 정보를 불러오지 못했습니다.\n잠시 후 다시 시도해 주세요.`로 확정했다.
- 2026-07-12: 현재 코드의 `AppStep.creatorChannelCommunityPostDetail(postId:onCommunityRefresh:)`, `CreatorChannelCommunityPostDetailView(postId:onCommunityRefresh:)`, `/api/v2/creator-channels/community-posts/{postId}` 흐름을 확인해 `COMMUNITY_POST` tap을 `postId` 단독 상세 진입으로 연결하도록 요구사항을 갱신했다. - 2026-07-12: 현재 코드의 `AppStep.creatorChannelCommunityPostDetail(postId:onCommunityRefresh:)`, `CreatorChannelCommunityPostDetailView(postId:onCommunityRefresh:)`, `/api/v2/creator-channels/community-posts/{postId}` 흐름을 확인해 `COMMUNITY_POST` tap을 `postId` 단독 상세 진입으로 연결하도록 요구사항을 갱신했다.
- 2026-08-18: `MainHomeFollowingCreatorSection``전체` 버튼은 가로 `ScrollView` 내부에 있고 `.body4`, 가변 너비, 100pt 높이, 우측 20pt 여백을 사용하지만, 추천 탭 `MainHomeLiveSection``전체` 버튼은 스크롤 밖에 고정되고 `.body5`, `70x102pt`, 별도 우측 여백 없음임을 확인했다.
## 15. Decision Log
| 날짜 | ID | 상태 | 결정 | 근거 | 영향 요구사항·Goal |
|---|---|---|---|---|---|
| 2026-08-18 | `DEC-015` | 확정 | 팔로잉 크리에이터 `전체` 버튼의 배치와 스타일을 추천 탭 현재 라이브 `전체` 버튼과 통일한다. | 사용자 인터뷰에서 배치와 스타일 모두 통일하기로 결정했다. | §7.3, §12, `P15-T1` |

View File

@@ -0,0 +1,104 @@
# Phase 15 팔로잉 크리에이터 전체 아이템 리뷰
## 1. 리뷰 정보
| 항목 | 내용 |
|---|---|
| 리뷰 대상 | Phase 15 / `P15-T1` |
| 기준 commit 또는 working tree | 현재 `main` working tree |
| 리뷰 일자 | 2026-08-18 |
| 리뷰어 | Oracle, Sisyphus |
| 기준 문서 | `docs/20260630_메인_홈_팔로잉_탭/prd.md`, `plan-task.md` |
| 리뷰 상태 | 수정 검증 완료 |
## 2. 리뷰 목적과 범위
### 목적
- 팔로잉 크리에이터 목록만 스크롤하고 `전체` 아이템이 우측에 고정되는지 확인한다.
- `전체` 아이템의 배치와 스타일이 추천 탭 현재 라이브 섹션과 일치하는지 확인한다.
### 포함 범위
- 코드: `SodaLive/Sources/V2/Main/Home/Following/Components/MainHomeFollowingCreatorSection.swift`
- 비교 기준: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeLiveSection.swift`
- 문서: PRD §7.3, §12, `DEC-015`, `plan-task.md` Phase 15
- 검증: 정적 구조 검사, diff 검사, iOS Simulator 빌드
### 제외 범위
- 사용자가 직접 수행하기로 한 visual-qa와 실제 기기·시뮬레이터 수동 UI 검증
- 추천 라이브 섹션, 전체 목록 라우팅, 크리에이터 아이템 스타일 변경
## 3. 판정 기준
- Blocker/High: 확정 요구사항 위반 또는 기존 탭 동작 회귀
- Medium: 제한된 조건의 기능·접근성 문제
- Low: 문서 정합성 또는 비핵심 유지보수 문제
## 4. 검토한 근거
- `MainHomeFollowingCreatorSection.swift:19-45`: `ScrollView``전체` 버튼이 루트 `HStack`의 형제다.
- `MainHomeFollowingCreatorSection.swift:38-44`: `.body5`, `Color.soda400`, `70x102pt`, 중앙 정렬, 우측 padding 없음이 적용됐다.
- `MainHomeFollowingView.swift:61-67`: 빈 배열이면 섹션 전체를 숨기는 기존 분기가 유지된다.
| 명령 또는 수동 검증 | 결과 | 핵심 증거 |
|---|---|---|
| Phase 15 정적 `rg` | 성공 | 요구한 배치·스타일 패턴 8개 확인 |
| `git diff --check` | 성공 | 출력 없음 |
| `xcodebuild ... -destination "generic/platform=iOS Simulator" CODE_SIGNING_ALLOWED=NO build` | 성공 | `BUILD SUCCEEDED` |
| 수동 UI 검증 | 사용자 확인 대기 | visual-qa 생략 요청 반영 |
## 5. 발견 사항 요약
| ID | 심각도 | 상태 | 제목 | 소유 Task | 후속 goal |
|---|---|---|---|---|---|
| `REV-P15-001` | Low | 수정 완료 | PRD에 이전 “목록 마지막” 표현 잔존 | `P15-T1` | 없음 |
## 6. 발견 사항 상세
### REV-P15-001 — PRD의 이전 배치 표현
- **심각도:** Low
- **상태:** 수정 완료
- **관련 요구사항:** PRD §7.3, §12, `DEC-015`
- **소유 Task:** `P15-T1`
Oracle 1차 리뷰에서 PRD Goals, User Stories, UI 범위의 “목록 마지막/목록 끝” 표현이 우측 고정 요구사항과 충돌함을 확인했다. 세 문장을 “가로 목록과 분리되어 섹션 오른쪽 끝에 고정”으로 정정했고, 이전 표현 검색 결과가 없으며 Oracle 재검토 승인을 받았다.
## 7. 확정 항목의 plan·goal 전환
전환 항목 없음. production 코드 문제가 아닌 문서 정합성 항목으로 리뷰 중 수정과 검증을 완료했다.
## 8. 리뷰 종료 판정
| 판정 항목 | 결과 | 근거 |
|---|---|---|
| 리뷰 범위 전체 확인 | 충족 | 코드·PRD·계획 대조 완료 |
| 후보 항목 판정 완료 | 충족 | `REV-P15-001` 수정 완료 |
| 확정 항목 plan 반영 | 해당 없음 | 신규 production 수정 불필요 |
| 검증 명령과 결과 기록 | 충족 | 정적 검사, diff, 빌드 결과 기록 |
**최종 결론:** 수정 검증 완료
**남은 항목:** 없음
## 9. 수정 후 검증 기록
### 1차 수정 검증 — 2026-08-18
- 무엇을: `REV-P15-001`의 PRD 충돌 표현 3곳을 정정했다.
- 왜: 우측 고정 요구사항과 이전 “목록 마지막” 표현의 충돌을 제거하기 위해서다.
- 어떻게:
- 이전 표현 `rg` 검사 — 결과 없음
- `git diff --check` — 성공, 출력 없음
- Oracle 재검토 — 승인
- 남은 항목: 사용자 수동 UI 검증
### 2차 수동 검증 — 2026-08-18
- 무엇을: 스크롤 중 `전체` 고정, 추천 라이브와의 스타일 일치, 크리에이터/`전체` 탭 동작을 확인했다.
- 왜: Phase 15의 남은 수동 UI 수용 기준을 종료하기 위해서다.
- 어떻게:
- 사용자 수동 테스트 — 완료 확인
- 남은 항목: 없음