# 코드 리뷰 보고서: 커뮤니티 아이템 통일 ## 1. 리뷰 정보 | 항목 | 내용 | |---|---| | 리뷰 대상 | Phase 1~2 / `P1-T1~P2-T2` | | 기준 commit 또는 working tree | `89c070875cbeea8395c1e90cb9f47ff80df5d90f` 이후 미커밋 변경 | | 리뷰 일자 | 2026-08-10 | | 리뷰어 | Codex 자가 리뷰—프로젝트 보수적 실행 정책에 따라 subagent 미사용 | | 기준 문서 | `docs/20260810_크리에이터_채널_커뮤니티_아이템_통일/prd.md`, `plan-task.md` | | 리뷰 상태 | `REV-P3-003` 수정 완료·외부 통합 검증 대기 | ## 2. 리뷰 목적과 범위 ### 목적 - 홈·커뮤니티 탭의 아이템, 상세 진입, 더보기, 목록 구매 제거, 상세 구매 이동이 `CCCI-001~008`을 충족하는지 확인한다. - 코드·문서·검증 기록이 실제 working tree와 일치하는지 확인한다. ### 포함 범위 - 코드: `SodaLive/Sources/V2/CreatorChannel/Home/**`, `Community/**`, `CreatorChannelView.swift`의 변경분 - 검증: 정적 contract check, `git diff --check`, `SodaLive-dev` Debug Simulator build - 수동 검증: 부팅된 Simulator와 `EXT-001` 반영 여부 확인 ### 제외 범위 - 백엔드 구현·배포 - 구매 endpoint와 `CommunityPostPurchaseDialog` 내부 UI - `CommunityPostCard`의 메인 홈 사용처 ## 3. 판정 기준 | 심각도 | 기준 | |---|---| | Blocker | 핵심 상세·구매·관리 흐름이 불가능하거나 완료 판정을 무효화함 | | High | 확정 요구사항 또는 API 계약 위반 | | Medium | 제한된 조건의 기능·상태 동기화 문제 | | Low | 문서 정합성 또는 비핵심 유지보수 문제 | | 상태 | 의미 | |---|---| | 확정 | 코드·명령 근거로 문제 확인 | | 오탐 | 요구사항·실행 결과상 문제가 아님 | | 보류 | 외부 계약·환경 반영 후 판정 가능 | | 수정 완료 | 수정과 관련 검증 완료 | ## 4. 검토한 근거 ### 문서와 코드 - 요구사항: `CCCI-001~009`, `DEC-001~013`, `EXT-001` - 계획: `P1-T1~P2-T2`, `P2-R1`, `P1-GATE`, `P2-GATE` - 홈 변환·아이템: `CreatorChannelCommunitySection.swift:3` - 목록 잠금·상세 gesture: `CreatorChannelCommunityListItem.swift`, `CreatorChannelCommunityGridItem.swift` - 상세 구매: `CreatorChannelCommunityPostDetailView.swift:19`, `CreatorChannelCommunityPostDetailViewModel.swift:186` - 메뉴·route·동기화: `CreatorChannelView.swift:480`, `CreatorChannelView.swift:605` ### 실행 환경 ```text OS: macOS 26.0 (25A354) Xcode: 26.0 (17A324) Scheme: SodaLive-dev / Debug Destination: iPhone 17 Pro, iOS 26.0 Simulator Backend: EXT-001 반영 여부를 이 환경에서 확인하지 못함 ``` ### 실행한 검증 | 명령 또는 수동 검증 | 결과 | 핵심 증거 | |---|---|---| | 홈 모델·변환·route·menu `rg` contract check | 성공 | 필드·`communityPostItem`·`CreatorChannelCommunityListItem`·`postId` route match | | 목록 구매 심볼·잠금 배경 `rg` contract check | 성공 | 목록 구매 심볼과 잠금 `Color.gray400` 0건, 목록·상세 `Color.gray800` match | | 상세 구매 `rg` contract check | 성공 | `showPurchaseError` 0건, 상세 dialog·repository 호출 match | | reaction bar 조건부 삽입 `rg` contract check | 성공 | 무조건 삽입 0건, `if !isPaidLocked` 조건부 삽입 2건 | | `git diff --check` | 성공 | whitespace 오류 0건 | | `xcodebuild -quiet -workspace SodaLive.xcworkspace -scheme SodaLive-dev -configuration Debug -destination 'platform=iOS Simulator,id=E9FC7721-AA96-440F-8349-2DC4B85F40F5' -derivedDataPath /tmp/sodalive-community-baseline CODE_SIGNING_ALLOWED=NO ONLY_ACTIVE_ARCH=YES build` | 성공 | exit code 0 | | `xcrun simctl list devices` | 수동 검증 불가 | 모든 사용 가능한 Simulator가 `Shutdown`; 스킬 정책상 임의 부팅하지 않음 | ## 5. 발견 사항 요약 사용자 회귀 제보로 확정한 reaction bar 빈 공간 1건은 수정·빌드를 완료했다. | ID | 심각도 | 상태 | 제목 | 소유 Task | 후속 goal | |---|---|---|---|---|---| | `REV-P3-001` | High | 수정 완료 | 상세 잠금 버튼이 구매 대신 공통 오류만 표시하던 계획 누락 | `P1-T3` | 완료 | | `REV-P3-002` | High | 보류 | 홈 API 신규 필드와 런타임 동작의 통합 검증 필요 | `P3-GATE`, `EXT-001` | 외부 반영 후 재개 | | `REV-P3-003` | Medium | 수정 완료 | 하트·댓글이 숨겨져도 빈 reaction bar가 24pt 공간을 차지함 | `P2-R1` | 완료 | ## 6. 발견 사항 상세 ### REV-P3-001 — 상세 구매 연결 누락 - **심각도:** High - **상태:** 수정 완료 - **관련 요구사항:** `CCCI-004`, `CCCI-007` - **소유 Task:** `P1-T3` 기준선에서 상세 잠금 영역은 `showPurchaseError()`만 호출해 목록 구매 제거 후 실제 구매가 불가능했다. 코드 수정 전에 PRD `DEC-012`와 계획 `P1-T3`를 추가하고, 기존 `CommunityPostPurchaseDialog`·`CreatorCommunityRepository.purchaseCommunityPost(postId:)`를 상세 View·ViewModel로 이동했다. 정적 contract check와 Debug build가 통과했다. ### REV-P3-002 — 백엔드·Simulator 통합 검증 대기 - **심각도:** High - **상태:** 보류 - **관련 요구사항:** `CCCI-001~008`, `EXT-001` - **소유 Task:** `P3-GATE` 백엔드가 홈 API `notices`·`communities`에 `isCommentAvailable`·`isPinned`을 제공해야 하며, 실제 터치·메뉴·구매 흐름은 부팅된 Simulator에서 확인해야 한다. 현재 Simulator는 모두 종료 상태다. 백엔드 반영과 Simulator 부팅 후 홈·리스트·썸네일·상세 흐름을 재검증한다. ### REV-P3-003 — 표시할 reaction이 없을 때 빈 공간 유지 - **심각도:** Medium - **상태:** 수정 완료 - **관련 요구사항:** `CCCI-009` - **소유 Task:** `P2-R1` `CreatorChannelCommunityListItem`과 `CreatorChannelCommunityPostDetailContentView`는 유료 잠금 상태에서 하트·댓글 자식만 숨기고, body에는 `reactionBar`를 항상 삽입했다. 그 결과 빈 `HStack`의 `.frame(height: 24)`와 부모 `VStack` spacing이 홈·커뮤니티 리스트·상세에 남았다. 코드 수정 전에 `P2-R1`을 추가하고, 두 body에서 기존 `isPaidLocked`로 reaction bar 전체를 조건부 제외했다. focused contract check·`git diff --check`·Debug build가 통과했다. ## 7. 확정 항목의 plan·goal 전환 - `REV-P3-001`: 코드 수정 전에 `P1-T3`로 전환했고 수정·빌드를 완료했다. - `REV-P3-003`: 코드 수정 전에 `P2-R1`로 전환했고 수정·검증을 완료했다. - `REV-P3-002`: 외부 조건이므로 `P3-GATE` 완료를 보류한다. ## 8. 리뷰 종료 판정 | 판정 항목 | 결과 | 근거 | |---|---|---| | 리뷰 범위 전체 확인 | 충족 | 사용자 회귀 제보와 수정 결과를 추가 반영 | | 후보 항목 판정 완료 | 충족 | `REV-P3-001`·`REV-P3-003` 수정 완료, `REV-P3-002` 보류 | | 확정 항목 plan 반영 | 충족 | `P1-T3`, `P2-R1`, `DEC-012~013` | | 보류 항목의 담당·재개 조건 기록 | 충족 | `EXT-001`·부팅된 Simulator | | 검증 명령과 결과 기록 | 충족 | 정적 계약·Debug build exit 0 | **최종 결론:** iOS reaction bar 회귀 수정·빌드 완료, 외부 통합 검증 대기 **남은 항목:** 백엔드 `EXT-001` 반영 후 부팅된 Simulator에서 본체 상세 이동, 권한별 더보기, 목록 dialog 미노출, 상세 구매, `Color.gray800`을 확인한다. ## 9. 수정 후 검증 기록 ### 1차 수정 검증 — 2026-08-10 - 무엇을: `REV-P3-001`의 상세 구매 누락을 수정했다. - 왜: 목록 구매 제거 후에도 사용자가 상세에서 실제 구매할 수 있어야 한다. - 어떻게: - 상세 구매 contract check — 성공 - `SodaLive-dev` 단일 Simulator Debug build — exit code 0 - 남은 항목: `REV-P3-002` ### 2차 수정 검증 — 2026-08-10 - 무엇을: `REV-P3-003`의 빈 reaction bar 공간을 제거했다. - 왜: 하트·댓글을 모두 숨기는 유료 잠금 상태에서 고정 24pt 높이와 부모 spacing까지 없어져야 한다. - 어떻게: - 무조건 `reactionBar` 삽입 contract check — 0건 - `if !isPaidLocked` 조건부 삽입 contract check — 2건 - `git diff --check` — 성공 - `SodaLive-dev` 단일 Simulator Debug build — exit code 0 - 남은 항목: `REV-P3-002`와 Simulator 시각 검증