docs(deeplink): 커뮤니티 상세 이동 검증을 기록한다
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# 커뮤니티 딥링크 상세 이동 계획
|
||||
|
||||
| 항목 | 내용 |
|
||||
|---|---|
|
||||
| 상태 | 구현·자동 검증 완료, 실제 게시물 UI 확인 제한 |
|
||||
| 작성일 | 2026-10-13 |
|
||||
| 요구사항 | [prd.md](prd.md) CD-001~005 |
|
||||
| API 기준 | 기존 상세 화면/조회 API 유지 |
|
||||
| 현재 Phase | 1: postId 기반 상세 라우팅 |
|
||||
|
||||
## 목표와 범위
|
||||
정상 community postId는 상세 화면으로 전달하고 누락·무효 값은 이동하지 않는다. 공통 handler와 기존 테스트만 변경하며 UI·API·다른 딥링크·기존 댓글 화면 정리는 제외한다.
|
||||
|
||||
## Phase 1
|
||||
**결과:** 커뮤니티 딥링크가 사용자 ID와 무관하게 정확한 게시글 상세 route를 선택한다.
|
||||
**선행조건:** 사용자 인터뷰 완료, 기존 딥링크 검사 22 assertions 통과.
|
||||
|
||||
### Task 1.1 라우팅 변경과 회귀 검사
|
||||
**Goal P1-T1:** CD-001~005를 production handler 실행으로 검증한다.
|
||||
**Files:**
|
||||
- Modify: `SodaLive/Sources/App/AppDeepLinkHandler.swift`
|
||||
- Test: `work/tests/AppDeepLinkGiftDetailCheck.swift`
|
||||
- Run: `work/tests/check-app-deep-link-gift-detail.sh`
|
||||
- Read: `SodaLive/Sources/App/AppStep.swift`, `SodaLive/Sources/ContentView.swift`, `SodaLive/Sources/Splash/SplashView.swift`
|
||||
- Read: `SodaLive/Sources/V2/CreatorChannel/Community/Detail/CreatorChannelCommunityPostDetailView.swift`, `CreatorChannelCommunityPostDetailViewModel.swift` (같은 디렉터리)
|
||||
**Interfaces:** 기존 URL handler 입력 → 기존 `creatorChannelCommunityPostDetail(postId:)` route.
|
||||
**완료 증거:** RED/GREEN 실행 결과, 유효·무효·스플래시·인접 라우팅 검사.
|
||||
|
||||
- [x] **RED:** 정상 postId 상세 이동 및 누락·무효 값 이동 금지 회귀 검사 추가.
|
||||
- [x] **RED 확인:** `bash work/tests/check-app-deep-link-gift-detail.sh`로 의도한 assertion 실패 확인.
|
||||
- [x] **GREEN:** postId 단독 community action과 기존 상세 route 연결.
|
||||
- [x] **GREEN 확인:** 같은 명령으로 신규·기존 검사 통과.
|
||||
- [x] **REFACTOR:** 이번 변경이 만든 handler 내부 불필요 코드 제거 및 회귀 재검증.
|
||||
|
||||
### Task 1.2 검증과 리뷰
|
||||
**Goal P1-GATE:** 변경 범위의 검증 결과와 확인 불가능한 환경 조건을 구분한다.
|
||||
**Files:** 위 코드/테스트, 본 PRD/계획, `reviews/phase1-community-post-detail-links.md`.
|
||||
**TDD 예외 사유:** 검증·리뷰 기록만 작성하는 Task.
|
||||
|
||||
- [x] Swift 컴파일/구문 검사와 앱 빌드 실행.
|
||||
- [x] 실제 handler 입력/결과 및 iOS UI 검증 가능 여부 기록.
|
||||
- [x] 읽기 전용 리뷰 후 확정 문제가 있으면 신규 Task 등록, 없으면 발견 사항 없음 기록.
|
||||
- [x] 변경 범위와 검증 결과를 Progress에 누적.
|
||||
|
||||
## 시나리오와 검증
|
||||
| 시나리오 | 이진 성공 기준 | 실행 표면 |
|
||||
|---|---|---|
|
||||
| 정상 입력 | `voiceon://community?postId=12345`가 상세 12345로 이동, 목록/댓글 예약 없음 | production handler를 swiftc로 컴파일한 기존 하네스 |
|
||||
| 잘못된 입력 | 누락·빈 값·문자·0·음수·범위 초과 입력은 route/pending 변경 없음 | 동일 하네스, 사용자 ID 0/양수와 path/query 변형 |
|
||||
| 시작·진입점 | splash에서 저장 후 apply, notificationList에서도 상세 12345 | 동일 하네스 |
|
||||
| 인접 회귀 | 기존 선물/콘텐츠 라우팅 유지 | 기존 22 assertions |
|
||||
|
||||
명령: `bash work/tests/check-app-deep-link-gift-detail.sh`, `swiftc -frontend -parse SodaLive/Sources/App/AppDeepLinkHandler.swift work/tests/AppDeepLinkGiftDetailCheck.swift`, `xcodebuild -workspace SodaLive.xcworkspace -scheme SodaLive-dev -configuration Debug -destination 'generic/platform=iOS Simulator' CODE_SIGNING_ALLOWED=NO build`.
|
||||
iOS 수동 QA는 개발 앱에서 `xcrun simctl openurl booted 'voiceon-test://community?postId=12345'`로 진입해 상세 화면/게시물을 확인해야 한다. 운영 앱의 등록 scheme은 `voiceon`, 개발 앱은 `voiceon-test`다. 빌드/앱 실행이 차단되면 handler 하네스를 UI 검증으로 대체했다고 주장하지 않는다.
|
||||
|
||||
## 실행 순서와 중단 조건
|
||||
P1-T1 → P1-GATE. 검증과 리뷰가 끝나면 추가 정리 없이 종료한다. 현재 브랜치에서만 작업한다.
|
||||
|
||||
## Progress
|
||||
### 기준 확인 — 2026-10-13
|
||||
- 기존 딥링크 하네스: exit 0, 22 assertions 통과.
|
||||
- 상세 화면은 받은 postId로 기존 상세 API를 조회함을 확인.
|
||||
- Xcode 26.0, 실행 중 시뮬레이터 없음.
|
||||
- 인터뷰 결과: postId 누락·잘못된 값은 기존 목록 fallback 대신 이동 금지.
|
||||
|
||||
### P1-T1 RED — 2026-10-13
|
||||
- 기존 하네스에 정상 입력·사용자 ID 독립성·누락/무효·스플래시·알림 목록 검사를 추가했다.
|
||||
- `swiftc -frontend -parse work/tests/AppDeepLinkGiftDetailCheck.swift`: exit 0.
|
||||
- `bash work/tests/check-app-deep-link-gift-detail.sh`: `FAIL: community link accepted: voiceon://community?postId=12345, userId=0` assertion으로 실패. 기존 코드의 사용자 ID 의존성 때문에 발생한 의도된 RED다.
|
||||
|
||||
### P1-T1 GREEN — 2026-10-13
|
||||
- community action은 postId만 보유하며 기존 상세 route에 전달한다. 사용자 ID fallback과 기존 목록/댓글 예약 호출을 handler에서 제거했다.
|
||||
- 명시적인 community 경로의 누락·무효 postId는 다른 쿼리 route로 우회하지 않는다.
|
||||
- `bash work/tests/check-app-deep-link-gift-detail.sh`: exit 0, 279 assertions 통과.
|
||||
- `swiftc -frontend -parse SodaLive/Sources/App/AppDeepLinkHandler.swift work/tests/AppDeepLinkGiftDetailCheck.swift`: exit 0.
|
||||
- `git diff --check`: exit 0.
|
||||
- `for test_script in work/tests/check-*.sh; do bash "$test_script" || exit $?; done`: exit 0, 기존 스크립트 전체 통과.
|
||||
- 첫 앱 빌드는 도구의 120초 제한으로 중단되어 실행 제한을 600초로 늘려 재실행했다.
|
||||
|
||||
### P1-GATE — 2026-10-13
|
||||
- 앱 빌드: 위 `xcodebuild ... build` 재실행 결과 `BUILD SUCCEEDED`. 로그: `/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/community-deeplink-build-retry.log`.
|
||||
- 변경 handler의 빌드 경고/오류 없음. `lsp_diagnostics` 도구가 제공되지 않아 Swift 컴파일·구문 검사와 앱 빌드로 확인했다.
|
||||
- Xcode test: `xcodebuild -workspace SodaLive.xcworkspace -scheme SodaLive-dev -configuration Debug -destination 'platform=iOS Simulator,id=E9FC7721-AA96-440F-8349-2DC4B85F40F5' CODE_SIGNING_ALLOWED=NO test`는 `Scheme SodaLive-dev is not currently configured for the test action`으로 실행 불가. 전체 검증 성공은 `work/tests/check-*.sh` 범위이며 XCTest 통과를 의미하지 않는다.
|
||||
- 독립 읽기 전용 리뷰: 차단 결함 없음, handler 하네스 279 assertions 재확인. [리뷰](reviews/phase1-community-post-detail-links.md).
|
||||
- 실제 QA: 작업 전용 iPhone 17 Pro/iOS 26.0 시뮬레이터 `9794D878-ABFB-48F6-9759-17C9C2EB48F8` 생성·부팅 후 빌드한 개발 앱 설치. 부팅/설치 명령은 120초 제한에 걸렸으나 `simctl get_app_container`로 설치 완료를 별도 확인했다.
|
||||
- `xcrun simctl launch ... 9794D878-ABFB-48F6-9759-17C9C2EB48F8 kr.co.vividnext.sodalive.debug2`: PID 26019. `xcrun simctl openurl 9794D878-ABFB-48F6-9759-17C9C2EB48F8 'voiceon-test://community?postId=12345'` 실행.
|
||||
- 스크린샷 `/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/community-deeplink-valid.png`에서 첫 실행 추적 허용 팝업과 배경 홈 화면 확인. 재실행 캡처는 같은 디렉터리의 `community-deeplink-reopen.png`.
|
||||
- [blocked] 실제 게시글 표시·접근 권한 및 푸시 탭 UI 검증: 첫 실행 시스템 팝업을 조작할 iOS UI 자동화 도구가 제공되지 않아 완료하지 못했다. 개발 앱에서 팝업을 처리한 뒤 접근 가능한 실제 postId로 확인해야 한다. handler 검사를 UI 검증 완료로 보고하지 않는다.
|
||||
- 작업 중 `SodaLive.xcodeproj/project.pbxproj`에 별도 항목 정렬 diff가 관찰됐다. 직접 수정한 파일이 아니므로 임의 복구하지 않았으며 라우팅 변경 범위와 분리한다.
|
||||
- QA 정리: `xcrun simctl terminate 9794D878-ABFB-48F6-9759-17C9C2EB48F8 kr.co.vividnext.sodalive.debug2 && xcrun simctl shutdown 9794D878-ABFB-48F6-9759-17C9C2EB48F8 && xcrun simctl delete 9794D878-ABFB-48F6-9759-17C9C2EB48F8` 성공. 작업 전용 앱/시뮬레이터를 정리했고 사용자 기존 기기/Preview는 변경하지 않았다. 테스트 임시 바이너리는 기존 스크립트의 EXIT trap으로 제거된다.
|
||||
- 최종 딥링크 검사 279 assertions 및 `git diff --check` 재통과. 스크린샷·빌드 로그는 위 임시 경로에 검증 자료로 보존한다.
|
||||
@@ -0,0 +1,60 @@
|
||||
# PRD: 커뮤니티 딥링크 상세 이동
|
||||
|
||||
## 문서 정보
|
||||
| 항목 | 내용 |
|
||||
|---|---|
|
||||
| 상태 | 구현 완료, 실제 게시물 UI 확인 제한은 계획에 기록 |
|
||||
| 작성일 | 2026-10-13 |
|
||||
| 결정권자 | 사용자 |
|
||||
| 관련 계획 | [plan-task.md](plan-task.md) |
|
||||
| API | 기존 게시글 상세 API 재사용, 계약 변경 없음 |
|
||||
| 리뷰 | [phase1-community-post-detail-links.md](reviews/phase1-community-post-detail-links.md) |
|
||||
|
||||
## 1. Overview
|
||||
`voiceon://community?postId=12345`를 실행하면 기존 `CreatorChannelCommunityPostDetailView`에서 해당 게시물을 표시한다.
|
||||
|
||||
## 2. Problem Statement
|
||||
기존 링크는 저장된 사용자 ID를 크리에이터 ID로 사용해 커뮤니티 목록과 댓글 시트를 연다. 게시글 상세를 바로 보여주지 않으며 사용자 ID가 없으면 정상 postId도 처리되지 않는다.
|
||||
|
||||
## 3. Goals
|
||||
- 유효한 postId만으로 해당 게시글 상세 route에 진입한다.
|
||||
- postId 누락·잘못된 값이면 현재 화면과 대기 중 이동 상태를 바꾸지 않는다.
|
||||
|
||||
## 4. Non-Goals
|
||||
- 상세 화면 UI, API, 인증·구매·접근 권한 정책 변경.
|
||||
- 관련 없는 기존 댓글 화면/상태의 일괄 정리.
|
||||
- worktree 생성 또는 다른 브랜치로 전환.
|
||||
|
||||
## 5. 사용자와 권한
|
||||
푸시 탭, 외부 URL, 앱 내 알림 목록의 공통 handler를 사용한다. 게시글 존재 여부와 접근 권한은 기존 상세 API와 화면의 오류 처리를 따른다.
|
||||
|
||||
## 6. 핵심 흐름과 라우팅
|
||||
`community` 링크 → 양수 Int postId 해석 → `.creatorChannelCommunityPostDetail(postId:)` → 기존 상세 화면의 게시글 조회.
|
||||
스플래시에서는 기존 pending action 전달을 유지한다. 기존 `post_id` 별칭, 크리에이터 경로형 및 `community_id` 쿼리형은 동일한 postId 상세 이동으로 처리한다.
|
||||
|
||||
## 7. 기능 요구사항
|
||||
| ID | 상태 | 요구사항 | 수용 기준 |
|
||||
|---|---|---|---|
|
||||
| CD-001 | 확정 | postId로 상세 이동 | 12345 전달 시 상세 route에 정확히 12345 전달, 목록/댓글 시트 호출 없음 |
|
||||
| CD-002 | 확정 | 누락·무효 값 거부 | 빈 값, 문자, 0, 음수, Int 범위 초과는 이동 및 pending 변경 없음 |
|
||||
| CD-003 | 확정 | 사용자 ID 불필요 | 저장된 사용자 ID 0과 양수 모두 CD-001 성립 |
|
||||
| CD-004 | 확정 | 공통 진입점과 시작 대기 유지 | external/notificationList 및 splash 후 apply가 같은 상세 route 생성 |
|
||||
| CD-005 | 확정 | 인접 기능 유지 | 기존 선물/콘텐츠 딥링크 검사 통과 |
|
||||
|
||||
## 8. 기술·운영 제약
|
||||
기존 Swift/앱 라우팅과 `work/tests` 하네스를 재사용한다. 신규 의존성·프로젝트 설정 변경 없이 현재 브랜치에서 작업한다. 실제 서버 데이터가 필요한 UI 검증과 독립 실행 가능한 handler 검증을 구분한다.
|
||||
|
||||
## 9. 성공 기준
|
||||
- CD-001~005의 실제 production handler 실행 검사가 통과한다.
|
||||
- 변경 Swift 구문/컴파일 검사와 가능한 앱 빌드를 수행하고 실패·환경 제한을 그대로 기록한다.
|
||||
- 기기 UI 실행 미확인 상태를 정상 동작 확인으로 보고하지 않는다.
|
||||
|
||||
## 10. Open Questions
|
||||
없음. 사용자 인터뷰로 누락·잘못된 값은 이동하지 않는 것으로 확정했다.
|
||||
|
||||
## 11. Decision Log
|
||||
| 날짜 | 결정 | 근거 |
|
||||
|---|---|---|
|
||||
| 2026-10-13 | 목록 대신 기존 게시글 상세로 이동 | 사용자 구현 요청 |
|
||||
| 2026-10-13 | 누락·잘못된 postId는 이동하지 않음 | 사용자 인터뷰 답변 |
|
||||
| 2026-10-13 | 현재 브랜치 사용, worktree 금지 | 사용자 직접 지시 |
|
||||
@@ -0,0 +1,43 @@
|
||||
# 커뮤니티 상세 딥링크 리뷰
|
||||
|
||||
## 1. 리뷰 정보
|
||||
| 항목 | 내용 |
|
||||
|---|---|
|
||||
| 대상 | Phase 1 / 현재 브랜치 working tree |
|
||||
| 일자 | 2026-10-13 |
|
||||
| 리뷰어 | 독립 읽기 전용 에이전트, Sisyphus 검증 |
|
||||
| 기준 | [PRD](../prd.md), [계획](../plan-task.md) |
|
||||
| 상태 | 코드 리뷰 승인, 실제 UI 확인 제한 기록 |
|
||||
|
||||
## 2. 목적과 범위
|
||||
공통 `AppDeepLinkHandler.swift`와 `work/tests/AppDeepLinkGiftDetailCheck.swift`의 변경, 기존 AppDelegate/알림 목록/Splash/AppStep/ContentView/상세 조회 연결을 검토했다. UI 디자인·API 계약·인증 정책 변경은 제외한다.
|
||||
|
||||
## 3. 판정 기준
|
||||
정상 postId는 해당 상세 route에 전달되고, 누락·무효 postId는 현재 route와 pending action을 바꾸지 않아야 한다. 사용자 ID와 진입점에 따른 오동작 또는 기존 선물/콘텐츠 회귀는 차단 결함이다.
|
||||
|
||||
## 4. 검토 근거와 검증
|
||||
- CD-001/003: community action은 postId만 보유한다. 기존 ContentView가 이를 상세 화면에 전달하고 ViewModel은 해당 postId로 기존 API를 호출한다.
|
||||
- CD-002: 양수 Int 검증과 명시적 community 경로 fallback 차단을 확인했다. main/splash에서 현재 route와 기존 pending action 보존 검사가 통과했다.
|
||||
- CD-004: 외부 URL/푸시/알림 목록이 같은 handler를 사용하며 스플래시 재적용도 동일 action을 사용한다.
|
||||
- CD-005: 기존 선물/콘텐츠 assertion 22개를 유지했다.
|
||||
|
||||
| 검증 | 결과 |
|
||||
|---|---|
|
||||
| 리뷰어의 딥링크 하네스 재실행 | PASS, 279 assertions |
|
||||
| 전체 `work/tests/check-*.sh` | 모두 PASS |
|
||||
| Swift 구문 검사 및 `git diff --check` | PASS |
|
||||
| SodaLive-dev Debug 시뮬레이터 빌드 | BUILD SUCCEEDED |
|
||||
| Xcode test action | 스킴에 test action이 구성되지 않아 실행 불가 |
|
||||
| 실제 앱 설치/딥링크 실행 | 시도 완료, 첫 실행 추적 허용 팝업으로 상세 표시 확인 제한 |
|
||||
|
||||
## 5. 발견 사항 요약
|
||||
확정 발견 사항 없음. 코드 리뷰는 승인한다. 실제 API 응답·게시물 표시·푸시 탭 E2E 검증은 하네스와 별개이며 완료로 판단하지 않는다.
|
||||
|
||||
## 6. 발견 사항 상세
|
||||
차단 결함 없음. 개발 앱 수동 QA scheme은 `voiceon-test`, 운영 앱은 `voiceon`이다. 이 차이는 계획의 QA 명령에 반영했다.
|
||||
|
||||
## 7. plan·goal 전환
|
||||
확정 결함이 없어 전환 항목 없음.
|
||||
|
||||
## 8. 종료 판정
|
||||
요청 범위 코드와 테스트는 승인한다. 실제 UI 확인 제한 및 실행 증거는 [계획 Progress](../plan-task.md)에 기록했다. 추가 리팩터링 없이 종료한다.
|
||||
Reference in New Issue
Block a user