docs(creator): 커뮤니티 후속 작업 기록을 갱신한다

This commit is contained in:
2026-08-11 00:11:11 +09:00
parent 8b8b384b29
commit 75480e7a71
4 changed files with 1172 additions and 2 deletions

View File

@@ -0,0 +1,242 @@
# Phase 15 커뮤니티 구매·상세 메뉴 리뷰 보고서
## 1. 리뷰 정보
| 항목 | 내용 |
|---|---|
| 리뷰 대상 | Phase 15 / `P15-T1`~`P15-T5`, `P15-GATE` |
| 기준 commit 또는 working tree | `02cd583f` 기반 미커밋 working tree |
| 리뷰 일자 | 2026-08-10 |
| 리뷰어 | Codex, 독립 재검토 `phase15_review` |
| 기준 문서 | `prd.md` F0-20260810, `plan-task.md` Phase 15 |
| 리뷰 상태 | 수정 검증 완료 |
## 2. 리뷰 목적과 범위
### 목적
- Phase 15의 미체크 항목이 단순 체크 누락인지 미구현인지 확인한다.
- PRD의 홈 Response, 유료 미구매 표시, 상세 메뉴 권한, 상위 새로고침 요구사항을 코드·테스트·Gate와 대조한다.
### 포함 범위
- 코드: Phase 15 파일 구조에 나열된 홈, 커뮤니티 탭, 상세, 상위 Activity, action 파일
- 테스트: Phase 15 focused local unit/source contract 테스트
- 문서: `prd.md` F0-20260810, `plan-task.md` Phase 15
- 수동 검증: 코드/diff 정적 검토
### 제외 범위
- `app/src/androidTest`, 기기·에뮬레이터 UI 조작, 스크린샷·시각 QA
- 서버 Response 실제 배포 여부와 외부 API 운영 상태
## 3. 판정 기준
| 심각도 | 기준 |
|---|---|
| Blocker | 보안·데이터 손실, 핵심 흐름 불능 |
| High | 확정 PRD/API 계약 위반 또는 주요 회귀 |
| Medium | 제한 조건의 기능·접근성·복구 문제 |
| Low | 유지보수성, 문서 정합성, style Gate 문제 |
## 4. 검토한 근거
### 문서와 코드
- 요구사항: PRD `Home Response Contract`, `Home Community Requirements`, `Community Tab Requirements`, `Detail Purchase and Badge Requirements`, `Detail More Menu Requirements`, `Change Propagation Requirements`
- 계획: `P15-T1`~`P15-T5`, `P15-GATE`
- 코드/테스트: Phase 15 파일 구조와 각 Task에 명시된 파일
### 실행 환경
```text
OS: Darwin 25.0.0 x86_64
Java: OpenJDK 17.0.15
Android/Gradle: 저장소 wrapper 및 debug variant
민감 환경 값: 기록하지 않음
```
### 실행한 검증
| 명령 | 결과 | 핵심 증거 |
|---|---|---|
| 홈 focused unit test | 성공 | `BUILD SUCCESSFUL` |
| 커뮤니/action focused unit test | 성공 | `BUILD SUCCESSFUL` |
| `CreatorChannelActivitySourceTest` | 성공 | `BUILD SUCCESSFUL` |
| `./gradlew :app:mergeDebugResources` | 성공 | `BUILD SUCCESSFUL` |
| `./gradlew :app:compileDebugKotlin` | 성공 | `BUILD SUCCESSFUL` |
| `./gradlew :app:ktlintCheck` | 실패 | `CreatorChannelActivity.kt:29:1 Unused import` 1건 |
| `git diff --check` | 성공 | 출력 없음 |
| 수정 후 전체 focused test | 성공 | `BUILD SUCCESSFUL` |
| 수정 후 resource/compile/ktlint Gate | 성공 | `BUILD SUCCESSFUL` |
| 수정 후 `git diff --check`, `git diff HEAD --check` | 성공 | 출력 없음 |
## 5. 발견 사항 요약
| ID | 심각도 | 상태 | 제목 | 소유 Task | 후속 goal |
|---|---|---|---|---|---|
| `REV-P15-001` | Low | 수정 완료 | 목록 메뉴 제거 후 미사용 import가 style Gate를 막음 | `P15-R1` | 미사용 import 1줄 제거 및 Gate 재검증 |
| `REV-P15-002` | High | 수정 완료 | 홈 reaction id가 작성자 row에 연결됨 | `P15-R2` | reaction id를 실제 하트·댓글 row로 이동 및 Gate 재검증 |
| `REV-P15-003` | High | 수정 완료 | 공유 FeedItem 잠금 정책이 다른 홈 화면 reaction을 숨김 | `P15-R3` | 크리에이터 채널 홈만 잠금 숨김 정책을 선택하고 공유 기본값 회귀 검증 |
| `REV-P15-004` | Low | 수정 완료 | 메인 홈 회귀 테스트 파일의 미사용 import가 style Gate를 막음 | `P15-R4` | 미사용 import 1줄 제거 및 Gate 재검증 |
## 6. 발견 사항 상세
### REV-P15-001 — 목록 메뉴 제거 후 미사용 import가 style Gate를 막음
- **심각도:** Low
- **상태:** 수정 완료
- **관련 요구사항:** `P15-T5` orphan 제거, `P15-GATE`
- **소유 Task:** `P15-R1`
**관찰 내용**
`CreatorChannelActivity`의 목록 고정/삭제 로직을 제거한 후 `SharedPreferenceManager` import가 남아 `ktlintCheck`가 실패했다.
**근거**
- 코드: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt:29`
- 검증: `./gradlew :app:ktlintCheck` 결과 `Unused import (no-unused-imports)`
- 문서: `plan-task.md` `P15-T5`, `P15-GATE`
**영향**
기능 동작에는 영향이 없으나 Phase 15 style Gate를 통과할 수 없다.
**권장 조치**
`SharedPreferenceManager` import 1줄만 제거하고 `ktlintCheck`와 Phase 15 Gate를 재실행한다.
**판정 기록**
- 2026-08-10 — 기능 테스트·resource merge·compile은 통과했고 ktlint 정확한 1건으로 확정했다.
- 2026-08-10 — `SharedPreferenceManager` import 1줄 제거 후 최종 `ktlintCheck`와 Phase 15 Gate가 PASS했다.
### REV-P15-002 — 홈 reaction id가 작성자 row에 연결됨
- **심각도:** High
- **상태:** 수정 완료
- **관련 요구사항:** PRD `Home Community Requirements`, `P15-T2`
- **소유 Task:** `P15-R2`
**관찰 내용**
`FeedCommunityView.bind()``ll_feed_community_reaction``item.showReaction`을 적용하지만, XML의 해당 id가 프로필·닉네임·작성 시간 row에 붙어 있다. 실제 하트·댓글 row에는 id가 없다.
**근거**
- XML: `view_feed_community.xml:36-41``ll_feed_community_reaction` 아래에 `iv_feed_community_profile`이 있음
- XML: `view_feed_community.xml:154-195`의 실제 reaction row에 id가 없음
- 코드: `FeedCommunityView.kt:51`, `FeedCommunityView.kt:81`
**재현 또는 검증 절차**
1. `price > 0 && existOrdered == false`인 홈 item의 `showReaction == false`를 확인한다.
2. `FeedCommunityView.bind()``ll_feed_community_reaction.isVisible = false`를 적용한다.
3. XML tree에서 해당 id가 작성자 row를 가리키므로 작성자 row가 숨겨진다.
4. 실제 reaction row는 자신의 visibility binding을 받지 않아 하트·댓글 UI가 남는다.
**영향**
유료 미구매 홈 item이 PRD와 반대로 작성자 영역을 숨기고 reaction UI를 노출한다.
**권장 조치**
`ll_feed_community_reaction` id를 작성자 row에서 실제 하트·댓글 row로 이동한다.
**판정 기록**
- 2026-08-10 — XML tree와 binding 대상을 대조해 PRD 2번을 재현하는 실제 결함으로 확정했다.
- 2026-08-10 — id를 실제 하트·댓글 reaction row로 이동하고 focused/resource/compile 및 최종 Gate PASS를 확인했다.
### REV-P15-003 — 공유 FeedItem 잠금 정책이 다른 홈 화면 reaction을 숨김
- **심각도:** High
- **상태:** 수정 완료
- **관련 요구사항:** PRD `Edge Cases`, `Constraints & Dependencies`, `P15-T1`~`P15-T2`
- **소유 Task:** `P15-R3`
**관찰 내용**
`FeedItem.Community.showReaction = !isLocked`와 공유 `FeedCommunityView.bind()` 조합이 크리에이터 채널 홈뿐 아니라 메인 홈 인기 커뮤니티에도 적용된다. 메인 홈 mapper도 `price`, `existOrdered`를 전달하므로 유료 미구매 item의 기존 reaction 표시가 함께 사라진다.
**근거**
- 공유 정책: `FeedItem.kt``showReaction`, `showComment`
- 다른 호출부: `HomeRecommendationMappers.kt:84-103``price`, `existOrdered`를 전달
- 공유 View 사용: `HomePopularCommunityAdapter.kt:49``view.bind(item.item)`
- 문서: PRD `다른 화면에서 사용하는 FeedItem.Community는 신규 필드 기본값으로 기존 표시 동작을 유지한다.`
**영향**
요구 범위 밖인 메인 홈 인기 커뮤니티의 유료 미구매 item 표시가 변경되어 기존 화면 회귀가 발생한다.
**권장 조치**
공유 모델의 신규 정책 기본값은 기존 reaction 표시를 유지하고, 크리에이터 채널 홈 mapper만 잠금 reaction 숨김을 명시적으로 선택한다.
**판정 기록**
- 2026-08-10 — 전체 `FeedItem.Community` production 생성자와 공유 View 호출부를 추적해 실제 범위 확장 결함으로 확정했다.
- 2026-08-10 — 기본값은 기존 reaction 표시를 유지하고 크리에이터 채널 홈만 opt-in하도록 수정했다. 공유 모델·메인 홈 mapper 회귀 테스트와 최종 Gate가 PASS했다.
### REV-P15-004 — 메인 홈 회귀 테스트 파일의 미사용 import가 style Gate를 막음
- **심각도:** Low
- **상태:** 수정 완료
- **관련 요구사항:** `P15-R3`, `P15-GATE`
- **소유 Task:** `P15-R4`
**관찰 내용**
메인 홈 mapper 회귀 테스트 추가로 `HomeMainFragmentLayoutTest`가 다시 lint 대상이 되면서 사용처가 없는 `ColorDrawable` import 1건이 확인됐다.
**근거**
- 코드: `HomeMainFragmentLayoutTest.kt:6`
- 검증: `./gradlew :app:ktlintCheck` 결과 `Unused import`
**영향**
기능 동작에는 영향이 없으나 Phase 15 style Gate가 실패한다.
**권장 조치**
사용처가 없는 `ColorDrawable` import 1줄만 제거한다.
**판정 기록**
- 2026-08-10 — `rg`로 import 외 사용처가 없음을 확인해 정확한 style Gate 결함으로 확정했다.
- 2026-08-10 — `ColorDrawable` import 1줄 제거 후 `ktlintCheck`와 최종 focused test Gate가 PASS했다.
## 7. 확정 항목의 plan·goal 전환
- `plan-task.md` Phase 15에 `Task 15.R1` / goal `P15-R1`, `Task 15.R2` / goal `P15-R2`, `Task 15.R3` / goal `P15-R3`, `Task 15.R4` / goal `P15-R4`를 추가했다.
- 각 항목의 대상 파일, 최소 수정 범위, 회귀 검증, 완료 증거를 명시했다.
## 8. 리뷰 종료 판정
| 판정 항목 | 결과 | 근거 |
|---|---|---|
| 리뷰 범위 전체 확인 | 충족 | PRD/plan·production/test/diff 대조 |
| 후보 항목 판정 완료 | 충족 | `REV-P15-001`~`REV-P15-004` 확정 |
| 확정 항목 plan 반영 | 충족 | `P15-R1`~`P15-R4` |
| 보류 항목 기록 | 해당 없음 | 없음 |
| 검증 명령과 결과 기록 | 충족 | `P15-R1`~`P15-R4` 수정 후 최종 Gate PASS |
**최종 결론:** 수정 검증 완료
**남은 항목:** 없음. 기기·에뮬레이터 수동 UI 확인과 실제 서버 Response 배포 상태는 리뷰 범위 밖이다.
## 9. 수정 후 검증 기록
- `REV-P15-001`: `CreatorChannelActivity`의 미사용 `SharedPreferenceManager` import 1줄을 제거했다.
- `REV-P15-002`: `ll_feed_community_reaction` id를 프로필 row에서 실제 하트·댓글 row로 이동했다.
- `REV-P15-003`: `FeedItem.Community.hideReactionWhenLocked` 기본값을 `false`로 두고 크리에이터 채널 홈 mapper만 `true`를 전달했다. 메인 홈 인기 커뮤니티 잠금 item의 기존 reaction 표시 회귀 테스트를 추가했다.
- `REV-P15-004`: `HomeMainFragmentLayoutTest`의 미사용 `ColorDrawable` import 1줄을 제거했다.
- 최종 전체 focused test: `BUILD SUCCESSFUL`.
- 최종 `:app:mergeDebugResources`, `:app:compileDebugKotlin`, `:app:ktlintCheck`: `BUILD SUCCESSFUL`.
- 최종 `git diff --check`, `git diff HEAD --check`: 출력 없이 PASS.
- 정적 재검토: 구매 호출은 상세에만 존재하고, 홈·커뮤니티 item은 상세 이동만 수행하며, 상세 배지 제거·권한별 메뉴·홈+커뮤니티 refresh 계약이 유지됨을 확인했다.
- 독립 재검토: Critical/Minor 없음, Important 1건(`REV-P15-003`)을 수정 반영했다.
- 수정 후 독립 최종 재검토: `REV-P15-001`~`REV-P15-004` 반영을 확인했고 새 Critical/Important/Minor 이슈 없음으로 판정했다.

View File

@@ -0,0 +1,130 @@
# Phase 16 홈·커뮤니티 리스트 더보기 메뉴 리뷰 보고서
## 1. 리뷰 정보
| 항목 | 내용 |
|---|---|
| 리뷰 대상 | Phase 16 / `P16-T1`~`P16-T3`, `P16-GATE` |
| 기준 commit 또는 working tree | 현재 `main` 미커밋 working tree |
| 리뷰 일자 | 2026-08-10 |
| 리뷰어 | Sisyphus, 독립 목표·QA·품질·보안·맥락 검토 |
| 기준 문서 | `prd.md` F0-20260810, `plan-task.md` Phase 16 |
| 리뷰 상태 | 수정 검증 완료 |
## 2. 리뷰 목적과 범위
### 목적
- 홈과 커뮤니티 리스트형의 권한별 더보기 메뉴가 PRD와 일치하는지 확인한다.
- 완료 체크박스와 production/test/Gate/문서 기록이 일치하는지 확인한다.
### 포함 범위
- 코드: Phase 16 공용 권한 모델, 홈·리스트 callback, Activity 메뉴·mutation
- 테스트: Phase 16 focused local unit/source contract 테스트
- 문서: `prd.md` F0-20260810, `plan-task.md` Phase 16
- 수동 검증: 코드·XML·diff 정적 검토
### 제외 범위
- `app/src/androidTest`, 기기·에뮬레이터 조작, 스크린샷·시각 QA
- 실제 서버 Response와 API mutation, Git commit, 별도 worktree
## 3. 판정 기준
| 심각도 | 기준 |
|---|---|
| Blocker | 보안·데이터 손실, 핵심 흐름 불능 |
| High | 확정 PRD/API 계약 위반 또는 주요 회귀 |
| Medium | 제한 조건의 기능·접근성·복구 문제 |
| Low | 유지보수성, 문서 정합성, style Gate 문제 |
## 4. 검토한 근거
- 요구사항: PRD `Home and Community List More Menu Requirements`, `Change Propagation Requirements`
- 계획: `P16-T1`~`P16-T3`, `P16-GATE`
- 코드/테스트: Phase 16 Task에 명시된 파일과 focused test
- 실행 환경: macOS, 저장소 Gradle wrapper, debug variant
| 명령 또는 검증 | 결과 | 핵심 증거 |
|---|---|---|
| 홈·Feed·Activity focused test | 성공 | `BUILD SUCCESSFUL` |
| community/action focused test | 성공 | `BUILD SUCCESSFUL` |
| `./gradlew :app:mergeDebugResources` | 성공 | `BUILD SUCCESSFUL` |
| `./gradlew :app:compileDebugKotlin` | 성공 | `BUILD SUCCESSFUL` |
| `./gradlew :app:ktlintCheck` | 성공 | 기존 `disabled_rules` 경고만 존재 |
| `git diff --check`, `git diff HEAD --check` | 성공 | 출력 없음 |
## 5. 발견 사항 요약
| ID | 심각도 | 상태 | 제목 | 소유 Task | 후속 goal |
|---|---|---|---|---|---|
| `REV-P16-001` | Low | 수정 완료 | Phase 16 구현·Gate 완료 상태가 문서에 누락됨 | `P16-R1` | 완료 기록과 Verification Log 누적 |
## 6. 발견 사항 상세
### REV-P16-001 — Phase 16 구현·Gate 완료 상태가 문서에 누락됨
- **심각도:** Low
- **상태:** 수정 완료
- **관련 요구사항:** Phase 16 완료 조건, `P16-GATE`
- **소유 Task:** `P16-R1`
**관찰 내용**
모든 Phase 16 Task와 Gate가 통과했지만 계획 기록은 `구현 미시작`으로 남고 `Verification Log`에 Gate 결과가 없었다.
**근거**
- 문서: `plan-task.md` Phase 16 계획 기록과 `Verification Log`
- 검증: 최종 5개 리뷰 중 목표·코드 품질·맥락 검토가 동일 문서 불일치를 차단 이슈로 판정
**영향**
기능 동작에는 영향이 없지만 문서상 완료 조건을 충족하지 못해 Phase 완료 판정을 내릴 수 없다.
**권장 조치**
기존 계획 기록은 보존하고 구현·Gate 완료 기록과 `Verification Log`를 누적한 뒤 최종 리뷰를 재실행한다.
**판정 기록**
- 2026-08-10 — 코드와 Gate는 통과했으나 완료 문서가 실제 상태와 달라 확정했다.
- 2026-08-10 — 기존 계획 기록을 보존하고 Phase 16 구현·Gate 완료 기록과 `Verification Log`를 누적했다.
## 7. 확정 항목의 plan·goal 전환
- `plan-task.md``Task 16.R1` / goal `P16-R1`을 추가했다.
## 8. 리뷰 종료 판정
| 판정 항목 | 결과 | 근거 |
|---|---|---|
| 리뷰 범위 전체 확인 | 충족 | PRD/plan·production/test/diff 대조 |
| 후보 항목 판정 완료 | 충족 | `REV-P16-001` 확정 |
| 확정 항목 plan 반영 | 충족 | `P16-R1` |
| 보류 항목 기록 | 해당 없음 | 없음 |
| 검증 명령과 결과 기록 | 충족 | Phase 16 구현 기록과 `Verification Log` 누적 |
**최종 결론:** 수정 검증 완료
**남은 항목:** 없음. 실제 서버 권한 검증과 기기 UI 확인은 리뷰 범위 밖이다.
## 9. 수정 후 검증 기록
- 수정 전: Phase 16 계획 기록은 구현 미시작이며 `Verification Log`에 Gate 결과가 없었다.
- 1차 수정: 기존 계획 기록 뒤에 구현·Gate 완료 기록을 추가하고 `Verification Log`에 최종 자동 검증과 제외 범위를 누적했다.
- 최종 검증: `git diff --check`, `git diff HEAD --check`가 출력 없이 PASS했다.
- 목표·제약 검토: PASS, 차단 이슈 없음.
- 실행 QA: PASS, 허용된 P0 시나리오 11/11과 focused 128개, community/action 96개 PASS.
- 코드 품질 검토: PASS, 차단 이슈 없음.
- 보안 검토: PASS, 클라이언트 범위의 Critical/High 이슈 없음. 서버 소유권·rate limit 검증은 저장소 밖이라 확인하지 못했다.
- 맥락 검토: PASS, 추가 요구사항·호출자·Git 이력 충돌 없음.
### 2차 독립 재점검 — 2026-08-11
- 문서 체크: `plan-task.md`의 실제 Task 체크박스는 모두 완료 상태이며, 체크 누락 또는 미구현 항목이 없음을 production/test와 역대조했다.
- 요구사항 대조: 더보기 권한 truth table, 홈·리스트 root/more click 분리, grid 제외, 작성자 관리/일반 사용자 신고, 성공 관리 작업의 홈+커뮤니티 갱신, 신고·실패 no-refresh가 PRD와 일치했다.
- 공유 회귀 대조: `FeedItem.Community.hideReactionWhenLocked=false`, `showMore=false` 기본값과 크리에이터 채널 홈의 명시적 opt-in을 확인해 다른 공유 feed의 기존 표시를 보존함을 확인했다.
- 자동 검증: Phase 15·16 focused test, community/action focused test, 전체 `:app:testDebugUnitTest`, resource merge, Kotlin compile, ktlint, 두 diff check가 모두 PASS했다.
- 독립 리뷰: Critical/Important/Minor 이슈 없음, 승인 가능 판정. 새 확정 항목이 없어 회귀 수정 Task와 production/test 수정은 추가하지 않았다.