fix(main): 최근 활동 이동을 보정한다
This commit is contained in:
@@ -537,8 +537,151 @@
|
||||
- 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build`
|
||||
- 기대 결과: `BUILD SUCCEEDED`
|
||||
|
||||
### Phase 21: 최근 활동 LIVE 이동 fallback 보정
|
||||
|
||||
**Phase 결과:** 최근 활동 크리에이터의 서버 원본 `activityType == LIVE` 아이템은 `targetId` 유무에 따라 라이브룸 또는 크리에이터 채널로 이동한다. `LIVE_REPLAY`는 표시 문구를 기존 `라이브`로 유지하되, `AUDIO`와 동일하게 콘텐츠 상세 페이지로 이동한다.
|
||||
|
||||
**선행조건:** 서버가 `HomeActiveCreatorItem.creatorId`를 항상 유효한 양수의 non-null `Long` 값으로 제공한다.
|
||||
|
||||
- [x] **Task 21.1: PRD/계획 문서에 LIVE 이동 fallback 요구사항 추가**
|
||||
- Goal: 인터뷰에서 확정한 응답 필드, 이동 분기, 양수 검사, 회귀 제외 범위를 구현 기준으로 고정한다.
|
||||
- 대상 파일:
|
||||
- 수정: `docs/20260602_메인_홈_추천_UI_API_연동/prd.md`
|
||||
- 수정: `docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md`
|
||||
- 작업 내용:
|
||||
- `HomeActiveCreatorItem` 응답에 non-null `creatorId`가 추가됨을 명시한다.
|
||||
- 서버 원본 `activityType == LIVE`에서 `targetId != null`이면 라이브룸, `targetId == null`이면 `creatorId` 기반 크리에이터 채널로 이동하도록 명시한다.
|
||||
- 서버가 `creatorId`를 유효한 양수로 보장하더라도 앱에서 `creatorId > 0`을 검사하도록 명시한다.
|
||||
- `LIVE_REPLAY`에는 `LIVE`의 새 fallback을 적용하지 않고, `AUDIO`와 동일하게 `targetId` 기반 콘텐츠 상세 페이지로 이동하도록 명시한다.
|
||||
- `AUDIO`, `COMMUNITY`, 알 수 없는 타입의 기존 동작은 변경하지 않도록 명시한다.
|
||||
- 완료 증거:
|
||||
- PRD 응답 스키마, 상세 진입 규칙, 성공 기준, 검증 계획과 이 Phase의 구현 Task가 같은 요구사항을 사용한다.
|
||||
- TDD 예외 사유:
|
||||
- production 동작을 변경하지 않는 문서 갱신 Task다.
|
||||
- 검증 기준:
|
||||
- 실행 명령: `rg "creatorId: Long|activityType == LIVE|targetId == null|creatorId > 0|LIVE_REPLAY" docs/20260602_메인_홈_추천_UI_API_연동/prd.md docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md`
|
||||
- 기대 결과: 응답 필드, 분기 조건, 양수 검사, `LIVE_REPLAY` 제외 규칙이 두 문서에서 검색된다.
|
||||
|
||||
- [x] **Task 21.2: 최근 활동 응답 모델과 활동 타입 구분 보정**
|
||||
- Goal: `creatorId`를 필수 값으로 디코딩하고 `LIVE`와 `LIVE_REPLAY`를 이동 분기에서 구분할 수 있게 한다.
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive/Sources/V2/Main/Home/Recommendation/Models/MainHomeRecommendationResponse.swift`
|
||||
- 수정: `SodaLive/Sources/V2/Main/Home/Recommendation/Models/RecommendedActivityType.swift`
|
||||
- 수정: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeActiveCreatorSection.swift`
|
||||
- 작업 내용:
|
||||
- `HomeActiveCreatorItem`에 non-optional `creatorId: Int`를 추가한다.
|
||||
- `RecommendedActivityType`에서 `LIVE`와 `LIVE_REPLAY`를 별도 case로 디코딩하되 두 case의 표시 문구는 기존 라이브 문구를 유지한다.
|
||||
- Preview의 `HomeActiveCreatorItem` 생성부에 `creatorId`를 추가한다.
|
||||
- 완료 증거:
|
||||
- 모델과 Preview가 신규 필드를 사용하고, `LIVE`와 `LIVE_REPLAY`의 표시 문구는 같지만 enum case는 구분된다.
|
||||
- 검증 기준:
|
||||
- 실행 명령: `rg "creatorId|case liveReplay|LIVE_REPLAY|HomeActiveCreatorItem\\(" SodaLive/Sources/V2/Main/Home/Recommendation`
|
||||
- 기대 결과: 신규 필드와 구분된 활동 타입, 갱신된 Preview 생성부가 검색된다.
|
||||
|
||||
- [x] **Task 21.3: LIVE 분기와 LIVE_REPLAY 콘텐츠 이동 연결 및 회귀 검증**
|
||||
- Goal: 최근 활동 `LIVE` 아이템의 두 이동 경로와 `LIVE_REPLAY`의 콘텐츠 상세 이동을 기존 추천 상세 진입 callback에 연결한다.
|
||||
- 대상 파일:
|
||||
- 수정: `SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift`
|
||||
- 수정: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeActiveCreatorSection.swift`
|
||||
- 확인: `SodaLive/Sources/V2/Main/Home/MainHomeView.swift`
|
||||
- 확인: `SodaLive/Sources/V2/Main/MainView.swift`
|
||||
- 확인: `SodaLive.xcodeproj/project.pbxproj`
|
||||
- 작업 내용:
|
||||
- `MainHomeActiveCreatorSection`에 기존 `onTapCreator` callback을 전달한다.
|
||||
- 서버 원본 `LIVE`에서 `targetId`가 있으면 `onTapLive(targetId)`, 없으면 `creatorId > 0` 검사 후 `onTapCreator(creatorId)`를 실행한다.
|
||||
- `LIVE_REPLAY`는 `AUDIO`와 동일하게 `targetId`가 있을 때 `onTapContent(targetId)`를 실행하고, 없으면 아무 동작도 하지 않는다.
|
||||
- `AUDIO`, `COMMUNITY`, 알 수 없는 타입의 기존 동작을 유지한다.
|
||||
- 라이브룸과 크리에이터 채널 이동은 `MainView`의 기존 추천 상세 진입 guard를 재사용한다.
|
||||
- 완료 증거:
|
||||
- `LIVE`의 두 분기, `creatorId` 양수 검사, `LIVE_REPLAY`의 콘텐츠 상세 이동이 코드에 존재하고, 정적 검증과 `SodaLive-dev` 빌드가 성공한다.
|
||||
- 검증 기준:
|
||||
- 실행 명령: `rg "onTapCreator|creatorId > 0|targetId|liveReplay|onTapLive|onTapContent|onTapCommunityPost" SodaLive/Sources/V2/Main/Home/Recommendation SodaLive/Sources/V2/Main/MainView.swift`
|
||||
- 기대 결과: `LIVE`의 두 이동 경로, `LIVE_REPLAY`의 `onTapContent` 연결, 다른 활동 타입의 기존 callback이 검색된다.
|
||||
- 실행 명령: `git diff --check`
|
||||
- 기대 결과: 출력 없이 성공한다.
|
||||
- 실행 명령: `plutil -lint SodaLive.xcodeproj/project.pbxproj`
|
||||
- 기대 결과: `OK`
|
||||
- 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build`
|
||||
- 기대 결과: `BUILD SUCCEEDED`
|
||||
- 수동 확인:
|
||||
- `LIVE + targetId != nil` 아이템을 터치하면 라이브룸으로 이동한다.
|
||||
- `LIVE + targetId == nil + creatorId > 0` 아이템을 터치하면 크리에이터 채널로 이동한다.
|
||||
- `LIVE_REPLAY + targetId != nil` 아이템을 터치하면 콘텐츠 상세 페이지로 이동한다.
|
||||
- `LIVE_REPLAY + targetId == nil` 아이템은 이동하지 않는다.
|
||||
- `AUDIO`, `COMMUNITY`, 알 수 없는 타입은 기존 동작을 유지한다.
|
||||
|
||||
- [x] **Task 21.4: LIVE_REPLAY 이동 요구사항 문서 정정**
|
||||
- Goal: 잘못 기록된 `LIVE_REPLAY` 라이브룸 이동 기준을 `AUDIO`와 동일한 콘텐츠 상세 이동 기준으로 정정한다.
|
||||
- 대상 파일:
|
||||
- 수정: `docs/20260602_메인_홈_추천_UI_API_연동/prd.md`
|
||||
- 수정: `docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md`
|
||||
- 작업 내용:
|
||||
- PRD의 상세 진입 규칙, 성공 기준, Open Questions, 검증 계획을 정정한다.
|
||||
- Phase 21 결과와 미완료 구현 Task에서 `LIVE_REPLAY`를 `onTapContent(targetId)`에 연결하도록 정정한다.
|
||||
- `LIVE_REPLAY`의 표시 문구는 기존과 같이 `I18n.HomeRecommendation.activityLive`를 유지하도록 명시한다.
|
||||
- 기존 검증 기록은 삭제하지 않고 후속 정정 기록을 추가한다.
|
||||
- 완료 증거:
|
||||
- 활성 요구사항과 미완료 구현 Task에서 `LIVE_REPLAY`의 라이브룸 이동 표현이 없고 콘텐츠 상세 이동 규칙이 일치한다.
|
||||
- TDD 예외 사유:
|
||||
- production 동작을 변경하지 않는 문서 정정 Task다.
|
||||
- 검증 기준:
|
||||
- 실행 명령: `rg "LIVE_REPLAY.*(라이브룸|콘텐츠 상세)|onTapContent\\(targetId\\)" docs/20260602_메인_홈_추천_UI_API_연동/prd.md docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md`
|
||||
- 기대 결과: 활성 요구사항과 미완료 구현 Task에는 `LIVE_REPLAY`의 콘텐츠 상세 이동만 명시되고, 과거 오류는 정정 기록에서만 설명된다.
|
||||
|
||||
## 검증 기록
|
||||
|
||||
### 2026-07-30 Phase 21 최근 활동 LIVE 이동 fallback 구현 완료
|
||||
|
||||
- 목적: 최근 활동 크리에이터의 `LIVE` fallback과 `LIVE_REPLAY` 콘텐츠 상세 이동을 코드에 반영
|
||||
- 수행 내용:
|
||||
- `HomeActiveCreatorItem.creatorId`를 필수 `Int`로 추가
|
||||
- `RecommendedActivityType.liveReplay`를 추가하고 `LIVE_REPLAY` 디코딩을 `.live`와 분리
|
||||
- `LIVE`와 `LIVE_REPLAY`의 표시 문구는 모두 `I18n.HomeRecommendation.activityLive`를 유지
|
||||
- `HomeActiveCreatorTapDestination`과 `activeCreatorTapDestination`으로 최근 활동 탭 목적지를 한 곳에서 결정
|
||||
- `LIVE + targetId`는 라이브룸, `LIVE + targetId == nil + creatorId > 0`은 크리에이터 채널로 연결
|
||||
- `LIVE_REPLAY + targetId`는 콘텐츠 상세로 연결하고, `targetId == nil`이면 이동하지 않도록 처리
|
||||
- `AUDIO`, `COMMUNITY`, 알 수 없는 타입의 기존 분기는 유지
|
||||
- 검증:
|
||||
- 임시 `swiftc` RED 체크 실행, 기존 코드에서 `HomeActiveCreatorItem.creatorId`, `RecommendedActivityType.liveReplay`, `activeCreatorTapDestination` 부재로 실패 확인
|
||||
- 임시 `swiftc` GREEN 체크 실행, `creatorId` 디코딩, `LIVE_REPLAY` case 분리, `LIVE`/`LIVE_REPLAY`/`AUDIO`/`COMMUNITY`/unknown 라우팅 precondition 통과 확인
|
||||
- `rg -n "creatorId|case liveReplay|LIVE_REPLAY|HomeActiveCreatorItem\(|activeCreatorTapDestination|onTapCreator|creatorId > 0|onTapLive|onTapContent|onTapCommunityPost" "SodaLive/Sources/V2/Main/Home/Recommendation" "SodaLive/Sources/V2/Main/MainView.swift"` 실행, Phase 21 구현 근거 확인
|
||||
- `git diff --check` 실행, 출력 없이 성공 확인
|
||||
- `plutil -lint "SodaLive.xcodeproj/project.pbxproj"` 실행, `OK` 확인
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build` 실행, `BUILD SUCCEEDED` 확인
|
||||
- `lsp_diagnostics`는 개별 Swift 파일 단독 분석에서 기존 프로젝트 타입(`I18n`, `EventItem`, `DateParser`)을 찾지 못해 false positive를 반환했으므로, 실제 컴파일 검증은 `xcodebuild` 결과를 기준으로 판단
|
||||
|
||||
### 2026-07-30 Phase 21 LIVE_REPLAY 이동 요구사항 정정
|
||||
|
||||
- 정정 대상:
|
||||
- Task 21.1과 Task 21.3에 기록했던 `LIVE_REPLAY`의 기존 라이브룸 이동 기준
|
||||
- 이전 `2026-07-30 Phase 21 최근 활동 LIVE 이동 fallback 요구사항 문서화` 기록의 `LIVE_REPLAY` 기존 동작 유지 표현
|
||||
- 정정 내용:
|
||||
- `LIVE_REPLAY`는 라이브룸으로 이동하지 않는다.
|
||||
- `AUDIO`와 동일하게 `targetId`를 콘텐츠 ID로 사용해 콘텐츠 상세 페이지로 이동한다.
|
||||
- `targetId == nil`이면 이동하지 않으며 `creatorId` fallback은 적용하지 않는다.
|
||||
- 표시 문구는 기존과 같이 `I18n.HomeRecommendation.activityLive`를 사용해 `라이브`로 표시한다.
|
||||
- 반영 범위:
|
||||
- PRD 상세 진입 규칙, 성공 기준, Open Questions, 검증 계획
|
||||
- Phase 21 결과와 Task 21.1, Task 21.3
|
||||
- 문서 정정 추적용 Task 21.4
|
||||
- 검증:
|
||||
- `rg "LIVE_REPLAY.*(라이브룸|콘텐츠 상세|activityLive|라이브)|onTapContent\\(targetId\\)" docs/20260602_메인_홈_추천_UI_API_연동/prd.md docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md` 실행, 활성 요구사항과 미완료 구현 Task에서 `LIVE_REPLAY`의 콘텐츠 상세 이동 및 기존 `라이브` 표시 유지 기준 확인
|
||||
- `git diff --check -- docs/20260602_메인_홈_추천_UI_API_연동/prd.md docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md` 실행, 출력 없이 성공 확인
|
||||
|
||||
### 2026-07-30 Phase 21 최근 활동 LIVE 이동 fallback 요구사항 문서화
|
||||
|
||||
- 목적: `HomeActiveCreatorItem.creatorId` 추가와 최근 활동 `LIVE`의 `targetId` 유무별 이동 규칙을 구현 전에 확정
|
||||
- 수행 내용:
|
||||
- PRD 응답 스키마에 non-null `creatorId: Long` 추가
|
||||
- 서버 원본 `LIVE`에서 `targetId`가 있으면 라이브룸, 없으면 `creatorId` 기반 크리에이터 채널로 이동하도록 명시
|
||||
- 서버가 유효한 양수를 보장하더라도 앱에서 `creatorId > 0`을 검사하도록 명시
|
||||
- `LIVE`와 `LIVE_REPLAY`를 앱 enum case에서 구분하고 `LIVE_REPLAY`에는 새 fallback을 적용하지 않도록 명시
|
||||
- `AUDIO`, `COMMUNITY`, 알 수 없는 활동 타입의 기존 동작 유지 기준 추가
|
||||
- Phase 21에 문서, 모델/enum, 이동 연결/검증 Task를 추가하고 구현 Task는 미완료로 유지
|
||||
- 검증:
|
||||
- `rg "creatorId: Long|activityType == LIVE|targetId == null|creatorId > 0|LIVE_REPLAY" docs/20260602_메인_홈_추천_UI_API_연동/prd.md docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md` 실행, 응답 필드, `LIVE` 분기, 양수 검사, `LIVE_REPLAY` 제외 규칙이 두 문서에 반영됨 확인
|
||||
- `git diff --check -- docs/20260602_메인_홈_추천_UI_API_연동/prd.md docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md` 실행, 출력 없이 성공 확인
|
||||
|
||||
### 2026-07-10 Phase 20 추천 커뮤니티 게시물 상세 진입 보정 완료
|
||||
|
||||
- 목적: 메인 홈 추천 탭의 최근 활동 `COMMUNITY`와 인기 커뮤니티 게시물 탭 액션을 커뮤니티 게시물 상세 페이지로 연결
|
||||
|
||||
@@ -76,6 +76,7 @@ data class HomeLiveItem(
|
||||
)
|
||||
|
||||
data class HomeActiveCreatorItem(
|
||||
val creatorId: Long,
|
||||
val creatorNickname: String,
|
||||
val creatorProfileImage: String,
|
||||
val activityType: String,
|
||||
@@ -159,6 +160,7 @@ enum class RecommendedActivityType(val code: String) {
|
||||
- `AUDIO` -> `I18n.HomeRecommendation.activityAudio`
|
||||
- `COMMUNITY` -> `I18n.HomeRecommendation.activityCommunity`
|
||||
- 알 수 없는 값은 서버 코드를 그대로 노출하지 않고 보조 문구를 숨긴다.
|
||||
- `LIVE`와 `LIVE_REPLAY`는 표시 문구만 동일하게 사용하며, 탭 이동 분기를 구분할 수 있도록 서로 다른 앱 enum case로 변환한다.
|
||||
|
||||
다국어 기본 문구:
|
||||
- ko: `라이브`, `오디오`, `커뮤니티`
|
||||
@@ -179,6 +181,11 @@ enum class RecommendedActivityType(val code: String) {
|
||||
- 민감 콘텐츠 보기 설정이 꺼져 있으면 `AppState.shared.setPendingContentSettingsGuideMessage(I18n.Settings.adultContentEnableGuide)`로 안내 문구를 예약하고 `AppState.shared.setAppStep(step: .contentViewSettings)`로 이동한다.
|
||||
- 위 조건을 통과한 경우에만 `liveDetail`, `creatorDetail`, `contentDetail`, `characterDetail` 등 실제 상세 이동을 실행한다.
|
||||
- 추천 탭 현재 라이브 아이템은 `roomId`가 항상 존재하는 값으로 취급하고, 아이템 탭 시 상세 화면을 거치지 않고 기존 `LiveViewModel.enterLiveRoom(roomId:)` 흐름을 호출해 방 상세 조회, 입장 전 결제 확인, 비밀방 비밀번호 dialog, `LiveRoomViewV2` 입장을 재사용한다.
|
||||
- 최근 활동 크리에이터에서 서버 원본 `activityType == LIVE`이고 `targetId != null`이면 `targetId`를 라이브룸 `roomId`로 사용해 기존 라이브룸 입장 흐름을 실행한다.
|
||||
- 최근 활동 크리에이터에서 서버 원본 `activityType == LIVE`이고 `targetId == null`이면 `creatorId`를 사용해 크리에이터 채널로 이동한다.
|
||||
- 최근 활동 크리에이터의 `creatorId`는 서버에서 항상 유효한 양수로 제공하지만, 앱에서도 `creatorId > 0`을 확인한 뒤에만 크리에이터 채널 이동을 실행한다. 검사를 통과하지 못하면 이동하지 않는다.
|
||||
- `LIVE_REPLAY`는 `AUDIO`와 동일하게 `targetId`를 콘텐츠 ID로 사용해 콘텐츠 상세 페이지로 이동한다. `targetId`가 없으면 이동하지 않으며, `LIVE`의 `creatorId` fallback은 적용하지 않는다.
|
||||
- 최근 활동 크리에이터의 `AUDIO`, `COMMUNITY`, 알 수 없는 활동 타입은 기존 탭 동작을 유지한다.
|
||||
- 최근 활동 크리에이터에서 `activityType == COMMUNITY`인 아이템은 `targetId`를 커뮤니티 게시물 `postId`로 취급하고, 탭 시 커뮤니티 게시물 상세 페이지로 이동한다.
|
||||
- 인기 커뮤니티 섹션의 커뮤니티 게시물은 `postId` 기준으로 커뮤니티 게시물 상세 페이지로 이동한다. 좋아요, 구매, 오디오 재생 액션은 기존 개별 액션을 유지한다.
|
||||
|
||||
@@ -302,6 +309,9 @@ MainHomeView
|
||||
- `FeedCommunityView`에 `구매완료` 버튼이 표시되지 않는다.
|
||||
- 사업자 정보는 마지막 섹션에서 화면 width를 채우고, 기본 3줄 말줄임표, 더보기, 전체 표시, 접기 전환이 동작한다.
|
||||
- 상세 진입 탭 액션은 기존 홈과 같은 로그인, 한국 사용자 본인인증, 민감 콘텐츠 보기 설정 guard를 통과한 뒤에만 실행된다.
|
||||
- 최근 활동 크리에이터의 `LIVE` 활동은 `targetId`가 있으면 라이브룸으로 이동하고, `targetId`가 없고 `creatorId > 0`이면 크리에이터 채널로 이동한다.
|
||||
- 최근 활동 크리에이터의 `LIVE_REPLAY` 표시 문구는 기존과 같이 `라이브` 계열 I18n 문구를 유지하되, 탭 시에는 `AUDIO`와 동일하게 `targetId` 기반 콘텐츠 상세 페이지로 이동하며 `creatorId` fallback은 적용되지 않는다.
|
||||
- 최근 활동 크리에이터의 `AUDIO`, `COMMUNITY`, 알 수 없는 활동 타입의 기존 동작에 회귀가 없다.
|
||||
- 최근 활동 크리에이터의 `COMMUNITY` 활동과 인기 커뮤니티 섹션의 게시물은 커뮤니티 게시물 상세 페이지로 이동한다.
|
||||
- `MainHomeView`는 추천/랭킹/팔로잉 탭 shell 역할만 하고, 추천 탭 섹션 조립은 `MainHomeRecommendationView`에 분리되어 있다.
|
||||
- 반복 UI는 기존 widget 또는 공용 컴포넌트를 재사용하고 불필요하게 중복 구현하지 않는다.
|
||||
@@ -312,10 +322,10 @@ MainHomeView
|
||||
- 각 섹션별 최대 표시 개수와 가로/세로 스크롤 정책이 Figma 기준 그대로인지, 서버 응답 전체를 모두 표시해야 하는지 확인이 필요하다.
|
||||
- `HomeLiveItem`에 민감/성인 라이브 여부를 판단할 `isAdult` 또는 동등한 필드가 추가되는지, 아니면 서버에서 추천 라이브를 사전 필터링하는지 확인이 필요하다.
|
||||
- 커뮤니티 `audioUrl`을 추천 탭 카드에서 표시/재생해야 하는지 확인이 필요하다.
|
||||
- 각 카드 터치 시 상세 이동 대상이 모두 정의되어 있는지 확인이 필요하다. 단, 최근 활동 `COMMUNITY`와 인기 커뮤니티 게시물은 커뮤니티 게시물 상세 페이지로 확정한다.
|
||||
- 각 카드 터치 시 상세 이동 대상이 모두 정의되어 있는지 확인이 필요하다. 단, 최근 활동 `LIVE`, `LIVE_REPLAY`, `COMMUNITY`, 인기 커뮤니티 게시물의 이동 규칙은 확정한다.
|
||||
|
||||
## 12. Verification Plan
|
||||
- 문서 검증: API URL, 응답 모델, 제외 섹션, FeedCommunityView, 사업자 정보 요구가 PRD와 계획 문서에 반영되었는지 확인한다.
|
||||
- 정적 검증: 신규 추천 API가 기존 `HomeApi`에 추가되지 않았고, Figma URL이 앱 코드에 직접 포함되지 않았는지 확인한다.
|
||||
- 빌드 검증: `docs/agent-guides/build-test-verification.md` 기준으로 가능한 iOS 빌드 또는 최소 정적 검증을 실행한다.
|
||||
- 기능 검증: 추천 API 성공/실패, 빈 섹션, 활동 타입 I18n, 상세 진입 guard, 커뮤니티 카드 상태, 사업자 정보 더보기/접기를 확인한다.
|
||||
- 기능 검증: 추천 API 성공/실패, 빈 섹션, 활동 타입 I18n, 상세 진입 guard, 최근 활동 `LIVE`의 `targetId` 유무별 이동, `creatorId` 양수 검사, `LIVE_REPLAY`의 콘텐츠 상세 이동, 다른 활동 타입의 회귀 여부, 커뮤니티 카드 상태, 사업자 정보 더보기/접기를 확인한다.
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
# Phase 21 최근 활동 LIVE 이동 fallback 보정 리뷰
|
||||
|
||||
## 1. 리뷰 정보
|
||||
|
||||
| 항목 | 내용 |
|
||||
|---|---|
|
||||
| 리뷰 대상 | Phase 21 / Task 21.1~21.4 |
|
||||
| 기준 commit 또는 working tree | `0232cd43356dd1988dea6cf03563716542cd491c` 기준 working tree의 Phase 21 변경 6개 파일 |
|
||||
| 리뷰 일자 | 2026-07-30 |
|
||||
| 리뷰어 | Codex |
|
||||
| 기준 문서 | `docs/20260602_메인_홈_추천_UI_API_연동/prd.md`, `docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md` |
|
||||
| 리뷰 상태 | 판정 완료 |
|
||||
|
||||
## 2. 리뷰 목적과 범위
|
||||
|
||||
### 목적
|
||||
|
||||
- Phase 21의 완료 체크와 실제 모델, 활동 타입 변환, 탭 목적지, callback 연결 및 검증 기록이 일치하는지 확인한다.
|
||||
- `LIVE`, `LIVE_REPLAY`, `AUDIO`, `COMMUNITY`, 알 수 없는 활동 타입의 이동 규칙과 기존 상세 진입 guard 재사용 여부를 확인한다.
|
||||
|
||||
### 포함 범위
|
||||
|
||||
- 코드:
|
||||
- `SodaLive/Sources/V2/Main/Home/Recommendation/Models/MainHomeRecommendationResponse.swift`
|
||||
- `SodaLive/Sources/V2/Main/Home/Recommendation/Models/RecommendedActivityType.swift`
|
||||
- `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeActiveCreatorSection.swift`
|
||||
- `SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift`
|
||||
- `SodaLive/Sources/V2/Main/Home/MainHomeView.swift`
|
||||
- `SodaLive/Sources/V2/Main/MainView.swift`
|
||||
- 테스트:
|
||||
- 변경된 실제 모델 소스를 `swiftc`로 컴파일한 임시 디코딩·라우팅 회귀 체크
|
||||
- 저장소에 앱 테스트 번들 타깃이 없어 별도 unit test는 실행하지 않음
|
||||
- 문서:
|
||||
- PRD의 응답 스키마, 진입 규칙, 성공 기준, 검증 계획
|
||||
- `plan-task.md`의 Phase 21 Task와 검증 기록
|
||||
- 정적/빌드 검증:
|
||||
- 공백 오류, 프로젝트 파일 유효성, `SodaLive-dev` Debug 빌드
|
||||
|
||||
### 제외 범위
|
||||
|
||||
- Phase 1~20 구현의 재검토
|
||||
- 실제 서버 응답 계약 자체의 재검증
|
||||
- 로그인·본인인증·민감 콘텐츠 설정 상태를 포함한 실기기/시뮬레이터 수동 탭 검증
|
||||
- Phase 21과 무관한 기존 코드와 빌드 경고
|
||||
|
||||
## 3. 판정 기준
|
||||
|
||||
### 심각도
|
||||
|
||||
| 심각도 | 기준 |
|
||||
|---|---|
|
||||
| Blocker | 보안·데이터 손실 위험, 핵심 흐름 불능, 완료 판정을 무효화하는 문제 |
|
||||
| High | 확정 요구사항·API Contract 위반 또는 주요 회귀 |
|
||||
| Medium | 제한된 조건에서 발생하는 기능·접근성·복구 문제 |
|
||||
| Low | 유지보수성, 문서 정합성 또는 비핵심 UX 문제 |
|
||||
|
||||
### 상태
|
||||
|
||||
| 상태 | 의미 | 후속 처리 |
|
||||
|---|---|---|
|
||||
| 후보 | 근거를 발견했지만 아직 재현·판정하지 않음 | 검증 후 상태 변경 |
|
||||
| 확정 | 코드·test·문서 근거로 문제가 확인됨 | `plan-task.md` 회귀 수정 Task 후보 |
|
||||
| 오탐 | 요구사항이나 실행 결과상 문제가 아님 | 근거를 남기고 종료 |
|
||||
| 보류 | 외부 계약·환경·제품 결정이 필요함 | 담당 주체와 재개 조건 기록 |
|
||||
| 수정 완료 | 수정과 관련 검증이 완료됨 | 실행 명령과 결과 연결 |
|
||||
|
||||
## 4. 검토한 근거
|
||||
|
||||
### 문서와 코드
|
||||
|
||||
- 요구사항:
|
||||
- `prd.md:78-85`의 `HomeActiveCreatorItem.creatorId`
|
||||
- `prd.md:184-189`의 최근 활동 `LIVE`, `LIVE_REPLAY`, 기존 활동 타입 이동 규칙
|
||||
- `prd.md:312-314`의 Phase 21 성공 기준
|
||||
- 계획:
|
||||
- `plan-task.md:540-629`의 Task 21.1~21.4
|
||||
- `plan-task.md:633-670`의 Phase 21 구현 및 정정 검증 기록
|
||||
- 코드:
|
||||
- `MainHomeRecommendationResponse.swift:29-61`의 필수 `creatorId`와 탭 목적지 분기
|
||||
- `RecommendedActivityType.swift:3-38`의 `LIVE`/`LIVE_REPLAY` 분리 및 동일 I18n 문구
|
||||
- `MainHomeActiveCreatorSection.swift:3-55`의 callback 전달
|
||||
- `MainHomeRecommendationView.swift:38-44`의 `onTapCreator` 연결
|
||||
- `MainView.swift:474-509`의 양수 검사, 상세 진입 guard 및 최종 이동
|
||||
- 테스트:
|
||||
- 실제 변경 모델 소스와 임시 stub/check 소스를 함께 컴파일해 9개 디코딩·라우팅 시나리오와 `LIVE`/`LIVE_REPLAY` 표시 문구 일치를 확인했다.
|
||||
- 임시 소스와 실행 바이너리는 검증 직후 `/private/tmp`에서 삭제했다.
|
||||
|
||||
### 실행 환경
|
||||
|
||||
```text
|
||||
OS: macOS 26.0 (25A354)
|
||||
Xcode: 26.0 (17A324)
|
||||
Swift: 6.2
|
||||
빌드 대상: Any iOS Device / SodaLive-dev / Debug
|
||||
환경 변수: 별도 설정 없음, 인증 토큰 및 민감정보 미사용
|
||||
```
|
||||
|
||||
### 실행한 검증
|
||||
|
||||
| 명령 또는 수동 검증 | 결과 | 핵심 증거 |
|
||||
|---|---|---|
|
||||
| `git diff --check` | 성공 | exit code 0, 출력 없음 |
|
||||
| `plutil -lint SodaLive.xcodeproj/project.pbxproj` | 성공 | `OK` |
|
||||
| `xcrun swiftc /private/tmp/sodalive_phase21_review_stubs.swift SodaLive/Sources/V2/Main/Home/Recommendation/Models/RecommendedActivityType.swift SodaLive/Sources/V2/Main/Home/Recommendation/Models/MainHomeRecommendationResponse.swift /private/tmp/sodalive_phase21_review_check.swift -o /private/tmp/sodalive_phase21_review_check` | 성공 | 실제 변경 모델 소스 컴파일 성공 |
|
||||
| `/private/tmp/sodalive_phase21_review_check` | 성공 | `Phase 21 routing checks passed: 9` |
|
||||
| `xcodebuild -workspace SodaLive.xcworkspace -scheme SodaLive-dev -configuration Debug build` (sandbox) | 실패 | exit code 66, CoreSimulator·캐시 접근 제한으로 workspace를 열지 못한 환경 실패 |
|
||||
| `xcodebuild -workspace SodaLive.xcworkspace -scheme SodaLive-dev -configuration Debug build` (sandbox 외 재실행) | 성공 | exit code 0, `BUILD SUCCEEDED` |
|
||||
| 실기기/시뮬레이터 탭 검증 | 불가 | 실제 서버 응답과 인증 상태를 준비하지 않아 제외 범위로 유지 |
|
||||
|
||||
## 5. 발견 사항 요약
|
||||
|
||||
**확정 발견 사항 없음.**
|
||||
|
||||
- 문서의 `LIVE`, `LIVE_REPLAY`, `AUDIO`, `COMMUNITY`, unknown 분기와 실제 코드가 일치한다.
|
||||
- `LIVE + targetId == nil`의 `creatorId > 0` 검사와 최종 callback의 양수 guard가 확인된다.
|
||||
- 기존 `performRecommendationDetailAction`과 라이브룸 입장 흐름을 재사용한다.
|
||||
- working tree 기준 정적 검증, 임시 회귀 체크 및 `SodaLive-dev` Debug 빌드가 성공했다.
|
||||
|
||||
## 6. 발견 사항 상세
|
||||
|
||||
확정 발견 사항 없음.
|
||||
|
||||
실기기/시뮬레이터 수동 탭 검증은 제외 범위이며, 코드·문서 불일치나 자동 검증 실패로 판정하지 않았다.
|
||||
|
||||
## 7. 확정 항목의 plan·goal 전환
|
||||
|
||||
전환 항목 없음.
|
||||
|
||||
확정 발견 사항이 없으므로 `plan-task.md` Phase 21에 신규 회귀 수정 Task를 추가하지 않는다.
|
||||
|
||||
## 8. 리뷰 종료 판정
|
||||
|
||||
| 판정 항목 | 결과 | 근거 |
|
||||
|---|---|---|
|
||||
| 리뷰 범위 전체 확인 | 충족 | Phase 21 문서, 변경 코드, callback 소비 지점, 정적 검증 및 빌드 확인 |
|
||||
| 후보 항목 판정 완료 | 충족 | 남은 후보 없음 |
|
||||
| 확정 항목 plan 반영 | 해당 없음 | 확정 발견 사항 없음 |
|
||||
| 보류 항목의 담당·재개 조건 기록 | 해당 없음 | 보류 항목 없음 |
|
||||
| 검증 명령과 결과 기록 | 충족 | 4절에 실제 명령, 성공·실패 및 환경 사유 기록 |
|
||||
|
||||
**최종 결론:** 확정 발견 사항 없음
|
||||
|
||||
**남은 항목:** 자동 리뷰 범위 내 없음. 실기기/시뮬레이터 수동 탭 검증은 제외 범위다.
|
||||
|
||||
## 9. 수정 후 검증 기록
|
||||
|
||||
해당 없음. 확정 발견 사항과 후속 수정이 없다.
|
||||
Reference in New Issue
Block a user