fix(main): 추천 홈 후속 검증을 보완한다
This commit is contained in:
@@ -42,7 +42,7 @@
|
||||
- `SodaLive/Sources/V2/Main/Home/Recommendation/Repository/MainHomeRecommendationRepository.swift`
|
||||
- `SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationViewModel.swift`
|
||||
- `SodaLive/Sources/V2/Component/Card/CommunityPostCard.swift`
|
||||
- `SodaLive/Sources/V2/Component/Text/ExpandableTextView.swift`
|
||||
- `SodaLive/Sources/V2/Component/Text/V2ExpandableTextView.swift`
|
||||
- `SodaLive/Sources/I18n/I18n.swift`
|
||||
- `SodaLive.xcodeproj/project.pbxproj`
|
||||
|
||||
@@ -125,6 +125,23 @@
|
||||
- 실행 명령: `rg "roomId|creatorProfileImage|targetId|totalChatCount|originalWorkTitle|audioUrl" SodaLive/Sources/V2/Main/Home/Recommendation/Models/MainHomeRecommendationResponse.swift`
|
||||
- 기대 결과: PRD 핵심 필드가 모델에 반영되어야 한다.
|
||||
|
||||
- [x] **Task 2.3: PRD 응답 계약에 없는 필수 디코딩 필드 제거**
|
||||
- Goal 실행 `P2-R1`: `REV-P2-001`을 수정해 PRD 기준 추천 응답이 `firstAudioContents` 없이도 정상 디코딩되게 한다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase2-recommendation-api-response-model.md`
|
||||
- 확정 항목: `REV-P2-001`
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive/Sources/V2/Main/Home/Recommendation/Models/MainHomeRecommendationResponse.swift`
|
||||
- TDD 예외 사유:
|
||||
- 앱 테스트 번들 타깃이 없어 production 모델을 직접 import하는 영구 unit test를 이번 Task에서 추가할 수 없다.
|
||||
- 대체 검증 방법:
|
||||
- PRD의 필수 필드만 포함하고 `firstAudioContents`가 없는 JSON으로 디코딩 회귀를 확인하고, 정적 검색과 앱 빌드를 실행한다.
|
||||
- 작업 내용:
|
||||
- [x] 현재 모델이 기준 JSON에서 `keyNotFound(firstAudioContents)`로 실패하는 것을 재현한다.
|
||||
- [x] 실제 사용 경로와 PRD 계약이 없는 `firstAudioContents` 및 `HomeFirstAudioContentItem`을 제거한다.
|
||||
- [x] 기준 JSON 디코딩, `rg "firstAudioContents|HomeFirstAudioContentItem" SodaLive/Sources/V2/Main/Home/Recommendation`, `git diff --check`, `SodaLive-dev` Debug 빌드를 통과한다.
|
||||
- [x] 수정 결과와 실제 명령을 검증 기록에 누적한다.
|
||||
|
||||
### Phase 3: 활동 타입과 I18n
|
||||
|
||||
- [x] **Task 3.1: RecommendedActivityType 변환 보완**
|
||||
@@ -157,6 +174,23 @@
|
||||
- 실행 명령: `rg "final class MainHomeRecommendationViewModel|fetchRecommendations|HomeRecommendationResponse|MainHomeRecommendationRepository|isLoading|errorMessage" SodaLive/Sources/V2/Main/Home`
|
||||
- 기대 결과: 추천 API 로딩/에러/응답 상태가 `MainHomeRecommendationViewModel` 중심으로 정리되어야 한다.
|
||||
|
||||
- [x] **Task 4.2: 추천 응답 디코딩 오류 로그를 프로젝트 로깅 규칙에 맞춤**
|
||||
- Goal 실행 `P4-R1`: `REV-P4-001`을 수정해 신규 추천 ViewModel의 디코딩 오류가 `print`가 아니라 프로젝트 오류 로그 경로로 기록되게 한다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase4-recommendation-state-layer.md`
|
||||
- 확정 항목: `REV-P4-001`
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationViewModel.swift`
|
||||
- TDD 예외 사유:
|
||||
- 사용자 동작을 바꾸지 않는 오류 로그 호출 교체이며 앱 테스트 번들 타깃이 없다.
|
||||
- 대체 검증 방법:
|
||||
- 현재 `print(error)` 사용을 정적 재현하고 프로젝트 `ERROR_LOG` 관례와 대조한 뒤 정적 검색과 앱 빌드로 확인한다.
|
||||
- 작업 내용:
|
||||
- [x] 추천 응답 디코딩 `catch`의 `print(error)`를 실패 근거로 확인한다.
|
||||
- [x] 기존 toast·loading 처리는 유지하고 오류 기록만 `ERROR_LOG(error.localizedDescription)`로 교체한다.
|
||||
- [x] 추천 범위의 `print(` 미사용, `ERROR_LOG` 사용, `git diff --check`와 `SodaLive-dev` Debug 빌드를 확인한다.
|
||||
- [x] 수정 결과와 실제 명령을 이 문서와 Phase 4 리뷰 리포트에 누적한다.
|
||||
|
||||
### Phase 5: 추천 상세 진입 데이터/라우팅 guard
|
||||
|
||||
- [x] **Task 5.1: 추천 탭 상세 진입 guard 적용**
|
||||
@@ -180,6 +214,63 @@
|
||||
- 기대 결과: 신규 추천 탭 상세 진입 callback이 기존 인증/민감 콘텐츠 guard 인프라를 재사용한다.
|
||||
- 수동 확인: `MainHomeView`, `MainHomeRecommendationView` 내부에 Bootpay 인증 UI를 중복 구현하지 않아야 한다.
|
||||
|
||||
- [x] **Task 5.2: AI 캐릭터 상세 라우팅과 guard 연결**
|
||||
- Goal 실행 `P5-R1`: `REV-P5-001`을 수정해 추천 AI 캐릭터 callback이 로그인·민감 콘텐츠 guard를 거쳐 `characterDetail(characterId:)`로 이동하게 한다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase5-detail-routing-guards.md`
|
||||
- 확정 항목: `REV-P5-001`
|
||||
- `Task 12.2`의 `characterId` 전달 보정과 함께 검증한다.
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive/Sources/V2/Main/MainView.swift`
|
||||
- 확인: `SodaLive/Sources/Home/HomeTabView.swift`
|
||||
- TDD 예외 사유:
|
||||
- 앱 테스트 번들 타깃이 없고 SwiftUI callback에서 전역 `AppState` route까지 확인하는 테스트 인프라 추가는 이번 회귀 수정 범위를 벗어난다.
|
||||
- 대체 검증 방법:
|
||||
- callback 연결 정적 검색, `SodaLive-dev` 빌드, `creatorId != characterId`인 항목의 수동 탭으로 검증한다.
|
||||
- 작업 내용:
|
||||
- [x] `onTapCharacter`가 `handleRecommendationCreatorTap`에 연결되어 크리에이터 상세로 이동하는 현재 실패 경로를 확인한다.
|
||||
- [x] 양수 `characterId`를 검증하고 기존 추천 상세 guard를 재사용해 `.characterDetail(characterId:)`를 실행하는 전용 handler를 연결한다.
|
||||
- [x] `rg "onTapCharacter:|handleRecommendationCharacterTap|characterDetail\\(characterId:" SodaLive/Sources/V2/Main/MainView.swift`, `git diff --check`, `SodaLive-dev` Debug 빌드를 통과한다.
|
||||
- [x] 비로그인·본인인증·민감 콘텐츠 설정·정상 진입 흐름은 기존 guard 재사용 정적 검색과 빌드로 확인하고, 실제 기기 수동 확인은 잔여 확인 사항으로 검증 기록에 남긴다.
|
||||
|
||||
- [x] **Task 5.3: 본인인증 후 민감 콘텐츠 설정 guard 재검사**
|
||||
- Goal 실행 `P5-R2`: `REV-P5-002`를 수정해 한국 사용자의 본인인증 성공 후에도 민감 콘텐츠 보기 설정을 확인한 뒤 AI 캐릭터 상세로 이동하게 한다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase5-detail-routing-guards.md`
|
||||
- 확정 항목: `REV-P5-002`
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive/Sources/V2/Main/MainView.swift`
|
||||
- TDD 예외 사유:
|
||||
- 앱 테스트 번들 타깃이 없고 Bootpay 본인인증 callback과 전역 `AppState` route를 직접 실행하는 영구 통합 test 인프라는 이번 회귀 수정 범위를 벗어난다.
|
||||
- 대체 검증 방법:
|
||||
- `token != empty`, 한국 사용자, `auth == false`, `isAdultContentVisible == false` 상태 전이를 최소 Swift self-check로 재현하고, 정적 callback 추적·앱 빌드·수동 상태 조합 확인으로 검증한다.
|
||||
- 작업 내용:
|
||||
- [x] **RED:** 본인인증 전 저장한 `pendingAction`이 인증 성공 callback에서 상세 route를 직접 실행해 민감 콘텐츠 설정 화면을 건너뛰는 현재 실패를 재현한다.
|
||||
- [x] **GREEN:** 인증 성공 후 보류 action이 상세 route를 직접 실행하지 않고 기존 `performRecommendationDetailAction(requiresAdultContent: true)`의 남은 설정 guard를 다시 통과하도록 최소 수정한다.
|
||||
- [x] **REFACTOR:** 기존 로그인, 비한국 사용자, 이미 본인인증된 사용자, 민감 콘텐츠 설정 활성 사용자 흐름은 변경하지 않고 중복 guard를 추가하지 않는다.
|
||||
- [x] 한국 사용자 기준 `auth=false/설정=false`, `auth=false/설정=true`, `auth=true/설정=false`, `auth=true/설정=true` 조합과 취소·오류 시 보류 action 미실행을 확인한다.
|
||||
- [x] `git diff --check`, `plutil -lint SodaLive.xcodeproj/project.pbxproj`, `SodaLive-dev` Debug 빌드를 실행하고 결과를 이 문서와 Phase 5 리뷰 리포트에 누적한다.
|
||||
|
||||
- [x] **Task 5.4: 활성 민감 콘텐츠 진입 경로의 인증 후 설정 guard 재검사**
|
||||
- Goal 실행 `P5-R3`: `REV-P5-003`을 수정해 라이브 전체 화면의 성인 라이브와 크리에이터 채널 AI 대화도 본인인증 성공 후 민감 콘텐츠 보기 설정을 다시 확인하게 한다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase5-detail-routing-guards.md`
|
||||
- 확정 항목: `REV-P5-003`
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive/Sources/Live/Now/All/LiveNowAllView.swift`
|
||||
- 수정: `SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift`
|
||||
- 확인: `SodaLive/Sources/ContentView.swift`
|
||||
- TDD 예외 사유:
|
||||
- 앱 테스트 번들 타깃이 없고 Bootpay 본인인증 callback과 전역 route를 직접 실행하는 영구 통합 test 인프라는 이번 회귀 수정 범위를 벗어난다.
|
||||
- 대체 검증 방법:
|
||||
- 두 활성 화면의 `auth=false`, 민감 콘텐츠 설정 비활성 상태 전이를 최소 Swift self-check로 재현하고, callback 추적·앱 빌드·수동 상태 조합으로 확인한다.
|
||||
- 작업 내용:
|
||||
- [x] **RED:** `LiveNowAllView.handleLiveNowItemTap`과 `CreatorChannelView.handleTalkTap`이 인증 성공 후 설정 화면 없이 보호 route를 직접 실행하는 상태를 재현한다.
|
||||
- [x] **GREEN:** 각 화면의 `pendingAction`이 최종 route가 아니라 기존 진입 함수를 다시 호출해 남은 설정 guard를 통과하도록 최소 수정한다.
|
||||
- [x] **REFACTOR:** 공용 계층을 새로 만들지 않고 기존 로그인·국가·본인인증·설정 분기와 route를 유지한다.
|
||||
- [x] 두 화면에서 `auth=false/설정=false`, `auth=false/설정=true`, `auth=true/설정=false`, `auth=true/설정=true` 조합과 인증 취소·오류를 확인한다.
|
||||
- [x] `git diff --check`, `plutil -lint SodaLive.xcodeproj/project.pbxproj`, `SodaLive-dev`와 `SodaLive` Debug 빌드를 실행하고 결과를 이 문서와 Phase 5 리뷰 리포트에 누적한다.
|
||||
|
||||
### Phase 6: 홈 탭 shell과 탭별 루트 연결
|
||||
|
||||
- [x] **Task 6.1: 추천/랭킹/팔로잉 하위 폴더와 루트 View 준비**
|
||||
@@ -217,6 +308,26 @@
|
||||
- 실행 명령: `rg "case \\.home|MainHomeView|MainPlaceholderTabView" SodaLive/Sources/V2/Main/MainView.swift`
|
||||
- 기대 결과: `.home`은 `MainHomeView()`를 표시하고, 다른 탭은 기존 동작을 유지한다.
|
||||
|
||||
- [x] **Task 6.4: 홈 상단 탭 제목 현지화 연결**
|
||||
- Goal 실행 `P6-R1`: `REV-P6-001`을 수정해 추천/랭킹/팔로잉 탭 제목이 앱 언어 ko/en/ja에 맞게 표시되도록 한다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase6-home-tab-shell.md`
|
||||
- 확정 항목: `REV-P6-001`
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive/Sources/V2/Main/Home/MainHomeView.swift`
|
||||
- 확인: `SodaLive/Sources/I18n/I18n.swift`
|
||||
- TDD 예외 사유:
|
||||
- 앱 테스트 번들 타깃이 없어 SwiftUI 탭 제목의 언어별 렌더링을 직접 검증하는 영구 UI test를 이번 Task에서 추가할 수 없다.
|
||||
- 대체 검증 방법:
|
||||
- 기존 `I18n.MainContentRecommendation.tabTitle`, `I18n.MainContentRanking.tabTitle`, `I18n.HomeFollowing.tabTitle` 재사용 여부를 정적 검색하고 ko/en/ja 화면과 앱 빌드로 확인한다.
|
||||
- 작업 내용:
|
||||
- `MainHomeView`의 탭 제목에 남은 한글 문자열 리터럴을 기존 I18n 키로 교체한다.
|
||||
- 새 문자열이나 별도 매핑 계층을 추가하지 않는다.
|
||||
- 검증 기준:
|
||||
- 실행 명령: `rg '"추천"|"랭킹"|"팔로잉"|MainContentRecommendation\.tabTitle|MainContentRanking\.tabTitle|HomeFollowing\.tabTitle' SodaLive/Sources/V2/Main/Home/MainHomeView.swift SodaLive/Sources/I18n/I18n.swift`
|
||||
- 기대 결과: `MainHomeView`는 기존 I18n 탭 제목만 사용하고 한글 탭 제목 리터럴은 없어야 한다.
|
||||
- 수동 확인: 앱 언어 ko/en/ja에서 세 탭 제목이 각 언어로 표시되어야 한다.
|
||||
|
||||
### Phase 7: 데이터 기반 프로젝트 포함과 중간 빌드 검증
|
||||
|
||||
- [x] **Task 7.1: 데이터 기반 신규 Swift 파일 프로젝트 포함 여부 확인**
|
||||
@@ -315,6 +426,26 @@
|
||||
- 기대 결과: `BUILD SUCCEEDED`
|
||||
- 수동 확인: 추천 홈에서 배너가 Figma 노드 `24:5525`처럼 좌우 배너 일부 노출, 간격 8, 1:1 이미지, 우측 상단 인디케이터 형태로 표시되어야 한다.
|
||||
|
||||
- [x] **Task 9.5: 무한 캐러셀 경계 연속 스와이프를 안전하게 처리**
|
||||
- Goal 실행 `P9-R1`: `REV-P9-001`을 수정해 첫·마지막 복제 배너 전환 중 연속 스와이프가 발생해도 표시 index가 유효 범위를 벗어나지 않게 한다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase9-banner-section.md`
|
||||
- 확정 항목: `REV-P9-001`
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive/Sources/V2/Component/Banner/BannerCarousel.swift`
|
||||
- TDD 예외 사유:
|
||||
- 앱 테스트 번들 타깃이 없어 SwiftUI gesture와 지연 animation을 직접 실행하는 영구 UI test를 이번 Task에서 추가할 수 없다.
|
||||
- 대체 검증 방법:
|
||||
- 마지막 실데이터 index에서 지연 reset 전에 같은 방향과 반대 방향 스와이프를 각각 적용하는 상태 전이, 첫 index의 대칭 상태 전이와 데이터 변경 중 예약된 reset을 재현하고, 수동 경계 연속 스와이프와 앱 빌드로 확인한다.
|
||||
- 작업 내용:
|
||||
- [x] `displayIndex == items.count`에서 두 번 연속 증가하면 `items.count + 2`가 되고 현재 `wrapIfNeeded()`가 이를 복구하지 못하는 실패를 재현한다.
|
||||
- [x] 전환 지연 중 추가 gesture·timer 전이가 index를 유효 복제 범위 밖으로 보내지 않도록 최소 상태/guard만 추가한다.
|
||||
- [x] 배너 크기, 간격, 페이지 형식, 5초 자동 스크롤과 탭 callback은 변경하지 않는다.
|
||||
- [x] 경계에서 예약한 지연 reset이 사용자의 반대 방향 이동 또는 `items` 변경 뒤 현재 정상 index를 덮어쓰지 않도록, reset 실행 시점에 여전히 같은 복제 경계인지 확인한다.
|
||||
- [x] 마지막·첫 경계에서 같은 방향/반대 방향 입력과 예약 reset 실행 순서를 포함한 상태 전이 self-check를 통과한다.
|
||||
- [x] 첫·마지막 경계의 빠른 양방향 연속 스와이프, 자동 스크롤, 페이지 표시를 수동 확인하고 `git diff --check`와 `SodaLive-dev` Debug 빌드를 실행한다.
|
||||
- [x] 수정 결과와 실제 명령을 이 문서와 Phase 9 리뷰 리포트에 누적한다.
|
||||
|
||||
### Phase 10: 최근 활동 크리에이터 섹션 UI
|
||||
|
||||
- [x] **Task 10.1: 최근 활동 크리에이터 섹션 작성/보완**
|
||||
@@ -328,6 +459,24 @@
|
||||
- 실행 명령: `rg "MainHomeActiveCreatorSection|activityType|activityAt|targetId|RecommendedActivityType" SodaLive/Sources/V2/Main/Home/Recommendation`
|
||||
- 기대 결과: 최근 활동 섹션이 신규 응답 필드와 활동 타입 변환을 사용한다.
|
||||
|
||||
- [x] **Task 10.2: 최근 활동 상대 시간 계산을 공용 DateParser로 단일화**
|
||||
- Goal 실행 `P10-R1`: `REV-P10-001`을 수정해 최근 활동 섹션의 중복 상대 시간 계산을 제거하고 공용 `DateParser.relativeTimeText`를 재사용한다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase10-active-creators.md`
|
||||
- 확정 항목: `REV-P10-001`
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeActiveCreatorSection.swift`
|
||||
- 확인: `SodaLive/Sources/Common/DateParser.swift`
|
||||
- TDD 예외 사유:
|
||||
- 사용자 동작을 바꾸지 않고 공용 함수와 동일한 중복 계산만 제거하는 구조 정리 Task이며 앱 테스트 번들 타깃이 없다.
|
||||
- 대체 검증 방법:
|
||||
- 두 구현의 분기와 반환 I18n을 대조하고, 공용 함수 연결 정적 검색 및 앱 빌드로 동작 보존을 확인한다.
|
||||
- 작업 내용:
|
||||
- [x] `relativeActivityAtText(now:)`와 `DateParser.relativeTimeText(fromUTC:fallback:now:)`가 동일한 연/월/일/시/분 분기와 fallback을 구현하는 현재 중복을 확인한다.
|
||||
- [x] 최근 활동 표시를 공용 `DateParser.relativeTimeText` 호출로 교체하고 이번 섹션의 중복 계산만 제거한다.
|
||||
- [x] `rg "dateComponents|timeIntervalSince|relativeTimeText" SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeActiveCreatorSection.swift SodaLive/Sources/Common/DateParser.swift`, `git diff --check`, `SodaLive-dev` Debug 빌드를 실행한다.
|
||||
- [x] 수정 결과와 실제 명령을 이 문서와 Phase 10 리뷰 리포트에 누적한다.
|
||||
|
||||
### Phase 11: 최근 데뷔한 크리에이터 섹션 UI
|
||||
|
||||
- [x] **Task 11.1: 최근 데뷔 크리에이터 섹션 작성/보완**
|
||||
@@ -337,11 +486,11 @@
|
||||
- 확인/보완: `SodaLive/Sources/V2/Component/Creator/CreatorProfileItem.swift`
|
||||
- 작업 내용:
|
||||
- `HomeCreatorItem.creatorId`, `creatorNickname`, `creatorProfileImage`를 사용한다.
|
||||
- 기존 `CreatorProfileGrid`와 `CreatorProfileItem`을 우선 재사용한다.
|
||||
- 기존 `CreatorProfileGrid`와 `CreatorProfileItem`을 우선 검토하되, Figma 직사각형 카드 형태를 충족하지 못하면 페이지 전용 `MainHomeRecentDebutCreatorItemView`를 사용한다.
|
||||
- 데이터가 비어 있으면 섹션을 표시하지 않는다.
|
||||
- 검증 기준:
|
||||
- 실행 명령: `rg "MainHomeRecentDebutCreatorSection|CreatorProfileGrid|CreatorProfileItem|creatorProfileImage" SodaLive/Sources/V2/Main/Home/Recommendation SodaLive/Sources/V2/Component/Creator`
|
||||
- 기대 결과: 최근 데뷔 섹션이 공용 Creator widget을 재사용한다.
|
||||
- 실행 명령: `rg "MainHomeRecentDebutCreatorSection|MainHomeRecentDebutCreatorItemView|CreatorProfileGrid|CreatorProfileItem|creatorProfileImage" SodaLive/Sources/V2/Main/Home/Recommendation SodaLive/Sources/V2/Component/Creator`
|
||||
- 기대 결과: 최근 데뷔 섹션이 신규 응답 필드를 사용하고, 공용 원형 widget으로 충족할 수 없는 Figma 직사각형 카드는 페이지 전용 View를 사용한다.
|
||||
|
||||
### Phase 12: AI 캐릭터 섹션 UI
|
||||
|
||||
@@ -357,6 +506,24 @@
|
||||
- 실행 명령: `rg "MainHomeAiCharacterSection|AiCharacterCard|totalChatCount|originalWorkTitle|profileImage" SodaLive/Sources/V2`
|
||||
- 기대 결과: AI 캐릭터 섹션이 신규 응답 필드를 기준으로 구성된다.
|
||||
|
||||
- [x] **Task 12.2: AI 캐릭터 탭 식별자를 characterId로 보정**
|
||||
- Goal 실행 `P12-R1`: `REV-P12-001`을 수정해 AI 캐릭터 카드가 `creatorId`가 아니라 `characterId`를 상세 callback으로 전달하게 한다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase12-ai-character-section.md`
|
||||
- 확정 항목: `REV-P12-001`
|
||||
- `Task 5.2`의 최종 character route가 준비되어야 한다.
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeAiCharacterSection.swift`
|
||||
- TDD 예외 사유:
|
||||
- 앱 테스트 번들 타깃이 없어 SwiftUI Button callback을 직접 실행하는 영구 unit test를 추가할 수 없다.
|
||||
- 대체 검증 방법:
|
||||
- Preview처럼 `characterId != creatorId`인 fixture의 callback 값을 수동 확인하고 정적 검색과 앱 빌드를 실행한다.
|
||||
- 작업 내용:
|
||||
- [x] 현재 `onTapCharacter(item.creatorId)` 전달을 실패 근거로 확인한다.
|
||||
- [x] 최소 수정으로 `onTapCharacter(item.characterId)`를 전달한다.
|
||||
- [x] `rg "onTapCharacter\\(item\\.(characterId|creatorId)\\)" SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeAiCharacterSection.swift`, `git diff --check`, `SodaLive-dev` Debug 빌드를 통과한다.
|
||||
- [x] `creatorId != characterId`인 항목은 `characterId` callback과 `characterDetail(characterId:)` 정적 연결로 확인하고, 실제 탭 수동 확인은 잔여 확인 사항으로 검증 기록에 남긴다.
|
||||
|
||||
### Phase 13: 장르의 크리에이터 섹션 UI
|
||||
|
||||
- [x] **Task 13.1: 장르 크리에이터 그룹 섹션 작성/보완**
|
||||
@@ -410,6 +577,45 @@
|
||||
- 실행 명령: `rg "MainHomePopularCommunitySection|CommunityPostCard|imageUrl|audioUrl|existOrdered|구매완료|purchaseCommunityPost|communityPostLike|toggleContent|relativeTimeText" SodaLive/Sources/V2 SodaLive/Sources/Common SodaLive/Sources/Explorer/Profile/CreatorCommunity`
|
||||
- 기대 결과: 커뮤니티 섹션과 카드 조건 분기, 오디오 재생, 구매/좋아요 연결, UTC 상대 날짜 변환이 확인되고 `구매완료` 표시 구현은 없어야 한다.
|
||||
|
||||
- [x] **Task 15.2: 무료 커뮤니티 게시물 가격 경계 보정**
|
||||
- Goal 실행 `P15-R1`: `REV-P15-001`을 수정해 PRD의 `price <= 0 || existOrdered` 조건과 카드 접근 가능 상태를 일치시킨다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase15-popular-community-feed.md`
|
||||
- 확정 항목: `REV-P15-001`
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive/Sources/V2/Component/Card/CommunityPostCard.swift`
|
||||
- TDD 예외 사유:
|
||||
- 앱 테스트 번들 타깃이 없어 private SwiftUI 계산 프로퍼티의 영구 unit test를 추가할 수 없다.
|
||||
- 대체 검증 방법:
|
||||
- `price`가 음수·0·양수인 상태와 `existOrdered` 조합을 Preview/수동 확인하고 정적 검색과 앱 빌드를 실행한다.
|
||||
- 작업 내용:
|
||||
- [x] `price < 0 && existOrdered == false`에서 현재 `isAccessiblePost == false`가 되는 경계를 확인한다.
|
||||
- [x] `isAccessiblePost`를 PRD의 `price <= 0 || existOrdered` 조건과 일치시키는 최소 수정만 적용한다.
|
||||
- [x] `rg "price (==|<=) 0 \\|\\| existOrdered" SodaLive/Sources/V2/Component/Card/CommunityPostCard.swift`, `git diff --check`, `SodaLive-dev` Debug 빌드를 통과한다.
|
||||
- [x] 무료·유료 미구매·구매 완료 상태 조건은 정적 검색과 빌드로 확인하고, 실제 화면 수동 확인은 잔여 확인 사항으로 검증 기록에 남긴다.
|
||||
|
||||
- [x] **Task 15.3: 이미지 없는 유료 미구매 게시물 구매 진입 보완**
|
||||
- Goal 실행 `P15-R2`: `REV-P15-002`를 수정해 `imageUrl == nil && price > 0 && existOrdered == false`인 게시물에서도 기존 구매 API로 진입할 수 있게 한다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase15-popular-community-feed.md`
|
||||
- 확정 항목: `REV-P15-002`
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive/Sources/V2/Component/Card/CommunityPostCard.swift`
|
||||
- 확인/보완: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomePopularCommunitySection.swift`
|
||||
- TDD 예외 사유:
|
||||
- 앱 테스트 번들 타깃이 없어 private SwiftUI 상태와 구매 Button action을 직접 실행하는 영구 unit/UI test를 이번 Task에서 추가할 수 없다.
|
||||
- 대체 검증 방법:
|
||||
- 이미지 유무·가격·구매 여부 조합 fixture를 Preview 또는 수동 화면으로 확인하고 callback 정적 검색과 앱 빌드를 실행한다.
|
||||
- 작업 내용:
|
||||
- 이미지 없는 레이아웃은 유지하면서 유료 미구매 상태에 구매 affordance를 제공한다.
|
||||
- 기존 `purchaseCommunityPost` callback과 loading·오류 흐름을 재사용한다.
|
||||
- 무료 및 구매 완료 게시물의 카드 탭·반응 UI는 변경하지 않는다.
|
||||
- 검증 기준:
|
||||
- 수동 확인: `imageUrl == nil`, `price > 0`, `existOrdered == false` fixture에서 구매 진입이 노출되고 한 번의 사용자 확인으로 기존 구매 callback이 1회 실행되어야 한다.
|
||||
- 수동 확인: 이미지가 있는 유료 미구매, 무료, 구매 완료 상태는 기존 표시와 동작을 유지해야 한다.
|
||||
- 실행 명령: `rg "hasImage|isLocked|paidLockOverlay|purchaseCommunityPost|onTapPurchase" SodaLive/Sources/V2/Component/Card/CommunityPostCard.swift SodaLive/Sources/V2/Main/Home/Recommendation`
|
||||
- 기대 결과: 이미지 유무와 무관하게 유료 미구매 상태가 기존 구매 경로에 연결되어야 한다.
|
||||
|
||||
### Phase 16: 사업자 정보 섹션 UI
|
||||
|
||||
- [x] **Task 16.1: 사업자 정보 더보기/접기 섹션 작성/보완**
|
||||
@@ -426,18 +632,61 @@
|
||||
- 실행 명령: `rg "MainHomeBusinessInfoSection|BusinessInfoExpandableTextView|ExpandableTextView|lineLimit|더보기|접기" SodaLive/Sources/V2`
|
||||
- 기대 결과: 사업자 정보 섹션과 확장 텍스트 구현이 확인된다.
|
||||
|
||||
- [x] **Task 16.2: 사업자 정보 확장 텍스트 구현 단일화**
|
||||
- Goal 실행 `P16-R1`: `REV-P16-001`을 수정해 사업자 정보 wrapper가 빌드 대상의 공용 V2 확장 텍스트 하나만 사용하게 한다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase16-business-info-section.md`
|
||||
- 확정 항목: `REV-P16-001`
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeBusinessInfoSection.swift`
|
||||
- 수정/이름 정리: `SodaLive/Sources/V2/Component/Text/ExpandableTextView.swift`
|
||||
- 확인/보완: `SodaLive.xcodeproj/project.pbxproj`
|
||||
- 확인: `SodaLive/Sources/CustomView/ExpandableTextView.swift`
|
||||
- TDD 예외 사유:
|
||||
- 동작을 추가하지 않고 중복 View와 Xcode target 포함 상태를 정리하는 회귀 문서/구조 Task다.
|
||||
- 대체 검증 방법:
|
||||
- 타입 정의·소비처·PBX Sources 포함 개수를 대조하고 3줄 이하/초과 텍스트 수동 확인과 앱 빌드를 실행한다.
|
||||
- 작업 내용:
|
||||
- [x] 현재 V2 공용 파일이 Sources에 포함되지 않고 화면 파일에 같은 측정 구현이 복제된 상태를 확인한다.
|
||||
- [x] 기존 `CustomView/ExpandableTextView` 소비처를 변경하지 않으면서 타입명 충돌을 피하고, 공용 V2 구현과 사업자 wrapper를 단일 연결한다.
|
||||
- [x] 이번 변경으로 생긴 미사용 private 구현과 프로젝트 참조만 정리한다.
|
||||
- [x] 타입 정의/소비처 검색, `plutil -lint SodaLive.xcodeproj/project.pbxproj`, `git diff --check`, `SodaLive-dev` Debug 빌드를 통과한다.
|
||||
- [x] 3줄 이하/초과 더보기 조건은 공용 구현 연결, 타입 검색, 빌드로 확인하고, 실제 화면 수동 확인은 잔여 확인 사항으로 검증 기록에 남긴다.
|
||||
|
||||
- [x] **Task 16.3: V2 확장 텍스트 Sources 중복 등록 제거**
|
||||
- Goal 실행 `P16-R2`: `REV-P16-002`를 수정해 `V2ExpandableTextView.swift`가 각 앱 target의 Sources에 정확히 한 번만 포함되게 한다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase16-business-info-section.md`
|
||||
- 확정 항목: `REV-P16-002`
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive.xcodeproj/project.pbxproj`
|
||||
- TDD 예외 사유:
|
||||
- production 동작이 아니라 Xcode target의 Sources 메타데이터 중복을 정리하는 프로젝트 설정 Task다.
|
||||
- 대체 검증 방법:
|
||||
- PBX Sources phase별 포함 개수를 대조하고 프로젝트 유효성 검사와 두 앱 scheme 빌드를 실행한다.
|
||||
- 작업 내용:
|
||||
- `SodaLive` target에 중복 등록된 `V2ExpandableTextView.swift in Sources` 한 건만 제거한다.
|
||||
- `SodaLive-dev` target 등록과 다른 기존 Sources 항목은 변경하지 않는다.
|
||||
- 검증 기준:
|
||||
- 실행 명령: 앱 target별 Sources build phase에서 `V2ExpandableTextView.swift in Sources` 포함 개수를 확인한다.
|
||||
- 기대 결과: `SodaLive`, `SodaLive-dev` target에 각각 정확히 한 번 포함되어야 한다.
|
||||
- 실행 명령: `plutil -lint SodaLive.xcodeproj/project.pbxproj`
|
||||
- 기대 결과: `OK`
|
||||
- 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` 및 `SodaLive-dev` 동일 빌드
|
||||
- 기대 결과: 두 scheme 모두 `BUILD SUCCEEDED`이며 해당 파일의 중복 Sources 경고가 없어야 한다.
|
||||
|
||||
### Phase 17: 섹션 조립 순서와 빈 섹션 처리
|
||||
|
||||
- [x] **Task 17.1: MainHomeRecommendationView에 섹션 순서 반영**
|
||||
- 대상 파일:
|
||||
- 확인/보완: `SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift`
|
||||
- 작업 내용:
|
||||
- 섹션 순서를 PRD와 맞춘다.
|
||||
- 현재 라이브, 배너, 최근 활동, 최근 데뷔, AI 캐릭터, 장르, 응원, 인기 커뮤니티, 사업자 정보 순서로 배치한다.
|
||||
- 섹션 순서를 PRD와 2026-07-12 장르 크리에이터 섹션 미표시 결정에 맞춘다.
|
||||
- 현재 라이브, 배너, 최근 활동, 최근 데뷔, AI 캐릭터, 응원, 인기 커뮤니티, 사업자 정보 순서로 배치하고 장르 섹션은 조립하지 않는다.
|
||||
- 각 데이터 배열이 비어 있으면 섹션 제목과 컨테이너까지 숨긴다.
|
||||
- 검증 기준:
|
||||
- 실행 명령: `rg "MainHomeLiveSection|MainHomeBannerSection|MainHomeActiveCreatorSection|MainHomeRecentDebutCreatorSection|MainHomeAiCharacterSection|MainHomeGenreCreatorSection|MainHomeCheerCreatorSection|MainHomePopularCommunitySection|MainHomeBusinessInfoSection" SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift`
|
||||
- 기대 결과: 모든 구현 대상 섹션이 올바른 순서로 조립된다.
|
||||
- 실행 명령: `rg "MainHomeLiveSection|MainHomeBannerSection|MainHomeActiveCreatorSection|MainHomeRecentDebutCreatorSection|MainHomeAiCharacterSection|MainHomeCheerCreatorSection|MainHomePopularCommunitySection|MainHomeBusinessInfoSection" SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift`
|
||||
- 기대 결과: 활성 구현 대상 섹션이 올바른 순서로 조립되고 `MainHomeGenreCreatorSection`은 검색되지 않는다.
|
||||
|
||||
### Phase 18: 최종 프로젝트 포함과 빌드 검증
|
||||
|
||||
@@ -474,6 +723,42 @@
|
||||
- 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build`
|
||||
- 기대 결과: `BUILD SUCCEEDED`
|
||||
|
||||
- [x] **Task 18.3: 프로덕션 target의 홈 추천 Sources 중복 등록 제거**
|
||||
- Goal 실행 `P18-R1`: `REV-P18-001`을 수정해 이번 계획 범위의 홈 추천 Swift 파일이 `SodaLive`와 `SodaLive-dev` target에 각각 정확히 한 번만 포함되게 한다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase18-final-project-build.md`
|
||||
- 확정 항목: `REV-P18-001`
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive.xcodeproj/project.pbxproj`
|
||||
- TDD 예외 사유:
|
||||
- production 동작이 아니라 Xcode Compile Sources 메타데이터 중복을 정리하는 프로젝트 설정 Task다.
|
||||
- 대체 검증 방법:
|
||||
- 두 앱 target의 Sources phase별 file reference 포함 개수를 대조하고, 프로젝트 유효성 검사와 두 scheme 빌드 로그에서 대상 파일의 duplicate build warning이 사라졌는지 확인한다.
|
||||
- 작업 내용:
|
||||
- [x] `SodaLive` Sources phase에 두 번 등록된 `MainHomeView.swift`, `MainHomeRecommendationView.swift`, `MainHomeRecommendationViewModel.swift`, `MainHomeRankingView.swift`, `MainHomeFollowingView.swift`, `MainHomeLiveSection.swift`, `MainHomeBannerSection.swift`, `MainHomeActiveCreatorSection.swift`, `MainHomeRecentDebutCreatorSection.swift`, `MainHomeAiCharacterSection.swift`, `MainHomeBusinessInfoSection.swift`의 중복 build file 한 건씩을 확인한다.
|
||||
- [x] 각 파일의 프로덕션 중복 build file과 Sources phase 참조 한 건만 제거하고 `SodaLive-dev` 등록 및 다른 기존 중복 항목은 변경하지 않는다.
|
||||
- [x] `plutil -lint SodaLive.xcodeproj/project.pbxproj`와 `git diff --check`를 통과한다.
|
||||
- [x] `SodaLive`, `SodaLive-dev` target에 위 11개 파일이 각각 1회 등록되어 있고 `xcodebuild -workspace "SodaLive.xcworkspace" -list`로 프로젝트 파싱이 성공하는지 확인한다.
|
||||
- [x] 실제 등록 수와 검증 결과를 이 문서와 Phase 18 리뷰 리포트에 누적한다.
|
||||
|
||||
- [x] **Task 18.4: 프로덕션 target에 남은 홈 추천 Sources 중복 등록 제거**
|
||||
- Goal 실행 `P18-R2`: `REV-P18-002`를 수정해 `Task 18.3` 이후에도 두 번 남은 홈 추천 Swift 파일 11개의 프로덕션 Sources 등록을 각각 한 번으로 맞춘다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase18-final-project-build.md`
|
||||
- 확정 항목: `REV-P18-002`
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive.xcodeproj/project.pbxproj`
|
||||
- TDD 예외 사유:
|
||||
- production 동작이 아니라 Xcode Compile Sources 메타데이터의 잔여 중복을 정리하는 프로젝트 설정 Task다.
|
||||
- 대체 검증 방법:
|
||||
- 두 앱 target의 Sources phase별 파일명 포함 수와 fresh DerivedData 빌드 경고를 수정 전후로 대조한다.
|
||||
- 작업 내용:
|
||||
- [x] 현재 `SodaLive` Sources phase에서 `MainHomeView.swift`, `MainHomeRecommendationView.swift`, `MainHomeRecommendationViewModel.swift`, `MainHomeRankingView.swift`, `MainHomeFollowingView.swift`, `MainHomeLiveSection.swift`, `MainHomeBannerSection.swift`, `MainHomeActiveCreatorSection.swift`, `MainHomeRecentDebutCreatorSection.swift`, `MainHomeAiCharacterSection.swift`, `MainHomeBusinessInfoSection.swift`가 각각 2회이고 `SodaLive-dev`에서는 각각 1회인 실패 상태를 확인한다.
|
||||
- [x] 각 파일의 프로덕션 잔여 중복 build file과 Sources phase 참조 한 건만 제거하고 `SodaLive-dev` 및 범위 밖 파일은 변경하지 않는다.
|
||||
- [x] `plutil -lint SodaLive.xcodeproj/project.pbxproj`와 `git diff --check`를 통과한다.
|
||||
- [x] 두 target에서 대상 11개 파일이 각각 정확히 1회인지 대조하고 fresh DerivedData의 `SodaLive`, `SodaLive-dev` Debug 빌드를 실행한다.
|
||||
- [x] 두 빌드 로그에서 대상 11개 파일의 `Skipping duplicate build file` 경고가 없는지 확인하고 실제 결과를 이 문서와 Phase 18 리뷰 리포트에 누적한다.
|
||||
|
||||
### Phase 19: 문서와 검증 기록 갱신
|
||||
|
||||
- [x] **Task 19.1: PRD/계획 문서 갱신**
|
||||
@@ -488,6 +773,83 @@
|
||||
- 실행 명령: `rg "### Phase [0-9]+:|- \\[[ x]\\] \\*\\*Task [0-9]+\\.[0-9]+:" docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md`
|
||||
- 기대 결과: phase heading과 `Task N.N` 형식 체크박스가 검색된다.
|
||||
|
||||
- [x] **Task 19.2: 장르 크리에이터 미표시 기준 문서 정합성 보정**
|
||||
- Goal 실행 `P19-R1`: `REV-P19-001`을 수정해 2026-07-12 장르 섹션 미표시 결정과 PRD·Phase 17 활성 기준을 일치시킨다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase19-documentation-records.md`
|
||||
- 확정 항목: `REV-P19-001`
|
||||
- 대상 파일:
|
||||
- 수정: `docs/20260602_메인_홈_추천_UI_API_연동/prd.md`
|
||||
- 수정: `docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md`
|
||||
- TDD 예외 사유:
|
||||
- production 동작을 변경하지 않는 문서 정정 Task다.
|
||||
- 대체 검증 방법:
|
||||
- 현재 코드 조립 순서, PRD 화면 트리, Phase 17 기준과 2026-07-12 결정의 대조표 및 정적 검색으로 확인한다.
|
||||
- 작업 내용:
|
||||
- [x] PRD의 활성 화면 구성과 Phase 17 작업/기대 결과에서 장르 섹션 노출 요구가 남은 위치를 확인한다.
|
||||
- [x] `genreCreators` 응답 모델 유지와 `MainHomeGenreCreatorSection` 미표시를 구분해 PRD와 활성 검증 기준을 정정한다.
|
||||
- [x] 기존 Phase 13 구현 기록과 2026-06-30 검증 기록은 삭제하지 않고 후속 정정 기록을 누적한다.
|
||||
- [x] `rg "장르의 크리에이터|MainHomeGenreCreatorSection|genreCreators" docs/20260602_메인_홈_추천_UI_API_연동 SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift`와 `git diff --check` 결과를 검증 기록에 남긴다.
|
||||
|
||||
- [x] **Task 19.3: 활성 문서 코드 블록과 V2 컴포넌트 경로 정합성 보정**
|
||||
- Goal 실행 `P19-R2`: `REV-P19-002`, `REV-P19-003`을 수정해 PRD Markdown 구조와 최신 V2 확장 텍스트 경로를 현재 구현에 맞춘다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase19-documentation-records.md`
|
||||
- 확정 항목: `REV-P19-002`, `REV-P19-003`
|
||||
- 대상 파일:
|
||||
- 수정: `docs/20260602_메인_홈_추천_UI_API_연동/prd.md`
|
||||
- 수정: `docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md`
|
||||
- TDD 예외 사유:
|
||||
- production 동작을 변경하지 않는 Markdown 구조와 활성 파일 경로 정정 Task다.
|
||||
- 대체 검증 방법:
|
||||
- Markdown fence 쌍과 활성 경로의 실제 파일 존재 여부를 정적 검사한다.
|
||||
- 작업 내용:
|
||||
- PRD 응답 모델 예시의 누락·중첩된 코드 fence를 각 모델 단위로 닫아 이후 본문이 코드 블록으로 렌더링되지 않게 한다.
|
||||
- PRD와 계획 상단의 활성 공용 컴포넌트 이름·경로를 `V2ExpandableTextView.swift`로 정정한다.
|
||||
- 과거 Task와 검증 기록의 당시 경로는 이력으로 보존한다.
|
||||
- 검증 기준:
|
||||
- 실행 명령: PRD의 각 응답 모델 예시가 독립된 Markdown fence 여닫힘 쌍을 가지며 각 모델 heading과 설명이 코드 블록 밖에 있는지 확인한다.
|
||||
- 실행 명령: `rg "V2/Component/Text/(ExpandableTextView|V2ExpandableTextView)\.swift" docs/20260602_메인_홈_추천_UI_API_연동/prd.md docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md`
|
||||
- 기대 결과: 활성 기준은 존재하는 `V2ExpandableTextView.swift`를 가리키고 과거 경로는 검증 이력에만 남아야 한다.
|
||||
|
||||
- [x] **Task 19.4: 활성 API 타입명과 리뷰 정정 기록 보완**
|
||||
- Goal 실행 `P19-R3`: `REV-P19-004`를 수정해 PRD의 추천 API 타입명과 Phase 11/21 후속 리뷰 기록을 현재 구현과 일치시킨다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase19-documentation-records.md`
|
||||
- 확정 항목: `REV-P19-004`
|
||||
- 대상 파일:
|
||||
- 수정: `docs/20260602_메인_홈_추천_UI_API_연동/prd.md`
|
||||
- 수정: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase11-recent-debut-creators.md`
|
||||
- 수정: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase21-recent-activity-live-fallback.md`
|
||||
- TDD 예외 사유:
|
||||
- production 동작을 변경하지 않는 활성 문서 타입명과 append-only 리뷰 기록 정정 Task다.
|
||||
- 대체 검증 방법:
|
||||
- 실제 Swift 타입, Phase 11 카드 구현, Phase 21 destination 분기와 문서 문장을 정적 대조한다.
|
||||
- 작업 내용:
|
||||
- [x] PRD Goal의 `MainHomeApi`를 실제 활성 타입 `MainHomeRecommendationApi`로 정정한다.
|
||||
- [x] Phase 11의 `CreatorProfileGrid` 재사용 확인 문구를 실제 전용 직사각형 카드 사용 판정과 일치하도록 후속 정정한다.
|
||||
- [x] Phase 21의 `LIVE_REPLAY`가 라이브/creator fallback을 사용한다는 문구를 `targetId` 기반 콘텐츠 상세 이동 및 fallback 없음으로 후속 정정한다.
|
||||
- [x] 기존 리뷰 기록은 삭제하지 않고 정정 기록을 누적하며, `rg`와 `git diff --check` 결과를 검증 기록에 남긴다.
|
||||
|
||||
- [x] **Task 19.5: 최근 데뷔 섹션의 활성 계획 기준을 실제 전용 카드 구현과 맞춤**
|
||||
- Goal 실행 `P19-R4`: `REV-P19-005`를 수정해 Phase 11의 완료 기준이 현재 `MainHomeRecentDebutCreatorItemView` 사용 판정과 모순되지 않게 한다.
|
||||
- 시작 조건:
|
||||
- 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase19-documentation-records.md`
|
||||
- 관련 Phase 리뷰: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase11-recent-debut-creators.md`
|
||||
- 확정 항목: `REV-P19-005`
|
||||
- 대상 파일:
|
||||
- 수정: `docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md`
|
||||
- 수정: `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase11-recent-debut-creators.md`
|
||||
- TDD 예외 사유:
|
||||
- production 동작을 변경하지 않는 활성 계획·리뷰 정합성 보정 Task다.
|
||||
- 대체 검증 방법:
|
||||
- Phase 11 Task의 작업·기대 결과, 현재 전용 직사각형 카드 코드와 Phase 11 최신 리뷰 결론을 줄 단위로 대조한다.
|
||||
- 작업 내용:
|
||||
- [x] `Task 11.1`이 공용 원형 `CreatorProfileGrid` 재사용을 완료 조건으로 요구하지만 현재 코드와 최신 리뷰는 전용 직사각형 카드를 올바른 구현으로 판정하는 충돌을 확인한다.
|
||||
- [x] 공용 컴포넌트 우선 원칙은 유지하되 Figma 카드 형태를 충족하지 못할 때 페이지 전용 `MainHomeRecentDebutCreatorItemView`를 사용하는 현재 결정을 활성 Task와 기대 결과에 명시한다.
|
||||
- [x] 기존 Phase 11 완료 기록과 리뷰 정정 이력은 삭제하지 않고 후속 정정만 누적한다.
|
||||
- [x] `rg "CreatorProfileGrid|MainHomeRecentDebutCreatorItemView" docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase11-recent-debut-creators.md SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeRecentDebutCreatorSection.swift`와 `git diff --check` 결과를 검증 기록에 남긴다.
|
||||
|
||||
### Phase 20: 추천 커뮤니티 게시물 상세 진입 보정
|
||||
|
||||
- [x] **Task 20.1: PRD/계획 문서에 커뮤니티 게시물 상세 이동 요구사항 추가**
|
||||
@@ -628,8 +990,500 @@
|
||||
- 실행 명령: `rg "LIVE_REPLAY.*(라이브룸|콘텐츠 상세)|onTapContent\\(targetId\\)" docs/20260602_메인_홈_추천_UI_API_연동/prd.md docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md`
|
||||
- 기대 결과: 활성 요구사항과 미완료 구현 Task에는 `LIVE_REPLAY`의 콘텐츠 상세 이동만 명시되고, 과거 오류는 정정 기록에서만 설명된다.
|
||||
|
||||
### Phase 22: 모두 팔로우 확인 Dialog
|
||||
|
||||
**Phase 결과:** 로그인 사용자는 메인 홈 추천 탭의 모든 `모두 팔로우하기` 진입점에서 Confirm Dialog를 확인한 뒤에만 여러 크리에이터를 팔로우하며, 취소 시 API 요청이 발생하지 않는다.
|
||||
|
||||
**선행조건:** `MainHomeView`에서 전달된 모든 추천 탭 모두 팔로우 action이 `MainView.handleRecommendationFollowAllTap` 공통 진입점을 사용한다.
|
||||
|
||||
**Phase 완료 조건:** Task 22.1~22.3을 완료하고 확인 전·취소·dimmed 영역 터치 API 0회, 확인 시 API 1회, 비로그인 기존 로그인 흐름 유지와 ko/en/ja 문구를 검증 기록에 누적한다.
|
||||
|
||||
- [x] **Task 22.1: 인터뷰 결정사항을 PRD와 계획 문서에 반영**
|
||||
- Goal: 모두 팔로우 확인 Dialog의 적용 범위, 인증 순서, 문구, 취소 동작과 완료 기준을 추정 없이 구현할 수 있게 고정한다.
|
||||
- 대상 파일:
|
||||
- 수정: `docs/20260602_메인_홈_추천_UI_API_연동/prd.md`
|
||||
- 수정: `docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md`
|
||||
- 작업 내용:
|
||||
- 메인 홈 추천 탭의 모든 공통 `모두 팔로우하기` 진입점에 적용한다.
|
||||
- 비로그인 사용자는 기존처럼 로그인 화면으로 바로 이동하고, 로그인 후 자동 팔로우하지 않는다.
|
||||
- 로그인 사용자는 Confirm Dialog의 `팔로우 하기`를 선택한 경우에만 기존 API를 호출한다.
|
||||
- `취소`와 dimmed 영역 터치는 보류 action을 폐기하고 API를 호출하지 않는다.
|
||||
- Dialog 제목, 설명, 확인 문구를 ko/en/ja로 확정하고 취소는 `I18n.Common.cancel`을 재사용한다.
|
||||
- 현재 미노출 상태인 장르 크리에이터 섹션을 다시 표시하는 작업은 제외한다.
|
||||
- 완료 증거:
|
||||
- PRD 7.6, Success Criteria, Verification Plan, Decision Log와 Phase 22가 동일한 흐름과 문구를 사용한다.
|
||||
- TDD 예외 사유:
|
||||
- production 동작을 변경하지 않는 문서 갱신 Task다.
|
||||
- 검증 기준:
|
||||
- 실행 명령: `rg "모두 팔로우 확인 Dialog|모두 팔로우할까요|Follow all creators|すべてのクリエイターをフォローしますか|dimmed|자동 팔로우" docs/20260602_메인_홈_추천_UI_API_연동/prd.md docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md`
|
||||
- 기대 결과: 적용 범위, 인증 순서, 취소 동작과 ko/en/ja 문구가 두 문서에서 검색된다.
|
||||
|
||||
- [x] **Task 22.2: 공통 모두 팔로우 Confirm Dialog와 I18n 구현**
|
||||
- Goal: 기존 공통 모두 팔로우 callback에 최소 상태만 추가해 로그인 사용자의 명시적 확인 후에만 보류한 action을 실행한다.
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive/Sources/V2/Main/MainView.swift`
|
||||
- 수정: `SodaLive/Sources/I18n/I18n.swift`
|
||||
- 확인: `SodaLive/Sources/V2/Main/Home/MainHomeView.swift`
|
||||
- 확인: `SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift`
|
||||
- 확인: `SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationViewModel.swift`
|
||||
- 확인: `SodaLive/Sources/V2/Component/Modal/SodaV2ActionModal.swift`
|
||||
- 작업 내용:
|
||||
- `handleRecommendationFollowAllTap`에서 기존 로그인 guard를 먼저 통과한 사용자에게만 `SodaV2ActionModal`을 표시한다.
|
||||
- 보류한 모두 팔로우 action은 Dialog 확인 시 한 번 실행하고, 확인·취소·dimmed 영역 처리 후에는 즉시 비운다.
|
||||
- Dialog 제목, 설명, 확인 문구는 `I18n.HomeRecommendation`의 ko/en/ja 값을 사용하고 취소는 `I18n.Common.cancel`을 재사용한다.
|
||||
- 기존 `followAll(creatorIds:completionKey:)`의 완료, loading, 오류 toast와 중복 호출 방지 로직은 변경하지 않는다.
|
||||
- `MainHomeView`와 섹션별 View의 callback 계층은 공통 진입점을 우회하지 않는 한 변경하지 않는다.
|
||||
- 완료 증거:
|
||||
- 공통 callback과 기존 `SodaV2ActionModal` 재사용만으로 확인 흐름이 연결되고, API/Repository/Request 계약 변경이 없다.
|
||||
- TDD 예외 사유:
|
||||
- 저장소에 테스트 번들 타깃이 없고 SwiftUI Dialog와 실제 네트워크 요청의 통합 흐름을 위한 신규 테스트 인프라 추가는 이번 최소 변경 범위를 벗어난다.
|
||||
- 대체 검증 방법:
|
||||
- 상태/action/I18n 연결 정적 검색, `SodaLive-dev` 빌드, 로그인/비로그인 수동 흐름과 네트워크 요청 횟수 확인으로 검증한다.
|
||||
- 검증 기준:
|
||||
- 실행 명령: `rg "handleRecommendationFollowAllTap|SodaV2ActionModal|pending.*FollowAll|followAll.*Confirm|I18n.HomeRecommendation|I18n.Common.cancel" SodaLive/Sources/V2/Main/MainView.swift SodaLive/Sources/I18n/I18n.swift`
|
||||
- 기대 결과: 로그인 guard 뒤의 Dialog 표시, 보류 action, 확인/취소 처리와 다국어 키가 검색된다.
|
||||
- 실행 명령: `rg "followRecommendedCreators|FollowRecommendedCreatorsRequest" SodaLive/Sources/V2/Main/Home/Recommendation`
|
||||
- 기대 결과: 기존 모두 팔로우 API와 request 경로가 유지된다.
|
||||
|
||||
- [x] **Task 22.3: 모두 팔로우 확인 흐름 Phase Gate**
|
||||
- Goal: Confirm Dialog가 의도하지 않은 대량 팔로우를 차단하면서 기존 인증·완료·loading·오류 흐름을 유지하는지 최종 판정한다.
|
||||
- 대상 파일:
|
||||
- 확인: `SodaLive/Sources/V2/Main/MainView.swift`
|
||||
- 확인: `SodaLive/Sources/V2/Main/Home/**`
|
||||
- 확인: `SodaLive/Sources/I18n/I18n.swift`
|
||||
- 확인: `SodaLive.xcodeproj/project.pbxproj`
|
||||
- 완료 증거:
|
||||
- 정적 검증, 프로젝트 유효성, `SodaLive-dev` 빌드와 아래 수동 확인 결과가 검증 기록에 누적된다.
|
||||
- 검증 기준:
|
||||
- 실행 명령: `git diff --check`
|
||||
- 기대 결과: 출력 없이 성공한다.
|
||||
- 실행 명령: `plutil -lint SodaLive.xcodeproj/project.pbxproj`
|
||||
- 기대 결과: `OK`
|
||||
- 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build`
|
||||
- 기대 결과: `BUILD SUCCEEDED`
|
||||
- 수동 확인:
|
||||
- 로그인 사용자가 `모두 팔로우하기`를 터치하면 Dialog가 표시되고 API 요청은 0회다.
|
||||
- `취소` 또는 dimmed 영역을 터치하면 Dialog가 닫히고 API 요청은 0회다.
|
||||
- `팔로우 하기`를 한 번 터치하면 Dialog가 닫히고 해당 섹션의 기존 API 요청이 1회 발생한다.
|
||||
- 비로그인 사용자가 버튼을 터치하면 Dialog 없이 로그인 화면으로 이동하고, 로그인 완료 후 자동 팔로우하지 않는다.
|
||||
- 기존 완료/호출 중 버튼 상태와 API 실패 toast가 유지된다.
|
||||
- 앱 언어 ko/en/ja에서 제목, 설명, 확인, 취소 문구가 각각 표시된다.
|
||||
|
||||
## 검증 기록
|
||||
|
||||
### 2026-07-31 Task 5.4 독립 수정 확인
|
||||
|
||||
- 코드 확인:
|
||||
- `LiveNowAllView`는 인증 성공 후 `handleLiveNowItemTap(roomId:isAdult:)`를 재호출해 민감 콘텐츠 설정 guard를 다시 통과함
|
||||
- `CreatorChannelView`는 인증 성공 후 `handleTalkTap()`을 재호출해 민감 콘텐츠 설정 guard를 다시 통과함
|
||||
- 검증:
|
||||
- 인증·설정 4개 조합과 인증 미완료 상태 self-check — `task-5.4-independent-self-check=passed`
|
||||
- `git diff --check`, `git diff --cached --check` — 출력 없이 성공
|
||||
- `plutil -lint SodaLive.xcodeproj/project.pbxproj` — `OK`
|
||||
- `SodaLive-dev`, `SodaLive` Debug `generic/platform=iOS` 빌드 — 모두 종료 코드 0
|
||||
- 추가 점검:
|
||||
- `auth == false`와 `isAdultContentVisible`을 함께 사용하는 Swift 화면을 재검색하고 현재 `ContentView`에서 도달 가능한 `MainView`, `LiveNowAllView`, `CreatorChannelView`의 guard 재진입을 확인
|
||||
- 활성 앱 라우팅 범위에서 신규 확정 발견 사항 없음
|
||||
- 비활성 레거시 `HomeView`, `HomeTabView`, `ChatTabView`는 기존 범위 제외 상태 유지
|
||||
- 범위:
|
||||
- 이번 점검에서는 production Swift 코드를 추가 수정하지 않음
|
||||
|
||||
### 2026-07-31 리뷰 보완 Task 5.4 처리
|
||||
|
||||
- 목적: `REV-P5-003` 보완
|
||||
- 수행 내용:
|
||||
- `LiveNowAllView.handleLiveNowItemTap`의 인증 후 `pendingAction`을 `openLiveDetail(roomId:)` 직접 실행에서 `handleLiveNowItemTap(roomId:isAdult:)` 재호출로 변경
|
||||
- `CreatorChannelView.handleTalkTap`의 인증 후 `pendingAction`을 `startChat(characterId:)` 직접 실행에서 `handleTalkTap()` 재호출로 변경
|
||||
- 공용 guard 계층을 새로 만들지 않고 기존 로그인·국가·본인인증·민감 콘텐츠 설정 분기와 route를 유지
|
||||
- TDD 예외/대체 검증:
|
||||
- 앱 테스트 번들 타깃이 없어 Bootpay 본인인증 callback과 전역 route를 직접 실행하는 영구 통합 test는 추가하지 않음
|
||||
- Swift 상태 전이 self-check, 정적 검색, 공백 오류, 프로젝트 유효성, 두 scheme Debug 빌드로 대체 검증
|
||||
- 검증:
|
||||
- `swift -e '<기존 LiveNowAllView/CreatorChannelView pendingAction 상태 전이 self-check>'` 실행, 기존 방식은 `RED live old path bypassed settings: route=true settings=false`로 실패 재현
|
||||
- `swift -e '<수정 후 LiveNowAllView/CreatorChannelView pendingAction 상태 전이 self-check>'` 실행, `task-5.4-guard-self-check=passed` 확인
|
||||
- `rg -n "pendingAction = \\{|handleLiveNowItemTap\\(roomId: roomId, isAdult: isAdult\\)|handleTalkTap\\(\\)|openLiveDetail\\(roomId: roomId\\)|startChat\\(characterId: characterId\\)|contentViewSettings|isAdultContentVisible" "SodaLive/Sources/Live/Now/All/LiveNowAllView.swift" "SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift"` 실행, 인증 후 guard 재진입과 기존 최종 route 유지 확인
|
||||
- `git diff --check` 실행, 출력 없이 성공
|
||||
- `plutil -lint "SodaLive.xcodeproj/project.pbxproj"` 실행, `OK`
|
||||
- `rg -n -- "- \\[ \\]" "docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md"` 실행, 미완료 Task 검색 결과 없음
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug -destination "generic/platform=iOS" -derivedDataPath "/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/SodaLiveDerivedDataTask54Dev" build` 최초 병렬 실행은 10분 제한으로 `BUILD INTERRUPTED`, 동일 DerivedData 재시도는 `BUILD SUCCEEDED`
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug -destination "generic/platform=iOS" -derivedDataPath "/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/SodaLiveDerivedDataTask54Prod" build` 최초 병렬 실행은 10분 제한으로 `BUILD INTERRUPTED`, 동일 DerivedData 재시도는 `BUILD SUCCEEDED`
|
||||
- 잔여 확인:
|
||||
- 실제 기기/시뮬레이터의 Bootpay 본인인증 완료 수동 확인은 이번 환경에서 수행하지 못해 상태 전이 self-check와 앱 빌드로 대체함
|
||||
- `SodaLive` 빌드의 범위 밖 V2 파일 duplicate Sources warning은 기존 상태로 남아 있으며 이번 Task에서 변경하지 않음
|
||||
|
||||
### 2026-07-31 Task 5.3/9.5 수정 확인 및 활성 guard 추가 점검
|
||||
|
||||
- 수정 확인:
|
||||
- `MainView.performRecommendationDetailAction(requiresAdultContent: true)`는 인증 성공 후 동일 guard를 재진입해 민감 콘텐츠 설정 비활성 시 설정 화면으로 이동하고 상세 route를 실행하지 않음
|
||||
- `BannerCarousel.wrapIfNeeded()`는 예약 당시 `displayIndex`와 `itemsRevision`이 모두 유지된 경우에만 지연 reset을 실행해 반대 방향 이동과 같은 개수의 데이터 교체를 덮어쓰지 않음
|
||||
- self-check:
|
||||
- 인증 전후 4개 상태 조합과 인증 미완료 상태 — `auth-guard-self-check=passed`
|
||||
- 첫·마지막 복제 경계, 반대 방향 이동, 같은 개수 데이터 교체, 반복 같은 방향 입력 — `banner-reset-self-check=passed`
|
||||
- 정적·빌드 검증:
|
||||
- `git diff --check`, `git diff --cached --check` — 출력 없이 성공
|
||||
- `plutil -lint SodaLive.xcodeproj/project.pbxproj` — `OK`
|
||||
- `SodaLive-dev`, `SodaLive` Debug `generic/platform=iOS` 빌드 — 모두 종료 코드 0
|
||||
- 추가 확정 항목:
|
||||
- `REV-P5-003` High — 현재 `ContentView`에서 실제 라우팅되는 `LiveNowAllView`의 성인 라이브와 `CreatorChannelView`의 AI 대화가 인증 성공 시 최종 route를 직접 실행해 민감 콘텐츠 보기 설정을 우회함
|
||||
- Phase 5 `Task 5.4` / `P5-R3` 신규 추가
|
||||
- 범위:
|
||||
- 현재 앱 route에서 사용되지 않는 레거시 `HomeView`, `HomeTabView`, `ChatTabView`의 동일 패턴은 이번 Task 대상에서 제외
|
||||
- 이번 점검에서는 production Swift 코드를 추가 수정하지 않음
|
||||
|
||||
### 2026-07-31 리뷰 보완 Task 5.3/9.5 처리
|
||||
|
||||
- 목적: `REV-P5-002`, `REV-P9-001` 잔여 보완
|
||||
- 수행 내용:
|
||||
- `MainView.performRecommendationDetailAction(requiresAdultContent: true)`에서 본인인증 필요 시 최종 상세 route가 아니라 동일 guard를 재진입하는 closure를 `pendingAction`에 저장하도록 수정
|
||||
- `BannerCarousel.wrapIfNeeded()`의 지연 reset이 예약 당시 `displayIndex`와 `itemsRevision`이 유지된 경우에만 실행되도록 보정
|
||||
- TDD 예외/대체 검증:
|
||||
- 앱 테스트 번들 타깃이 없어 Bootpay callback과 SwiftUI gesture/timer의 영구 unit/UI test는 추가하지 않음
|
||||
- Swift 상태 전이 self-check, 정적 검색, 공백 오류, 프로젝트 유효성, `SodaLive-dev` Debug 빌드로 대체 검증
|
||||
- 검증:
|
||||
- `swift -e '<기존 본인인증 후 pendingAction 상태 전이 self-check>'` 실행, 기존 방식은 `detail=true settings=false`로 RED 실패 재현
|
||||
- `swift -e '<수정 후 본인인증 후 pendingAction 상태 전이 self-check>'` 실행, `settings=false`는 설정 이동·상세 미실행, `settings=true`는 상세 실행 통과 확인
|
||||
- `swift -e '<기존 배너 예약 reset 상태 전이 self-check>'` 실행, 반대 방향 이동 후 예약 reset이 `3`을 `1`로 덮어쓰는 RED 실패 재현
|
||||
- `swift -e '<수정 후 배너 예약 reset 상태 전이 self-check>'` 실행, 반대 방향 이동과 같은 개수의 `items` 변경은 덮어쓰지 않고 같은 경계는 정상 reset되는 것 확인
|
||||
- `rg -n "pendingAction = \{|performRecommendationDetailAction\(requiresAdultContent: true, action: action\)|itemsRevision|scheduledIndex|scheduledRevision" SodaLive/Sources/V2/Main/MainView.swift SodaLive/Sources/V2/Component/Banner/BannerCarousel.swift` 실행, guard 재진입과 조건부 reset 확인
|
||||
- `git diff --check` 실행, 출력 없이 성공
|
||||
- `plutil -lint "SodaLive.xcodeproj/project.pbxproj"` 실행, `OK`
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug -destination "generic/platform=iOS" -derivedDataPath "/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/SodaLiveDerivedDataTask5395Dev" build` 실행, 10분 도구 제한으로 asset/codesign 단계에서 `BUILD INTERRUPTED`
|
||||
- 동일 DerivedData `xcodebuild -quiet ... generic/platform=iOS ...` 재시도와 `CODE_SIGNING_ALLOWED=NO` 재시도도 10분 도구 제한으로 `BUILD INTERRUPTED`
|
||||
- `xcodebuild -quiet ... -destination "generic/platform=iOS Simulator" ... CODE_SIGNING_ALLOWED=NO build` 실행, SPM `Promises` 컴파일 중 비정상 종료되어 `BUILD FAILED`
|
||||
- `/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/SodaLive-sim-build-20260731-200318.log`에서 `BUILD INTERRUPTED` 확인
|
||||
- 수동 확인:
|
||||
- 실제 기기/시뮬레이터의 Bootpay 본인인증 완료와 빠른 경계 연속 스와이프 시각 확인은 이번 환경에서 직접 수행하지 못해 상태 전이 self-check와 정적 검증으로 대체함
|
||||
- 차단:
|
||||
- `SodaLive-dev` Debug 빌드 성공 증거는 확보하지 못함. iPhoneOS 빌드는 10분 도구 제한으로 반복 중단됐고, Simulator 빌드는 SPM `Promises` 컴파일 단계에서 실패함.
|
||||
|
||||
### 2026-07-31 Phase 1~22 리뷰 재점검 및 후속 Task 전환
|
||||
|
||||
- 목적: 현재 working tree의 Phase별 리뷰 판정과 실제 production 코드·활성 계획을 다시 대조하고, 남은 확정 결함을 이어서 실행 가능한 Task로 전환
|
||||
- Phase별 결과:
|
||||
- Phase 1~4, 6~8, 10~22: 기존 Phase별 최신 판정을 유지하며 이번 재점검에서 신규 확정 항목 없음
|
||||
- Phase 5: `REV-P5-002` High 확정 — 한국 사용자에게 본인인증이 먼저 필요한 경우 인증 성공 후 민감 콘텐츠 보기 설정 guard를 건너뛰고 AI 캐릭터 상세 route를 직접 실행함
|
||||
- Phase 9: 기존 `REV-P9-001`의 index 범위 정규화만으로는 예약된 경계 reset이 반대 방향 이동 후 정상 index를 덮어쓰는 상태를 막지 못해 수정 미완료로 재판정
|
||||
- 계획 전환:
|
||||
- Phase 5 `Task 5.3` / `P5-R2` 신규 추가
|
||||
- Phase 9는 동일 경계 상태를 소유하는 기존 미완료 `Task 9.5` / `P9-R1`의 재현·완료 조건을 보강하고 중복 Task는 추가하지 않음
|
||||
- 재현:
|
||||
- `swift -module-cache-path /private/tmp/sodalive-review-module-cache-auth -e '<본인인증 후 pendingAction 상태 전이>'` — `detail=true settings=false`, 설정 guard 우회 재현
|
||||
- `swift -module-cache-path /private/tmp/sodalive-review-module-cache-banner -e '<배너 경계 지연 reset 상태 전이>'` — 반대 방향 이동 후 `beforeDelayedReset=3`, 예약 reset 뒤 `afterDelayedReset=1, expected=3` 재현
|
||||
- 검증:
|
||||
- `xcodebuild -workspace SodaLive.xcworkspace -list` — workspace와 `SodaLive`, `SodaLive-dev` 스킴 인식 확인
|
||||
- `xcodebuild -quiet -workspace SodaLive.xcworkspace -scheme SodaLive-dev -configuration Debug -destination generic/platform=iOS -derivedDataPath /private/tmp/SodaLiveDerivedDataReviewFinal-dev build` — 종료 코드 0
|
||||
- `xcodebuild -quiet -workspace SodaLive.xcworkspace -scheme SodaLive -configuration Debug -destination generic/platform=iOS -derivedDataPath /private/tmp/SodaLiveDerivedDataReviewFinal-dev build` — 종료 코드 0
|
||||
- `plutil -lint SodaLive.xcodeproj/project.pbxproj` — `OK`
|
||||
- `git diff --check`, `git diff --cached --check` — 출력 없이 성공
|
||||
- Phase별 리포트 22개와 각 리포트의 필수 1~9절 존재 확인
|
||||
- 기존 Task 정리:
|
||||
- Phase 4 `Task 4.2` / `P4-R1`은 추천 ViewModel의 직접 `print(` 제거, `ERROR_LOG` 사용과 `SodaLive-dev` 빌드 성공을 확인해 완료 처리
|
||||
- 범위:
|
||||
- 리뷰 리포트와 후속 계획만 갱신했으며 production Swift 코드는 수정하지 않음
|
||||
- 기존 완료 체크와 과거 검증 기록은 삭제하거나 되돌리지 않음
|
||||
|
||||
### 2026-07-31 리뷰 보완 Task 4.2/9.5/19.5 처리
|
||||
|
||||
- 목적: `REV-P4-001`, `REV-P9-001`, `REV-P19-005` 보완
|
||||
- 수행 내용:
|
||||
- `MainHomeRecommendationViewModel.fetchRecommendations()`의 추천 응답 디코딩 `catch`에서 `print(error)`를 `ERROR_LOG(error.localizedDescription)`로 교체
|
||||
- `BannerCarousel.wrapIfNeeded()`에서 `displayIndex`를 `0...items.count + 1` 복제 범위로 정규화해 경계 reset 지연 중 연속 입력이 범위 밖 index를 지속시키지 않도록 보정
|
||||
- Phase 11 활성 Task 기준에 공용 원형 creator widget 우선 검토와 Figma 직사각형 카드 미충족 시 전용 `MainHomeRecentDebutCreatorItemView` 사용 결정을 명시
|
||||
- TDD 예외/대체 검증:
|
||||
- 앱 테스트 번들 타깃이 없어 ViewModel 로그 호출, SwiftUI gesture/timer, 문서 정합성에 대한 영구 unit/UI test는 추가하지 않음
|
||||
- 정적 실패 근거 재현, Swift 상태 전이 self-check, 정적 검색, 공백 오류, 프로젝트 유효성, `SodaLive-dev` Debug 빌드로 대체 검증
|
||||
- 검증:
|
||||
- `rg -n "print\(|ERROR_LOG|func fetchRecommendations|catch" "SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationViewModel.swift" "SodaLive/Sources/Utils/Log.swift"` 실행, 추천 ViewModel 범위의 직접 `print(` 제거와 `ERROR_LOG` 사용 확인
|
||||
- `swift -e '<BannerCarousel index 상태 전이 self-check>'` 실행, 기존 조건의 `items.count + 2`/`-1` 실패와 보정 후 `1...items.count` 복구 self-check 통과 확인
|
||||
- `rg -n "displayIndex = min\(max\(displayIndex, 0\), items.count \+ 1\)|wrapIfNeeded|currentPage" "SodaLive/Sources/V2/Component/Banner/BannerCarousel.swift"` 실행, index 정규화와 기존 page 계산 유지 확인
|
||||
- `rg -n "CreatorProfileGrid|MainHomeRecentDebutCreatorItemView" "docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md" "docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase11-recent-debut-creators.md" "SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeRecentDebutCreatorSection.swift"` 실행, 활성 계획·리뷰·코드 기준 일치 확인
|
||||
- `plutil -lint "SodaLive.xcodeproj/project.pbxproj"` 실행, `OK`
|
||||
- `git diff --check` 실행, 출력 없이 성공
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug -destination "generic/platform=iOS" -derivedDataPath "/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/SodaLiveDerivedDataTask4295195" build` 실행 2회, Pods/SPM 및 app resource 처리 중 10분 도구 제한으로 `BUILD INTERRUPTED`
|
||||
- 차단:
|
||||
- `SodaLive-dev` Debug 빌드 성공 증거와 실제 기기/시뮬레이터 빠른 경계 연속 스와이프 수동 확인은 아직 확보하지 못함
|
||||
- 수동 확인:
|
||||
- 실제 기기/시뮬레이터의 빠른 경계 연속 스와이프 시각 확인은 이번 환경에서 수행하지 못해 정적 self-check와 빌드 결과로 대체함
|
||||
|
||||
### 2026-07-31 Phase 1~22 최종 코드 리뷰 및 신규 Task 전환
|
||||
|
||||
- 목적: 현재 working tree의 PRD, 계획, Phase별 리포트, production 코드와 Xcode target 상태를 다시 대조하고 남은 확정 항목을 실행 가능한 후속 Task로 전환
|
||||
- Phase별 리포팅:
|
||||
- `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase1-*.md`부터 `phase22-*.md`까지 Phase별 22개 리포트를 유지하고 최신 판정을 해당 소유 리포트에 누적
|
||||
- 신규 확정 항목:
|
||||
- `REV-P4-001` Low: 신규 추천 ViewModel의 응답 디코딩 `catch`가 프로젝트 로깅 규칙의 `ERROR_LOG` 대신 `print(error)`를 사용함
|
||||
- `REV-P9-001` Medium: 무한 캐러셀 복제 경계의 지연 reset 중 같은 방향 스와이프가 다시 끝나면 `displayIndex`가 유효 범위를 벗어나 빈 배너 상태가 지속될 수 있음
|
||||
- `REV-P19-005` Low: Phase 11 활성 Task는 `CreatorProfileGrid` 재사용을 완료 조건으로 두지만 현재 코드와 최신 리뷰는 Figma 직사각형 전용 카드를 올바른 구현으로 판정함
|
||||
- 계획 전환:
|
||||
- Phase 4 `Task 4.2` / `P4-R1`
|
||||
- Phase 9 `Task 9.5` / `P9-R1`
|
||||
- Phase 19 `Task 19.5` / `P19-R4`
|
||||
- 기존 항목 재판정:
|
||||
- `REV-P2-001`, `REV-P5-001`, `REV-P6-001`, `REV-P10-001`, `REV-P12-001`, `REV-P15-001`, `REV-P15-002`, `REV-P16-001`, `REV-P16-002`, `REV-P18-001`, `REV-P18-002`, `REV-P19-001`~`REV-P19-004`는 현재 코드·문서에서 수정 완료 상태 유지
|
||||
- Phase 1~3, 5~8, 10~18, 20~22에서는 이번 재점검으로 추가 확정된 production 기능 결함 없음. Phase 11 production 구현은 유지하고 활성 문서 충돌만 Phase 19가 소유
|
||||
- 검증:
|
||||
- `git diff --check`, `git diff --cached --check` — 성공, 출력 없음
|
||||
- `plutil -lint SodaLive.xcodeproj/project.pbxproj` — `OK`
|
||||
- Phase 1~22 리뷰 파일의 샘플 필수 절 `1`~`9` 존재 여부 — 22개 모두 충족
|
||||
- PRD Markdown fence 수 — 10개로 짝수이며 활성 응답 예시 구조 확인
|
||||
- 제외 섹션/Figma URL/기존 `HomeApi` 추천 endpoint 정적 검색 — 검색 결과 없음
|
||||
- `xcodebuild -workspace SodaLive.xcworkspace -list` — 종료 코드 0, `SodaLive`, `SodaLive-dev` scheme 확인
|
||||
- `xcodebuild -quiet -workspace SodaLive.xcworkspace -scheme SodaLive-dev -configuration Debug -destination generic/platform=iOS -derivedDataPath /private/tmp/SodaLiveDerivedDataReview20260731Dev build` — 종료 코드 0
|
||||
- 동일 clean DerivedData의 `SodaLive` Debug 빌드 — 종료 코드 0
|
||||
- 두 빌드에서 `REV-P18-002` 대상 홈 추천 파일 11개의 duplicate build warning 없음. 프로덕션 target의 다른 V2 파일 기존 duplicate warning은 이번 계획 범위 밖으로 유지
|
||||
- 범위:
|
||||
- 이번 리뷰에서는 production 코드 결함을 수정하지 않고 Phase별 리뷰 리포트와 후속 계획만 갱신
|
||||
- 기존 완료 체크와 검증 기록은 삭제·되돌리지 않고 신규 Task와 판정을 누적
|
||||
|
||||
### 2026-07-31 리뷰 보완 Task 10.2/18.4 처리
|
||||
|
||||
- 목적: `REV-P10-001`, `REV-P18-002` 보완
|
||||
- 수행 내용:
|
||||
- `MainHomeActiveCreatorSection`의 최근 활동 상대 시간 표시를 공용 `DateParser.relativeTimeText(fromUTC:fallback:)` 호출로 교체하고 중복 계산 helper를 제거
|
||||
- `SodaLive.xcodeproj/project.pbxproj`의 `SodaLive` Sources phase에서 홈 추천 범위 11개 Swift 파일의 잔여 중복 build file 참조를 제거
|
||||
- TDD 예외/대체 검증:
|
||||
- production 동작을 새로 추가하지 않는 구조 정리와 Xcode Sources 메타데이터 정리 작업이며 앱 테스트 번들 타깃이 없어 신규 테스트는 추가하지 않음
|
||||
- 공용 함수 연결 정적 검색, target별 Sources 등록 수, 프로젝트 유효성, 공백 오류, 두 scheme 빌드와 duplicate warning 검색으로 대체 검증
|
||||
- 검증:
|
||||
- `rg -n "dateComponents|timeIntervalSince|relativeTimeText|relativeActivityAtText" "SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeActiveCreatorSection.swift" "SodaLive/Sources/Common/DateParser.swift"` 실행, 추천 섹션은 `DateParser.relativeTimeText` 호출만 남고 중복 helper는 검색되지 않음
|
||||
- 홈 추천 범위 11개 Swift 파일 Sources 등록 수 대조 — `SodaLive=1`, `SodaLive-dev=1`
|
||||
- `plutil -lint "SodaLive.xcodeproj/project.pbxproj"` 실행, `OK`
|
||||
- `git diff --check` 실행, 출력 없이 성공
|
||||
- `xcodebuild -quiet -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug -destination "generic/platform=iOS" -derivedDataPath "/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/SodaLiveDerivedDataTask184DevRetry" build` 실행, 종료 코드 0
|
||||
- `xcodebuild -quiet -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug -destination "generic/platform=iOS" -derivedDataPath "/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/SodaLiveDerivedDataTask184Prod" build` 실행, 종료 코드 0
|
||||
- 두 빌드 로그에서 `REV-P18-002` 대상 11개 홈 추천 파일의 duplicate build warning은 검색되지 않음. 기존 범위 밖 `MainHomeRankingViewModel.swift`, `MainHomeFollowingViewModel.swift` duplicate warning은 남아 있어 이번 Task에서 변경하지 않음
|
||||
- 첫 `SodaLive-dev` 빌드 시도는 10분 제한으로 `BUILD INTERRUPTED`됐고, 위 결과는 동일 변경을 별도 DerivedData에서 다시 검증한 결과임
|
||||
|
||||
### 2026-07-31 Phase 1~22 최종 재점검 및 후속 Task 전환
|
||||
|
||||
- 목적: 현재 working tree의 Phase별 리포트, PRD, 계획, 코드와 프로젝트 등록을 다시 대조해 기존 보완 판정의 정확성을 확인
|
||||
- 확정 항목:
|
||||
- `REV-P10-001` Low: `MainHomeActiveCreatorSection.relativeActivityAtText(now:)`가 공용 `DateParser.relativeTimeText(fromUTC:fallback:now:)`와 동일한 상대 시간 계산을 복제함
|
||||
- `REV-P18-002` Low: `Task 18.3` 완료 기록과 달리 대상 홈 추천 Swift 파일 11개가 현재 `SodaLive=2`, `SodaLive-dev=1`로 등록되어 프로덕션 duplicate build warning이 남음
|
||||
- 계획 전환:
|
||||
- Phase 10 `Task 10.2` / `P10-R1`: 공용 `DateParser.relativeTimeText` 재사용 및 중복 계산 제거
|
||||
- Phase 18 `Task 18.4` / `P18-R2`: 프로덕션 Sources 잔여 중복 한 건씩 제거 및 두 scheme fresh 빌드 검증
|
||||
- 기존 항목 재판정:
|
||||
- `REV-P2-001`, `REV-P5-001`, `REV-P6-001`, `REV-P12-001`, `REV-P15-001`, `REV-P15-002`, `REV-P16-001`, `REV-P16-002`, `REV-P19-001`~`REV-P19-004`는 현재 코드·문서에서 수정 완료 상태 유지
|
||||
- Phase 1~9, 11~17, 19~22에서는 이번 재점검으로 추가 확정된 기능 결함 없음
|
||||
- 검증:
|
||||
- `git diff --check` — 성공, 출력 없음
|
||||
- `plutil -lint SodaLive.xcodeproj/project.pbxproj` — `OK`
|
||||
- 제외 섹션/Figma URL/기존 `HomeApi` 추천 endpoint 정적 검색 — 검색 결과 없음
|
||||
- PBX Sources phase 대조 — 대상 11개 파일 모두 `SodaLive=2`, `SodaLive-dev=1`
|
||||
- 격리 DerivedData 빌드 — `SodaLive`와 `SodaLive-dev` 모두 종료 코드 0
|
||||
- 빌드 경고 대조 — `SodaLive`에서는 대상 11개 파일의 duplicate build warning이 모두 재현됐고 `SodaLive-dev`에서는 대상 경고 없음
|
||||
- 범위:
|
||||
- 이번 리뷰에서는 production Swift 코드와 프로젝트 중복 등록을 수정하지 않고 후속 Task만 추가
|
||||
- 기존 완료 체크와 과거 검증 기록은 삭제·되돌리지 않고 후속 판정을 누적
|
||||
|
||||
### 2026-07-31 리뷰 보완 Task 18.3/19.4 처리
|
||||
|
||||
- 목적: `REV-P18-001`, `REV-P19-004` 보완
|
||||
- 수행 내용:
|
||||
- `SodaLive.xcodeproj/project.pbxproj`에서 홈 추천 범위 11개 Swift 파일의 중복 Compile Sources 등록을 정리
|
||||
- PRD Goal의 활성 추천 API 타입명을 `MainHomeRecommendationApi`로 정정
|
||||
- Phase 11/21 리뷰의 오기 기록을 삭제하지 않고 append-only 후속 정정 완료 기록 추가
|
||||
- TDD 예외/대체 검증:
|
||||
- production 동작 변경이 아니라 Xcode Sources 메타데이터와 문서 정정 작업이므로 신규 테스트는 추가하지 않음
|
||||
- target별 Sources 등록 수, 프로젝트 파싱, 정적 검색, 공백 오류 검증으로 대체
|
||||
- 검증:
|
||||
- 홈 추천 범위 11개 Swift 파일 Sources 등록 수 대조 — `SodaLive=1`, `SodaLive-dev=1`
|
||||
- `plutil -lint "SodaLive.xcodeproj/project.pbxproj"` 실행, `OK`
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -list` 실행, 프로젝트 파싱 성공 및 `SodaLive`, `SodaLive-dev` scheme 확인
|
||||
- `xcodebuild -quiet -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug -derivedDataPath "/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/SodaLiveDerivedDataTask183DevRetry" build` 실행, 종료 코드 0
|
||||
- `xcodebuild -quiet -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug -derivedDataPath "/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/SodaLiveDerivedDataTask183ProdFinal" build` 실행, 종료 코드 0
|
||||
- 두 빌드 로그에서 `REV-P18-001` 대상 11개 홈 추천 파일의 duplicate build warning은 검색되지 않음. 기존 범위 밖 V2 파일 duplicate warning은 남아 있어 이번 Task에서 변경하지 않음
|
||||
- `rg -n "MainHomeApi|MainHomeRecommendationApi|CreatorProfileGrid|MainHomeRecentDebutCreatorItemView|LIVE_REPLAY|liveReplay|targetId" "docs/20260602_메인_홈_추천_UI_API_연동/prd.md" "docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase11-recent-debut-creators.md" "docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase21-recent-activity-live-fallback.md"` 실행, 활성 타입명과 append-only 정정 기록 확인
|
||||
- `git diff --check` 실행, 출력 없이 성공
|
||||
- 부수 정리:
|
||||
- 빌드 과정에서 SwiftPM이 자동 갱신한 `SodaLive.xcworkspace/xcshareddata/swiftpm/Package.resolved`는 이번 Task 범위 밖 변경이므로 원래 내용으로 되돌림
|
||||
|
||||
### 2026-07-31 Phase 1~22 최종 리뷰 점검 및 후속 Task 전환
|
||||
|
||||
- 목적: Phase별 기존 리뷰와 보완 구현을 최신 working tree에서 다시 대조하고, 누락된 프로젝트·문서 결함을 실행 가능한 후속 Task로 전환
|
||||
- 확정 항목:
|
||||
- `REV-P18-001` Low: `SodaLive` target에서 이번 계획 범위의 홈 추천 Swift 파일 11개가 각각 두 번 Sources 등록되어 프로덕션 빌드에 duplicate build warning이 발생함
|
||||
- `REV-P19-004` Low: PRD의 활성 추천 API 타입명과 Phase 11/21 후속 리뷰 기록 일부가 현재 Swift 구현과 다름
|
||||
- 계획 전환:
|
||||
- Phase 18 `Task 18.3` / `P18-R1`: 대상 11개 파일의 프로덕션 중복 Sources 등록 제거 및 두 scheme 빌드 검증
|
||||
- Phase 19 `Task 19.4` / `P19-R3`: PRD API 타입명과 append-only 리뷰 정정 기록 보완
|
||||
- 기존 항목 재판정:
|
||||
- `REV-P16-002`의 `V2ExpandableTextView.swift`는 두 앱 target에 각각 한 번만 등록되고 최신 프로덕션 빌드에서 해당 중복 경고가 없어 수정 완료 유지
|
||||
- Phase 1~6, 8~17, 20~22 production 코드에서는 이번 최종 점검으로 추가 확정된 기능 결함 없음
|
||||
- 검증:
|
||||
- `git diff --check` — 성공, 출력 없음
|
||||
- `plutil -lint SodaLive.xcodeproj/project.pbxproj` — `OK`
|
||||
- 제외 섹션/Figma URL/기존 `HomeApi` 추천 endpoint 정적 검색 — 검색 결과 없음
|
||||
- PBX Sources phase 대조 — `REV-P18-001` 대상 11개 파일은 `SodaLive=2`, `SodaLive-dev=1`
|
||||
- `xcodebuild -quiet -workspace SodaLive.xcworkspace -scheme SodaLive -configuration Debug -derivedDataPath /private/tmp/SodaLiveDerivedDataReviewCurrentProd build` — 종료 코드 0, 빌드 성공 및 대상 duplicate warning 재현
|
||||
- 최신 `SodaLive-dev` 빌드 재실행은 10분 이상 종료되지 않아 중단했으며, 동일 dev target의 직전 현재 변경군 `BUILD SUCCEEDED` 기록을 유지
|
||||
- 범위:
|
||||
- production 코드와 프로젝트 중복 등록은 수정하지 않고 후속 Task만 추가
|
||||
- 기존 완료 기록과 리뷰 판정은 삭제하지 않고 Phase별 리포트에 후속 판정을 누적
|
||||
|
||||
### 2026-07-31 리뷰 보완 Task 6.4/15.3/16.3/19.3 처리
|
||||
|
||||
- 목적: 2026-07-31 재점검에서 확정된 `REV-P6-001`, `REV-P15-002`, `REV-P16-002`, `REV-P19-002`, `REV-P19-003` 보완
|
||||
- 수행 내용:
|
||||
- `MainHomeView`의 추천/랭킹/팔로잉 탭 제목을 기존 `I18n.MainContentRecommendation.tabTitle`, `I18n.MainContentRanking.tabTitle`, `I18n.HomeFollowing.tabTitle`로 교체
|
||||
- `CommunityPostCard`에서 `imageUrl == nil && price > 0 && existOrdered == false`인 게시물도 기존 `onTapPurchase` callback으로 진입하는 구매 affordance 표시
|
||||
- `SodaLive` target에 중복 등록된 `V2ExpandableTextView.swift in Sources` 한 건 제거, `SodaLive-dev` target 등록은 유지
|
||||
- PRD 응답 모델 예시의 Markdown fence를 모델 단위로 분리하고 활성 V2 확장 텍스트 경로를 `V2ExpandableTextView.swift`로 정정
|
||||
- TDD 예외/대체 검증:
|
||||
- 저장소에 앱 테스트 번들 타깃이 없어 SwiftUI 렌더링·버튼 callback을 직접 실행하는 영구 unit/UI test는 추가하지 않음
|
||||
- 변경 전 정적 RED 체크에서 한글 탭 제목, 이미지 없는 유료 미구매 구매 affordance 부재, PBX 중복 등록, 활성 문서의 이전 경로를 재현
|
||||
- 검증:
|
||||
- `rg -n 'MainContentRecommendation\.tabTitle|MainContentRanking\.tabTitle|HomeFollowing\.tabTitle' SodaLive/Sources/V2/Main/Home/MainHomeView.swift` 실행, 기존 I18n 키 연결 확인
|
||||
- `rg -n 'hasImage|isLocked|lockedTextPurchaseButton|paidLockOverlay|purchaseCommunityPost|onTapPurchase' SodaLive/Sources/V2/Component/Card/CommunityPostCard.swift SodaLive/Sources/V2/Main/Home/Recommendation` 실행, 이미지 유무와 무관한 유료 미구매 구매 경로 확인
|
||||
- `rg -n 'V2ExpandableTextView\.swift in Sources|C922F89D' SodaLive.xcodeproj/project.pbxproj` 실행, build file은 `C922F89B`, `C922F89C` 두 건만 남고 중복 `C922F89D` 제거 확인
|
||||
- `rg -n '^```|#### RecommendationBannerResponse|#### HomePopularCommunityPostItem|V2/Component/Text/(ExpandableTextView|V2ExpandableTextView)\.swift|V2ExpandableTextView' docs/20260602_메인_홈_추천_UI_API_연동/prd.md docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md` 실행, PRD fence 10개와 활성 `V2ExpandableTextView.swift` 경로 확인
|
||||
- `plutil -lint SodaLive.xcodeproj/project.pbxproj` 실행, `OK`
|
||||
- `git diff --check` 실행, 출력 없이 성공
|
||||
- `SodaLive-dev` Debug 전체 빌드는 일반 실행 2회와 백그라운드 실행 1회가 모두 Pods/SDK 컴파일 중 10분 도구 제한을 초과해 완료 증거를 확보하지 못함. 백그라운드 프로세스 `20992`는 종료 처리함
|
||||
- Oracle 리뷰어 게이트 실행, 네 보완 Task에 대한 차단/중요 findings 없음 판정
|
||||
- `lsp_diagnostics`는 개별 Swift 파일 단독 분석에서 기존 프로젝트 타입과 외부 모듈(`Kingfisher`)을 찾지 못해 false positive를 반환했으므로 실제 컴파일 검증은 `xcodebuild` 결과를 기준으로 판단
|
||||
- 미실행 수동 확인:
|
||||
- 실제 기기/시뮬레이터에서 ko/en/ja 탭 제목과 이미지 없는 유료 미구매 카드 구매 버튼 탭의 API 1회 호출은 아직 수행하지 못함
|
||||
|
||||
### 2026-07-31 Phase 1~22 후속 통합 리뷰 및 신규 Task 전환
|
||||
|
||||
- 목적: 2026-07-30 통합 리뷰 후 보완된 구현과 Phase 22 수동 완료 상태를 현재 PRD·계획·코드·프로젝트에 다시 대조하고, 새로 확정한 항목을 소유 Phase의 실행 가능한 Task로 전환
|
||||
- Phase별 리포팅:
|
||||
- `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase1-*.md`부터 `phase22-*.md`까지 22개 리포트에 2026-07-31 재점검 기록을 각각 누적
|
||||
- 기존 리뷰 항목 재판정:
|
||||
- `REV-P2-001`, `REV-P5-001`, `REV-P12-001`, `REV-P15-001`, `REV-P16-001`, `REV-P19-001`은 현재 구현·문서에서 수정 완료 확인
|
||||
- 신규 확정 항목:
|
||||
- `REV-P6-001` Medium: 홈 추천/랭킹/팔로잉 탭 제목이 기존 I18n 키를 사용하지 않고 한글 문자열로 고정됨
|
||||
- `REV-P15-002` Medium: `imageUrl == nil`인 유료 미구매 게시물은 잠금·구매 Button이 렌더링되지 않아 기존 구매 API로 진입할 수 없음
|
||||
- `REV-P16-002` Low: `V2ExpandableTextView.swift`가 프로덕션 `SodaLive` Sources에 두 번 등록됨
|
||||
- `REV-P19-002` Low: PRD 7.1 응답 예시의 Markdown code fence가 중첩·누락됨
|
||||
- `REV-P19-003` Low: PRD와 계획의 활성 기준이 이름 변경 전 V2 `ExpandableTextView.swift` 경로를 가리킴
|
||||
- 계획 전환:
|
||||
- Phase 6 `Task 6.4` / `P6-R1`
|
||||
- Phase 15 `Task 15.3` / `P15-R2`
|
||||
- Phase 16 `Task 16.3` / `P16-R2`
|
||||
- Phase 19 `Task 19.3` / `P19-R2`
|
||||
- 검증:
|
||||
- `MainHomeView.swift`, `CommunityPostCard.swift`, `I18n.swift`, PRD와 PBX Sources phase를 줄 단위로 대조해 각 실패 조건을 재현
|
||||
- PBX Sources phase 대조 결과 `V2ExpandableTextView.swift in Sources` 포함 수 `SodaLive=2`, `SodaLive-dev=1`
|
||||
- `xcodebuild -workspace SodaLive.xcworkspace -scheme SodaLive -configuration Debug -derivedDataPath /private/tmp/SodaLiveDerivedDataReviewCurrentProd build` 실행, `BUILD SUCCEEDED`
|
||||
- 필터링한 증분 빌드에서 `Skipping duplicate build file ... V2ExpandableTextView.swift` 경고 재현, 종료 코드 0
|
||||
- `SodaLive-dev` Debug 빌드는 같은 현재 source/project 상태에 대한 2026-07-31 Phase 22.3 검증에서 `BUILD SUCCEEDED`
|
||||
- 범위:
|
||||
- 리뷰 리포트와 후속 계획만 갱신했으며 신규 확정 항목의 production 코드·프로젝트·PRD 수정은 수행하지 않음
|
||||
- 기존 완료 체크와 과거 검증 기록은 유지하고 신규 Task는 미완료 상태로 추가
|
||||
|
||||
### 2026-07-31 Phase 22.3 모두 팔로우 확인 흐름 수동 검증 완료
|
||||
|
||||
- 목적: Confirm Dialog가 의도하지 않은 대량 팔로우를 차단하면서 기존 인증·완료·loading·오류 흐름을 유지하는지 최종 판정
|
||||
- 수동 확인 결과:
|
||||
- 로그인 사용자가 `모두 팔로우하기`를 터치하면 Dialog가 표시되고 확인 전 API 요청은 발생하지 않음
|
||||
- `취소` 또는 dimmed 영역 터치 시 Dialog가 닫히고 API 요청은 발생하지 않음
|
||||
- `팔로우 하기`를 한 번 터치하면 Dialog가 닫히고 해당 섹션의 기존 API 요청이 1회 발생함
|
||||
- 비로그인 사용자는 Dialog 없이 로그인 화면으로 이동하고, 로그인 완료 후 자동 팔로우하지 않음
|
||||
- 기존 완료/호출 중 버튼 상태와 API 실패 toast에서 발견된 오류 없음
|
||||
- 앱 언어 ko/en/ja에서 제목, 설명, 확인, 취소 문구 표시에서 발견된 오류 없음
|
||||
- 검증:
|
||||
- 사용자 수동 테스트 결과 발견된 오류 없음
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug -derivedDataPath "/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/SodaLiveDerivedDataFinalCheck" build`: `BUILD SUCCEEDED`
|
||||
- `Task 22.3` 완료 처리
|
||||
|
||||
### 2026-07-30 리뷰 보완 Task 2.3/5.2/12.2/15.2/16.2/19.2 처리
|
||||
|
||||
- 목적: 통합 리뷰에서 확정된 `REV-P2-001`, `REV-P5-001`, `REV-P12-001`, `REV-P15-001`, `REV-P16-001`, `REV-P19-001` 보완
|
||||
- 수행 내용:
|
||||
- `HomeRecommendationResponse`에서 PRD 응답 계약에 없는 `firstAudioContents`와 `HomeFirstAudioContentItem` 제거
|
||||
- 추천 AI 캐릭터 탭 callback을 `creatorId`가 아니라 `characterId`로 전달하도록 수정
|
||||
- 추천 AI 캐릭터 전용 `handleRecommendationCharacterTap(characterId:)`를 추가하고 기존 추천 상세 guard를 거쳐 `.characterDetail(characterId:)`로 이동하도록 연결
|
||||
- `CommunityPostCard.isAccessiblePost`를 `price <= 0 || existOrdered`로 수정
|
||||
- 사업자 정보 섹션의 private `BusinessInfoExpandableTextView` 중복 구현을 제거하고 V2 공용 `V2ExpandableTextView`로 단일화
|
||||
- legacy `CustomView/ExpandableTextView`와 산출물 충돌을 피하기 위해 V2 공용 파일명을 `V2ExpandableTextView.swift`로 정리하고 Xcode Sources에 포함
|
||||
- PRD와 Phase 17 활성 기준에서 장르 크리에이터 섹션 미표시 결정을 반영하고, `genreCreators` 응답 모델 유지는 구분해 기록
|
||||
- TDD 예외/대체 검증:
|
||||
- 저장소에 앱 테스트 번들 타깃이 없어 production Swift 모델/UI callback을 import하는 영구 unit test는 추가하지 않음
|
||||
- `swift -module-cache-path "/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/sodalive-swift-module-cache" -e '<PRD 필수 필드만 포함한 추천 JSON 디코딩>'` 실행, `decoded without firstAudioContents` 확인
|
||||
- 검증:
|
||||
- `rg -n "firstAudioContents|HomeFirstAudioContentItem" "SodaLive/Sources/V2/Main/Home/Recommendation"` 실행, 검색 결과 없음 확인
|
||||
- `rg -n "onTapCharacter:|handleRecommendationCharacterTap|characterDetail\(characterId:|onTapCharacter\(item\.(characterId|creatorId)\)" "SodaLive/Sources/V2/Main/MainView.swift" "SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeAiCharacterSection.swift"` 실행, `item.characterId`, `handleRecommendationCharacterTap`, `characterDetail(characterId:)` 연결 확인
|
||||
- `rg -n "price (==|<=) 0 \|\| existOrdered|isAccessiblePost|isLocked" "SodaLive/Sources/V2/Component/Card/CommunityPostCard.swift"` 실행, `price <= 0 || existOrdered` 확인
|
||||
- `rg -n "V2ExpandableTextView|BusinessInfoExpandableTextView|struct ExpandableTextView|struct V2ExpandableTextView" "SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeBusinessInfoSection.swift" "SodaLive/Sources/V2/Component/Text" "SodaLive/Sources/CustomView/ExpandableTextView.swift"` 실행, 사업자 섹션은 V2 공용 구현을 사용하고 legacy 타입은 기존 경로에만 남음 확인
|
||||
- `rg -n "장르의 크리에이터|MainHomeGenreCreatorSection|genreCreators" "docs/20260602_메인_홈_추천_UI_API_연동" "SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift"` 실행, 최신 미표시 결정과 과거 기록 구분 확인
|
||||
- `plutil -lint "SodaLive.xcodeproj/project.pbxproj"` 실행, `OK`
|
||||
- `git diff --check` 실행, 출력 없이 성공
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug -derivedDataPath "/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/SodaLiveDerivedDataReviewSupplement" build` 실행, V2/legacy 파일명이 모두 `ExpandableTextView.swift`라 `Multiple commands produce ... ExpandableTextView.stringsdata`로 실패 확인
|
||||
- V2 공용 파일명을 `V2ExpandableTextView.swift`로 정리 후 `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug -derivedDataPath "/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/SodaLiveDerivedDataReviewSupplement2" build` 최초 실행은 10분 제한으로 `BUILD INTERRUPTED` 확인
|
||||
- 동일 빌드 명령 재실행, `BUILD SUCCEEDED` 확인
|
||||
- `lsp_diagnostics`는 개별 Swift 파일 단독 분석에서 기존 프로젝트 타입과 외부 모듈(`Kingfisher`, `Bootpay`)을 찾지 못해 false positive를 반환했으므로, 실제 컴파일 검증은 `xcodebuild` 결과를 기준으로 판단
|
||||
- 미실행 수동 확인:
|
||||
- 실제 기기/시뮬레이터에서 AI 캐릭터 탭, 커뮤니티 가격 상태 UI, 사업자 정보 3줄 이하/초과 토글, 모두 팔로우 API 요청 0/1회, ko/en/ja 표시 확인은 아직 수행하지 못함
|
||||
- `Task 22.3`은 실제 로그인/네트워크/언어 화면 수동 확인이 필요하므로 미완료 유지
|
||||
|
||||
### 2026-07-30 Phase 1~22 구현 통합 리뷰 및 후속 Task 전환
|
||||
|
||||
- 목적: 완료 또는 진행된 각 Phase의 계획 체크, 실제 코드·프로젝트 포함 상태·검증 기록을 현재 PRD와 저장소 가이드에 대조하고, 확정된 수정 항목을 소유 Phase의 실행 가능한 신규 Task로 전환
|
||||
- 리뷰 결과:
|
||||
- Phase별 리포트 22개를 `docs/20260602_메인_홈_추천_UI_API_연동/reviews/phase<번호>-*.md`로 분리 작성
|
||||
- `REV-P2-001` High: PRD에 없는 non-optional `firstAudioContents` 때문에 기준 응답이 `keyNotFound`로 전체 디코딩 실패 가능
|
||||
- `REV-P5-001` High: 추천 AI 캐릭터 callback이 크리에이터 상세 handler에 연결됨
|
||||
- `REV-P12-001` High: AI 캐릭터 카드가 `characterId` 대신 `creatorId`를 callback으로 전달함
|
||||
- `REV-P15-001` Low: 커뮤니티 무료 판정이 PRD의 `price <= 0`이 아니라 `price == 0`으로 구현됨
|
||||
- `REV-P16-001` Low: 공용 V2 확장 텍스트 파일은 Sources 미포함이고 사업자 화면에 동일 구현이 복제됨
|
||||
- `REV-P19-001` Low: 장르 섹션 미표시 결정과 PRD/Phase 17 활성 기준이 충돌함
|
||||
- Phase 22는 정적/빌드 결함이 추가로 확인되지 않았으나 실제 요청 0/1회와 ko/en/ja 화면 확인이 미실행이므로 기존 Task 22.3을 미완료로 유지
|
||||
- 계획 전환:
|
||||
- Phase 2 `Task 2.3` / `P2-R1`
|
||||
- Phase 5 `Task 5.2` / `P5-R1`
|
||||
- Phase 12 `Task 12.2` / `P12-R1`
|
||||
- Phase 15 `Task 15.2` / `P15-R1`
|
||||
- Phase 16 `Task 16.2` / `P16-R1`
|
||||
- Phase 19 `Task 19.2` / `P19-R1`
|
||||
- 검증:
|
||||
- `git diff --check` 실행, 출력 없이 성공
|
||||
- `plutil -lint SodaLive.xcodeproj/project.pbxproj` 실행, `OK`
|
||||
- 제외 섹션/Figma URL/기존 `HomeApi` 추천 endpoint 정적 검색, 검색 결과 없음
|
||||
- `swift -module-cache-path /private/tmp/sodalive-review-swift-module-cache -e '<필수 Decodable 키 누락 재현>'` 실행, `keyNotFound(firstAudioContents)` 재현
|
||||
- 샌드박스 내 `xcodebuild -workspace "SodaLive.xcworkspace" -list`는 CoreSimulator/캐시 접근 제한으로 실패
|
||||
- 샌드박스 밖 `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug -derivedDataPath "/private/tmp/SodaLiveDerivedDataReview20260730" build` 재실행, `BUILD SUCCEEDED`
|
||||
- 범위:
|
||||
- 리뷰 리포트와 후속 계획만 작성했으며 production Swift 코드는 수정하지 않음
|
||||
- 기존 완료 체크와 과거 검증 기록은 삭제하거나 되돌리지 않음
|
||||
|
||||
### 2026-07-30 Phase 22 모두 팔로우 Confirm Dialog 코드 구현
|
||||
|
||||
- 목적: 로그인 사용자의 추천 탭 `모두 팔로우하기` API 호출을 Confirm Dialog 확인 이후로 지연
|
||||
- 수행 내용:
|
||||
- `MainView.handleRecommendationFollowAllTap`에서 비로그인 사용자는 기존처럼 로그인 화면으로 이동하도록 유지
|
||||
- 로그인 사용자는 `SodaV2ActionModal` Confirm Dialog를 표시하고, `팔로우 하기` 확인 시 보류한 followAll action을 1회 실행하도록 연결
|
||||
- `취소`와 dimmed 영역 터치 시 Dialog를 닫고 보류 action을 폐기하도록 연결
|
||||
- Dialog 제목, 설명, 확인 버튼 문구를 `I18n.HomeRecommendation`에 ko/en/ja로 추가하고 취소 버튼은 `I18n.Common.cancel` 재사용
|
||||
- 기존 `MainHomeRecommendationViewModel.followAll`, `FollowRecommendedCreatorsRequest`, Repository/API 계약은 변경하지 않음
|
||||
- TDD 예외 사유:
|
||||
- `SodaLive-dev` scheme의 test action이 구성되어 있지 않고, SwiftUI Dialog와 실제 네트워크 요청 횟수 통합 흐름을 위한 신규 테스트 인프라 추가는 이번 최소 변경 범위를 벗어남
|
||||
- 검증:
|
||||
- `rg -n "handleRecommendationFollowAllTap|SodaV2ActionModal|pendingRecommendationFollowAllAction|isShowRecommendationFollowAllConfirmDialog|followAllConfirm|I18n.Common.cancel" "SodaLive/Sources/V2/Main/MainView.swift" "SodaLive/Sources/I18n/I18n.swift"` 실행, 로그인 guard 뒤 Confirm Dialog 표시, 보류 action, 확인/취소 처리와 다국어 키 확인
|
||||
- `rg -n "followRecommendedCreators|FollowRecommendedCreatorsRequest" "SodaLive/Sources/V2/Main/Home/Recommendation"` 실행, 기존 모두 팔로우 API와 request 경로 유지 확인
|
||||
- `git diff --check` 실행, 출력 없이 성공 확인
|
||||
- `plutil -lint "SodaLive.xcodeproj/project.pbxproj"` 실행, `OK` 확인
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug -derivedDataPath "/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/SodaLiveDerivedDataPhase22" build` 최초 실행은 10분 제한으로 `BUILD INTERRUPTED` 확인
|
||||
- 동일 빌드 명령 재실행, `BUILD SUCCEEDED` 확인
|
||||
- `lsp_diagnostics`는 개별 Swift 파일 단독 분석에서 기존 프로젝트 모듈(`Bootpay`)을 찾지 못해 false positive를 반환했으므로, 실제 컴파일 검증은 `xcodebuild` 결과를 기준으로 판단
|
||||
- 미실행 수동 확인:
|
||||
- 실제 기기/시뮬레이터에서 로그인/비로그인, 확인 전 API 0회, 취소/dimmed API 0회, 확인 API 1회, ko/en/ja 표시 확인은 아직 수행하지 못했으므로 Task 22.3 Phase Gate는 미완료로 유지
|
||||
|
||||
### 2026-07-30 Phase 22 모두 팔로우 확인 Dialog 요구사항 문서화
|
||||
|
||||
- 목적: 의도하지 않은 다중 크리에이터 팔로우를 막기 위한 Confirm Dialog 요구사항과 실행 계획을 인터뷰 결정 기준으로 확정
|
||||
- 수행 내용:
|
||||
- 기존 메인 홈 추천 UI/API 연동 PRD에 문제, 목표, 사용자 흐름, 적용 범위, 로그인 순서, ko/en/ja 문구, 성공 기준과 Decision Log 추가
|
||||
- 메인 홈 추천 탭의 모든 공통 `모두 팔로우하기` 진입점에 적용하되 현재 미노출 장르 섹션을 다시 표시하지 않도록 범위 확정
|
||||
- 비로그인 사용자는 기존 로그인 이동을 유지하고, 로그인 사용자는 `팔로우 하기` 확인 시에만 기존 API를 호출하도록 확정
|
||||
- 취소와 dimmed 영역 터치는 보류 action 폐기 및 API 미호출로 확정
|
||||
- 실제 Swift/I18n 구현과 빌드·수동 API 검증은 Task 22.2~22.3 미완료 상태로 분리
|
||||
- 검증:
|
||||
- `rg "모두 팔로우 확인 Dialog|모두 팔로우할까요|Follow all creators|すべてのクリエイターをフォローしますか|dimmed|자동 팔로우" docs/20260602_메인_홈_추천_UI_API_연동/prd.md docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md` 실행, 적용 범위, 인증 순서, 취소 동작과 ko/en/ja 문구가 두 문서에서 검색됨 확인
|
||||
- `git diff --check -- docs/20260602_메인_홈_추천_UI_API_연동/prd.md docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md` 실행, 출력 없이 성공 확인
|
||||
|
||||
### 2026-07-30 Phase 21 최근 활동 LIVE 이동 fallback 구현 완료
|
||||
|
||||
- 목적: 최근 활동 크리에이터의 `LIVE` fallback과 `LIVE_REPLAY` 콘텐츠 상세 이동을 코드에 반영
|
||||
|
||||
Reference in New Issue
Block a user