# 이벤트 상세 API 연동 PRD ## 문서 정보 | 항목 | 내용 | |---|---| | 문서 상태 | 클라이언트 구현·로컬 검증 완료 | | 작성일 / 최종 수정일 | 2026-10-29 | | 대상 제품 | SodaLive iOS 이벤트 상세 | | 작성자·결정권자 | 사용자 계약, 구현 에이전트에 실행 위임 | | 관련 API Contract | [api-contract.md](api-contract.md) | | 관련 구현 계획 | [plan-task.md](plan-task.md) | | 관련 review | [phase1-event-detail-api.md](reviews/phase1-event-detail-api.md) | ## 1. Overview 기존 이벤트 진입점에서 ID만 전달하고 상세 API의 최신 단일 이벤트를 표시한다. 후속 딥링크도 ID만으로 진입할 수 있도록 payload 보존을 제거한다. ## 2. Problem Statement 기존 상세 화면은 목록 payload를 직접 표시하고 optional 상세 이미지를 강제 해제한다. 목록에 없는 이벤트의 독립 조회와 접근 불가 판단이 불가능하다. 이전 이벤트 목록 중복 로딩 개선 문서와는 별개의 신규 작업이다. ## 3. Goals 양수 Int ID로 익명/인증 상세 조회를 수행하고 loading, loaded, unavailable, 네트워크·응답 error를 구별한다. 기존 이미지 비율, 참여 버튼 모양·위치, toast와 navigation bar를 유지한다. ## 4. Non-Goals 딥링크 parser/등록, 목록·팝업 조회와 로그인 게이트 변경, 공통 인증/URL 정책 리팩터링, 새 UI·의존성, 자동 외부 이동, payload fallback은 제외한다. 서버도 동시 구현 중이므로 사용자 지시에 따라 클라이언트 구현 후 실서버 연결 테스트는 하지 않는다. 현재 브랜치에서 직접 작업하며 worktree를 만들지 않는다. ## 5. Target Users and Permissions 공개 상세는 비로그인 사용자도 조회한다. 토큰이 있으면 Bearer를 전달한다. 기존 진입점의 로그인 게이트는 유지한다. 401의 세션 초기화·main 이동은 기존 AuthPlugin 소유다. ## 6. 핵심 사용자 흐름 1. 기존 목록·팝업·배너에서 이벤트를 선택한다. 2. `AppStep.eventDetail(eventId: Int)`로 이동하고 상세를 한 번 요청한다. 3. 유효한 응답은 optional 상세 이미지와 안전한 참여 링크를 표시한다. 이미지 없는 link-only도 정상이다. 4. 비양수 ID 또는 HTTP 200 success=false는 해당 상세 화면만 닫는다. 네트워크/HTTP/파싱 오류는 toast로 알린다. 5. 화면 이탈 시 취소하고 지연 응답·중복 응답의 화면 변경을 차단한다. ## 7. 정보 구조와 라우팅 `AppStep.eventDetail(eventId: Int)` → `EventDetailView(eventId:)` → 소유 StateObject VM → 기존 EventRepository/EventApi. iOS 16.6+의 Int는 signed 64-bit이며 Int.max까지 손실 없이 전달한다. 실제 딥링크 추가는 후속 범위다. ## 8. 기능 요구사항 | ID | 상태 | 요구사항 | 수용 기준 | 계약/Goal 연결 | |---|---|---|---|---| | EVT-001 | 확정 | 모든 기존 진입점은 ID만 전달 | 7개 호출 및 destination 변경, 선택·인증 분기 보존 | §1, P1-T2 | | EVT-002 | 확정 | 공개 v2 상세 GET | requestPlain, 빈 토큰 Authorization 없음, 기존 list/popup 불변 | §1, P1-T1 | | EVT-003 | 확정 | status → success → 단일 object 순서 검증 | false의 data 모양 무시, malformed success는 error | §2, P1-T1 | | EVT-004 | 확정 | 생명주기·링크 안전성 | cancel/중복 로딩·dismiss 방지, HTTP(S)+host만 참여 가능 | §3, P1-T1/P1-T2 | ## 10. UI/UX Expectations 기존 7개 관련 화면과 BaseView, DetailNavigationBar, GiftBoxCardView 및 Color/Spacing/Radius/FontModifier를 확인했다. 기존 화면은 black/gray22, Pretendard 기반 appFont, 13.3pt 레거시 간격을 사용한다. 재설계 없이 상세 이미지 scaledToFit과 기존 버튼 값을 보존한다. 참여 action은 동일 외형의 plain Button으로 바꾼다. popup 이미지 fallback·가짜 제목/날짜는 없다. ## 11. API 계약 [api-contract.md](api-contract.md)의 확정 계약을 사용한다. DTO는 기존 EventItem 그대로 재사용한다. ## 12. 보안과 데이터 취급 외부 응답은 status와 envelope/필수 필드/일치 ID를 검증한다. 외부 참여 URL은 로컬에서 절대 HTTP(S)+비어 있지 않은 host만 허용한 뒤 기존 canOpenURL/open을 사용한다. 이는 좁은 scheme 경계이며 도메인 신뢰·리디렉션 안전성을 보증하지 않는다. 토큰/응답 본문을 추가 로깅하지 않는다. ## 13. 성능과 품질 요구사항 실제 Combine과 production API/repository/VM/DTO를 swiftc CLI로 검사한다. 같은 loaded 화면은 재조회하지 않는다. 새 VM은 두 앱 타깃에 등록한다. 빌드·시뮬레이터·최종 리뷰는 상위 실행자 검증 대상으로 명확히 구분한다. ## 14. 성공 기준 - [x] 집중 CLI에서 요청·인증·ID 경계·상태·URL·취소/중복·main delivery 검증 통과. - [x] 모든 ID-only 탐색 호출과 두 target membership 확인. - [x] RED/GREEN 실제 결과와 미실행 검증을 계획 문서에 기록. ## 15. Open Questions 없음. 사용자 계약을 구현 기준으로 확정했다. ## 16. 요구사항 추적표 EVT-001~004는 api-contract §1~3, P1-T1/P1-T2/P1-GATE 및 `work/tests/check-event-detail.sh`로 추적한다. 네이티브 화면 검증은 상위 실행자 담당이다. ## 17. Decision Log | 날짜 | ID | 상태 | 결정 | 근거 | 영향 | |---|---|---|---|---|---| | 2026-10-29 | DEC-001 | 확정 | payload 대신 Int ID만 라우팅 | 향후 이벤트 딥링크가 예정되어 독립 조회 필요 | EVT-001 | | 2026-10-29 | DEC-002 | 확정 | 기존 EventItem 재사용, thumbnail 필수, link-only 정상 | 사용자 확정 계약 | EVT-003 | | 2026-10-29 | DEC-003 | 확정 | unavailable은 View-scoped dismiss, AuthPlugin 유지 | AppState.back은 live sheet를 우선 닫음 | EVT-004 | | 2026-10-29 | DEC-004 | 확정 | 현재 브랜치 직접 작업, 실서버 연결 테스트 제외 | 사용자 후속 지시, 서버 동시 구현 중 | 구현·검증 범위 | ## 후속 요구사항: 목록 이미지 원본 비율 - 2026-10-29 | ID | 상태 | 요구사항 | 수용 기준 | Goal 연결 | |---|---|---|---|---| | EVT-005 | 확정 | 기존 이벤트 목록 이미지를 원본 비율로 표시 | 기존 너비 유지, scaledToFit과 높이 없는 frame으로 이미지 전체 표시 | P2-T1 | ### 후속 결정 | 날짜 | ID | 상태 | 결정 | 근거 | 영향 | |---|---|---|---|---|---| | 2026-10-29 | DEC-005 | 확정 | 목록의 표시 modifier만 변경하고 downsampling은 유지 | 사용자 명시 요청; Kingfisher는 max(width, height)로 다운샘플링하며 원본 비율을 유지 | EVT-005 | - 기존 간격·탭·상태·API·상세 화면은 변경하지 않는다. 서버/CDN 호출은 하지 않는다. - 순수 UI modifier 변경으로 새 로직 테스트 seam이 없어 TDD 예외로 처리한다. 소스 문자열 의사 테스트는 추가하지 않으며 로컬 렌더·빌드·리뷰 증거는 상위 실행자 검증 대기다. - 후속 검증 완료: 독립 macOS SwiftUI 원본 비율 렌더 6/6, 양 앱 Debug 시뮬레이터 빌드, 로컬 회귀 14개 PASS 및 [Phase 2 리뷰](reviews/phase2-event-list-image-aspect.md) APPROVE. 실제 iOS 앱 화면 조작·서버/CDN 테스트는 수행하지 않았다.