Files
sodalive-ios/docs/20261029_이벤트_상세_API_연동/plan-task.md
T

23 KiB

이벤트 상세 API 연동 실행 계획

문서 항목 내용
상태 클라이언트 구현·로컬 검증 완료
작성일 2026-10-29
요구사항 기준 prd.md
API 기준 api-contract.md
현재 Phase 1 상세 API와 ID-only 탐색
현재 활성 Goal 없음

목표

기존 진입점에서 ID로 이벤트 최신 상세를 안전하게 조회하고 참여한다.

현재 상태

Phase 상태 완료 Task 활성/다음 Goal 남은 조건
1 완료 3/3 없음 실화면 QA는 도구 부재로 미실행

범위와 기술적 제약

실제 EventApi/EventRepository/EventItem, 신규 V2 VM, 기존 상세 View 및 7개 탐색 호출만 변경한다. Swift/Combine/Moya와 기존 UI 스타일을 유지하며 dependency·테스트 타깃·공통 인증 변경은 없다. 딥링크 parser와 사용자 지시에 따른 실서버 테스트는 제외한다. 상위 실행자가 양 스킴 빌드·전체 CLI 회귀·단일 리뷰를 완료했다.

Phase 1

Phase 결과: ID만으로 상세를 조회하고 안전한 참여 링크를 제공한다. 선행조건: 사용자 확정 계약, 가이드/샘플과 기존 notice CLI seam 확인 완료.

Task 1.1 API·상태·생명주기

Goal 실행 P1-T1: 실제 production API/repository/VM/DTO가 응답·취소·링크 계약을 만족한다. 완료 증거: focused CLI RED/GREEN 및 직접 production driver 실행 결과.

Files:

  • Create: work/tests/EventDetailCheck.swift, work/tests/check-event-detail.sh, SodaLive/Sources/V2/Settings/Event/EventDetailViewModel.swift

  • Modify: SodaLive/Sources/Settings/Event/EventApi.swift, SodaLive/Sources/Settings/Event/EventRepository.swift

  • Consumes: 기존 EventItem, ApiResponse, ApiResponseWithoutData, provider plugin.

  • Produces: getEventDetail(id:), EventDetailViewModel(eventId:), loading/loaded/unavailable/error와 일회성 dismissal 소비.

  • RED: 실제 production 파일을 컴파일하는 notice 방식 CLI를 먼저 작성한다.

  • RED 확인: bash work/tests/check-event-detail.sh로 신규 인터페이스 미구현 실패를 기록한다.

  • GREEN: status-first·success-first decoding, 안전 URL, 취소/요청 중복 제어를 최소 구현한다.

  • GREEN 확인: 동일 CLI에서 요청/토큰/64-bit/비양수/nullable·malformed/HTTP/transport/main/cancel/중복 검사를 통과한다.

  • REFACTOR: 신규 중복만 정리하고 focused regression을 재실행한다.

Task 1.2 View·ID-only 라우팅·타깃 등록

Goal 실행 P1-T2: 모든 기존 진입점에서 ID를 전달하고 기존 외형으로 상세를 표시한다. 시작 조건: P1-T1의 VM 계약. 완료 증거: ID-only source 보완 검사, Swift parse, pbxproj 검증.

Files:

  • Modify: SodaLive/Sources/App/AppStep.swift, SodaLive/Sources/ContentView.swift, SodaLive/Sources/Settings/Event/EventDetailView.swift, SodaLive.xcodeproj/project.pbxproj

  • Modify: SodaLive/Sources/Settings/Event/EventListView.swift, SodaLive/Sources/Main/EventPopupDialogView.swift, SodaLive/Sources/Live/EventBanner/SectionEventBannerView.swift, SodaLive/Sources/Content/Main/Banner/ContentMainBannerView.swift, SodaLive/Sources/Content/Main/V2/ContentMainBannerViewV2.swift, SodaLive/Sources/V2/Main/MainView.swift

  • RED: CLI 보완 검사로 payload route 잔존을 검출한다.

  • RED 확인: 기존 payload route assertion 실패를 기록한다.

  • GREEN: StateObject, BaseView/toast, scoped dismiss와 optional image/참여 Button을 연결한다. 7개 호출과 양 target membership을 갱신한다.

  • GREEN 확인: CLI 보완 검사와 swiftc -frontend -parse, plutil -lint 성공을 확인한다.

  • REFACTOR: 기존 외형·선택·인증 분기의 불필요한 변경이 없는지 diff를 대조한다.

Task 1.3 검증 runner와 최종 기록 정리

Goal 실행 P1-T3: REV-P1-001/002의 비차단 지적을 해결하고 반복 가능한 로컬 검증 결과를 남긴다.

  • Files: work/tests/check-event-detail.sh, prd.md, plan-task.md, reviews/phase1-event-detail-api.md.
  • RED: env -u TMPDIR bash work/tests/check-event-detail.sh가 unset 변수로 exit 1임을 확인했다. runner에 EXIT trap이 없음을 확인했다.
  • GREEN: 기존 notice runner의 mktemp -d와 EXIT trap을 적용한다.
  • GREEN 확인: TMPDIR 제거 실행과 격리된 TMPDIR의 성공/실패 실행 후 생성 디렉터리 부재를 확인한다.
  • REFACTOR: 추가 앱 코드 변경 없이 최신 빌드·전체 회귀·리뷰 결과를 문서에 누적하고 소유 임시 자원을 정리한다.

Phase 1 Gate (최초 구현 인계 기록)

Goal 실행 P1-GATE: 집중 검증과 문서 결과를 인계한다.

  • 두 Task 완료 증거와 RED/GREEN 기록.
  • bash work/tests/check-event-detail.sh exit 0.
  • 영향 회귀 bash work/tests/check-my-page-notices.sh exit 0.
  • 양 앱 타깃 등록·Swift parse·diff 공백 검사 통과.
  • 빌드·시뮬레이터 QA·최종 리뷰 미실행을 명시하고 상위 실행자에 인계.

실행 순서와 의존성

P1-T1 → P1-T2 → P1-GATE. 서브에이전트/commit/push/별도 worktree는 사용하지 않는다.

Progress

계약·설계 확인 1차 실행 - 2026-10-29

  • 상태: 완료.
  • 무엇을: 저장소 가이드, 문서 샘플, 기존 notice CLI, EventItem/API/Repository/View, 전체 진입점, AppState.back과 AuthPlugin을 확인했다.
  • 왜: signed 64-bit ID-only와 false-first/status-first 계약, scoped dismiss의 실제 경계를 확정하기 위해서다.
  • 어떻게: read 및 rg로 실제 파일을 대조했다. 기존 UI/토큰 10개 이상을 확인하고 레거시 상세 외형을 그대로 보존하기로 했다.
  • 남은 항목: 테스트부터 작성하고 실행한다.

RED 1차 실행 - 2026-10-29

  • bash work/tests/check-event-detail.sh: exit 1. 신규 VM 입력 파일이 아직 없어 컴파일 실패했다. 이는 인터페이스 준비 단계의 RED이며 동작 assertion 증거와 구분한다.
  • swiftc -swift-version 5 -parse-as-library -module-cache-path "$TMPDIR/event-route-module-cache" -D EVENT_ROUTE_CHECK work/tests/EventDetailCheck.swift -o "$TMPDIR/check-event-routes-red" && "$TMPDIR/check-event-routes-red" "$PWD": exit 1, FAIL: event detail route still retains payload instead of Int ID.
  • 다음 행동: API 인터페이스와 최소 VM 선언을 추가해 실제 VM 동작 assertion의 RED를 확인한다. 이후에만 VM 상태 로직을 구현한다.

RED 2차 실행 - 2026-10-29

  • bash work/tests/check-event-detail.sh: exit 1, FAIL: Loading must deduplicate.
  • API 선언과 VM 인터페이스만 준비한 실제 production VM에 대해 native Combine driver를 실행했다. 요청 경로·헤더 검사는 PASS했고 상태 로직 미구현 assertion이 실패했다. 테스트를 완화하지 않고 VM 동작 구현으로 진행한다.

GREEN 및 P1-GATE 실행 - 2026-10-29

  • 상태: 완료. 이벤트 API/Repository/VM/DTO를 native Combine으로 실제 실행하는 CLI와 직접 영향 notice 회귀를 실행했다.
  • 왜: 서버 payload와 무관한 ID-only 진입, 익명 헤더, 응답 상태 분류와 이탈 안전성을 검증하고 기존 공유 envelope 동작이 유지되는지 확인했다.
  • 모든 shell 검증에 다음 환경을 사용했다. 생성된 event-detail 디렉터리와 route RED 실행 파일은 이 TMPDIR 내부에 보존했고 정리는 상위 실행자 소유다.
export TMPDIR=/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/tmp.UN5uRreooU
export NODE_COMPILE_CACHE=$TMPDIR/node-compile-cache
export BUN_RUNTIME_TRANSPILER_CACHE_PATH=$TMPDIR/bun-transpiler
bash work/tests/check-event-detail.sh
bash work/tests/check-my-page-notices.sh
swiftc -frontend -parse SodaLive/Sources/App/AppStep.swift SodaLive/Sources/ContentView.swift SodaLive/Sources/Settings/Event/EventApi.swift SodaLive/Sources/Settings/Event/EventRepository.swift SodaLive/Sources/Settings/Event/EventDetailView.swift SodaLive/Sources/Settings/Event/EventListView.swift SodaLive/Sources/Main/EventPopupDialogView.swift SodaLive/Sources/Live/EventBanner/SectionEventBannerView.swift SodaLive/Sources/Content/Main/Banner/ContentMainBannerView.swift SodaLive/Sources/Content/Main/V2/ContentMainBannerViewV2.swift SodaLive/Sources/V2/Main/MainView.swift SodaLive/Sources/V2/Settings/Event/EventDetailViewModel.swift work/tests/EventDetailCheck.swift
plutil -lint SodaLive.xcodeproj/project.pbxproj
bash -n work/tests/check-event-detail.sh
GIT_MASTER=1 git diff --check

각 명령 exit 0. 이벤트 CLI 실제 출력:

PASS: actual API/repository exact GET/requestPlain, anonymous/bearer, legacy routes/headers, >32-bit and Int.max
PASS: actual DTO/VM single object, optional omitted/null, image-only/link-only/both/neither, 64-bit IDs, main delivery, no refetch
PASS: nonpositive no request; false ignores malformed data/localized message; malformed success/HTML503/abnormal HTTP/401/transport stay error, loading ends, one dismissal
PASS: actual participation URL HTTP(S)+host boundary; cancel/queued/late/stale/duplicate responses, reload after cancellation, disappearance suppresses dismissal
PASS: Event detail regression checks (actual production API/repository/VM/DTO, native Combine; no server calls)
PASS: supplementary ID-only route/destination and 7 existing navigation call sites

notice CLI는 다음 네 줄로 완료됐다:

PASS: actual NoticeApi/Repository public v2 GET requestPlain without Authorization; legacy list auth/timezone unchanged
PASS: actual DTO/roller 0/1/2/3, omitted/null envelope, repeated order/wrap/selection, exact HTML/date, legacy no-id, shrink/reset and lifecycle predicate
PASS: actual MyPageViewModel background delivery on main, 0/1/2/3 success, empty hides, HTTP/envelope/decode/transport failure preserves data, log-only/loading semantics
PASS: My Page notices regression checks (actual production API/Repository/VM/DTO/roller, native Combine; no server calls)

plutil은 SodaLive.xcodeproj/project.pbxproj: OK, Swift parse·shell 문법·diff 공백 검사는 출력 없이 exit 0이었다. 타깃·경로 그래프는 다음 명령으로 별도 검증했다:

plutil -convert json -o - SodaLive.xcodeproj/project.pbxproj | python3 -c 'import json,sys; project=json.load(sys.stdin); objects=project["objects"]; refs=[key for key,obj in objects.items() if obj.get("isa")=="PBXFileReference" and obj.get("path")=="EventDetailViewModel.swift"]; assert len(refs)==1, refs; ref=refs[0]; paths=[]
def walk(key,path=""):
 obj=objects[key]; path="/".join(part for part in [path,obj.get("path","")] if part)
 if key==ref: paths.append(path)
 for child in obj.get("children",[]): walk(child,path)
walk(objects[project["rootObject"]]["mainGroup"]); assert paths==["SodaLive/Sources/V2/Settings/Event/EventDetailViewModel.swift"], paths
for name in ["SodaLive","SodaLive-dev"]:
 target=next(obj for obj in objects.values() if obj.get("isa")=="PBXNativeTarget" and obj.get("name")==name); files=[file for phase in target["buildPhases"] if objects[phase]["isa"]=="PBXSourcesBuildPhase" for file in objects[phase]["files"]]; count=sum(objects[file].get("fileRef")==ref for file in files); assert count==1,(name,count); print("PASS: "+name+" has exactly one EventDetailViewModel.swift source membership at "+paths[0])'

exit 0, 실제 출력:

PASS: SodaLive has exactly one EventDetailViewModel.swift source membership at SodaLive/Sources/V2/Settings/Event/EventDetailViewModel.swift
PASS: SodaLive-dev has exactly one EventDetailViewModel.swift source membership at SodaLive/Sources/V2/Settings/Event/EventDetailViewModel.swift
  • 직접 사용 검증: production 모듈 driver로 object 정상 로드, link-only, 비양수 입력, transport/HTTP/파싱 오류와 취소/지연 응답을 실행했다. 실제 서버·UIApplication.open은 실행하지 않았다.
  • 미실행: 전체 build/test·시뮬레이터/실기기 시각 QA·VoiceOver·최종 리뷰. 사용자 위임 범위에 따라 상위 실행자가 수행한다. 이 환경에는 lsp_diagnostics 도구가 없어서 해당 clean 판정은 하지 않았다. 대신 VM/API/repository/DTO의 swiftc typecheck/실행과 변경 Swift 전체 parse를 확인했다.
  • diff 대조: 상세의 레거시 외형 값, list/live의 상세 대 외부 URL 분기와 로그인 게이트를 유지했다. AppDeepLinkHandler, AuthPlugin, AcceptLanguagePlugin, EventItem, 기존 notice 테스트는 변경하지 않았다.
  • 관찰: 최종 project.pbxproj diff에는 이번 패치에 없는 MyPageNoticeRoller 참조·그룹 블록의 순서 이동도 보인다. 공유 작업 변경으로 간주하여 되돌리지 않았다. 이벤트 VM 추가 membership과 경로는 독립적으로 검증했다.
  • 남은 구현 항목: 없음. 다음 행동: 상위 실행자의 앱 빌드·실화면 QA·단일 리뷰.

Decision Log

날짜 ID 상태 결정 근거 영향 Goal
2026-10-29 DEC-001 확정 ID-only, Int.max 검증, DTO 재사용 PRD DEC-001/002 P1-T1/P1-T2
2026-10-29 DEC-002 확정 View 환경 dismiss와 일회성 소비 전역 back의 live sheet 우선 처리 P1-T1/P1-T2
2026-10-29 DEC-003 확정 현재 브랜치 직접 작업, 실서버 연결 테스트 제외 사용자 후속 지시, PRD DEC-004 최종 검증

상위 실행자 검증 1차 - 2026-10-29

  • 현재 브랜치에서 작업했으며 별도 worktree/commit/push는 생성하지 않았다.
  • bash work/tests/check-event-detail.sh: 실제 production API/repository/VM/DTO와 native Combine, ID-only 7개 호출 검사 PASS, exit 0.
  • for script in work/tests/check-*.sh; do bash "$script"; done: 신규 이벤트 검사를 포함한 14개 스크립트 모두 PASS. 변경 전 13개 스크립트도 모두 PASS였다.
  • xcodebuild -workspace SodaLive.xcworkspace -scheme SodaLive -configuration Debug -destination 'generic/platform=iOS Simulator' -disableAutomaticPackageResolution CODE_SIGNING_ALLOWED=NO build: BUILD SUCCEEDED, exit 0.
  • 같은 명령의 -scheme SodaLive-dev: BUILD SUCCEEDED, exit 0. 변경한 Swift 코드가 양 타깃에서 컴파일됐다.
  • 기존 중복 Compile Sources, Run Script 출력 미지정, AppIntents 메타데이터 경고는 수정 범위 밖이라 유지했다.
  • 초기 standard 빌드는 120초 timeout, 다음 시도는 구현 도중 VM 타깃 등록 전이라 scope 오류였다. 등록 완료 후 위 최종 빌드는 성공했다.
  • Xcode 실행이 만든 MyPageNoticeRoller 블록의 순서 이동만 원위치로 정리했다. 정리 전후 plutil JSON 정렬 SHA-256은 c010f8053c481722451be769f8dbfe6532866ad3301e20054465106c020a13e2로 동일하여 프로젝트 의미와 빌드 입력은 변하지 않았다.
  • 실서버 연결 테스트: 사용자 지시로 구현 후 수행하지 않았다. 지시 전 조사에서 관찰한 401은 서버 개발 중의 정보이며 클라이언트 완료 차단 사유가 아니다.
  • 네이티브 화면 조작/시각 QA, VoiceOver 및 lsp_diagnostics는 해당 도구가 없어 미실행이다. Swift 컴파일과 로컬 상태 드라이버 검사로 대체했으며 실제 화면 검증 통과를 주장하지 않는다.
  • 단일 Oracle 리뷰 진행 중. 추가 확인: env -u TMPDIR bash work/tests/check-event-detail.sh는 5행의 unset 변수로 exit 1. 반복 실행 시 생성된 검사 임시 디렉터리도 자체 정리가 없어 리뷰와 수정 대상으로 기록한다.

발견된 문제

양 스킴 빌드·14개 CLI 회귀는 최종 PASS이며 Oracle 단일 리뷰는 APPROVE다. MyPage 블록 순서 이동은 상위 실행자의 Xcode 실행 산출물로 확인 후 제거했다. 네이티브 실화면 QA/VoiceOver/LSP는 도구 부재로 미실행이며 실서버 테스트는 사용자 지시로 제외한다.

P1-T3 및 최종 리뷰 - 2026-10-29

  • Oracle 단일 리뷰: 앱 계약 위반의 확정 차단 사항 없음, APPROVE. 비차단 runner/문서 지적은 후속 수정했다.
  • runner 수정 후 env -u TMPDIR bash work/tests/check-event-detail.sh: exit 0, 모든 집중 검사 PASS.
  • bash -x work/tests/check-event-detail.sh: exit 0, 생성한 임시 디렉터리의 EXIT trap 실행과 이후 test ! -e PASS를 확인했다.
  • bash -c 'swiftc() { return 42; }; export -f swiftc; bash -x work/tests/check-event-detail.sh; result=$?; test "$result" -eq 42': 의도한 컴파일 실패 코드 42 유지, EXIT trap 실행, 이후 test ! -e PASS를 확인했다.
  • bash -n work/tests/check-event-detail.sh: exit 0. 앱 production 코드는 리뷰 승인·양 스킴 빌드 이후 변경하지 않았다. 최종 수정은 runner 정리 2줄과 문서뿐이라 해당 runner 경로만 재검증했다.
  • 자원 정리: xcodebuild/이벤트 swiftc 실행 프로세스 부재를 확인하고 이번 실행이 생성한 parent/구현자 임시 디렉터리와 notepad를 삭제했다. 두 run root의 test ! -e PASS. 공유 Xcode 캐시·사용자 파일·worktree는 삭제하지 않았다. 일회성 raw 빌드 로그는 함께 제거했고 명령·종료 코드·주요 결과는 이 문서에 보존했다.

Phase 2: 목록 이미지 원본 비율

Phase 결과: EVT-005에 따라 기존 너비에서 이미지 전체를 원본 비율로 표시한다. 선행조건: 사용자 요청 확정, 기존 디자인/Kingfisher 조사 완료. 현재 브랜치에서 최소 수정한다.

Task 2.1 목록 이미지 표시

Goal 실행 P2-T1: 고정 1000:300 표시 높이를 제거하고 기존 너비를 유지한다. Files: SodaLive/Sources/Settings/Event/EventListView.swift. 완료 증거: 변경 소스 확인, Swift parse와 diff 공백 검사; 실제 화면·빌드·리뷰는 상위 실행자 담당.

  • EVT-005/DEC-005 및 TDD 예외를 소스 수정 전에 기록한다.
  • scaledToFill을 scaledToFit으로 바꾸고 표시 frame의 높이만 제거한다. downsampling·간격·탭·상태·API는 유지한다.
  • swiftc -frontend -parse SodaLive/Sources/Settings/Event/EventListView.swift와 GIT_MASTER=1 git diff --check의 exit 0을 확인한다.
  • 상위 실행자가 로컬 렌더·빌드·테스트·리뷰를 수행하고 증거를 누적한다.

P2-T1 검증 기록

  • 무엇/왜: 목록 이미지의 고정 표시 비율만 제거한다. 새 로직 seam이 없는 UI modifier 변경이므로 TDD 예외이며 소스 문자열 의사 테스트는 만들지 않는다.
  • 검증 범위: 구현자는 소스 확인·parse·diff 검사만 수행한다. 로컬 렌더·빌드·리뷰 증거는 상위 실행자 검증 대기이며 서버/CDN 호출은 금지한다.
  • 실행 결과: 위 Swift parse·diff 공백 검사는 모두 출력 없이 exit 0. 기존 ID-only 라우팅 변경은 보존했다. 지정 TMPDIR를 사용했으며 정리는 상위 실행자 소유다.

P2-T1 상위 실행자 검증 - 2026-10-29

  • 독립 macOS SwiftUI ImageRenderer에 실제 변경 전후 modifier를 적용했다. 원본 fixture는 로컬 CoreGraphics로 생성하여 서버/CDN 호출이 없었다. 너비 363.3/717.3pt에서 1000x300, 600x600, 400x600의 6개 조합을 측정하고 전체 상하단 색상 밴드가 남는지 assertion했다. parent도 driver를 직접 실행하여 6/6 PASS, exit 0을 확인하고 비교 PNG 두 장을 직접 읽었다.
  • 363.3pt 너비의 새 높이는 각각 108.99/363.30/544.95pt, 717.3pt 너비는 215.19/717.30/1075.95pt다. 오차 0.01pt 이내로 원본 비율을 유지한다. 이 검증은 격리된 네이티브 image modifier 검증이며 실제 iOS 전체 화면이나 Kingfisher 다운로드 검증이 아니다.
  • for script in work/tests/check-*.sh; do bash "$script"; done: 첫 12개 PASS 후 13번째 실행 중 전체 명령이 120초 timeout. 남은 bash work/tests/check-received-gift-detail.sh && bash work/tests/check-user-creator-chat-date-presentation.sh를 240초 제한으로 별도 재실행하여 둘 다 PASS/exit 0. 합계 기존 14개 검사 모두 통과했다.
  • xcodebuild -workspace SodaLive.xcworkspace -scheme SodaLive -configuration Debug -destination 'generic/platform=iOS Simulator' -disableAutomaticPackageResolution CODE_SIGNING_ALLOWED=NO build: BUILD SUCCEEDED, exit 0. 동일 명령의 SodaLive-dev 스킴도 BUILD SUCCEEDED, exit 0.
  • 단일 독립 리뷰: phase2-event-list-image-aspect.md, APPROVE. 추가 수정 사항 없음.
  • git diff --check exit 0. LSP 도구가 없어 Swift parse 및 양 타깃 실제 컴파일로 대체했다. 현재 브랜치 작업이며 commit/worktree/실서버 호출은 없다.
  • 정리: 관련 실행 프로세스 부재를 확인하고 소유한 build/probe 임시 디렉터리(스크립트·이미지·바이너리·캐시)와 notepad를 제거했다. 두 run root 부재 검사 PASS. 공유 Xcode 캐시·기존 변경은 유지했고 측정값/명령/리뷰 판정은 위 기록에 보존했다.

Phase 3: 상세 참여 버튼 배경색

Phase 결과: EVT-006에 따라 배경색만 변경하고 기존 radius와 동작을 유지한다. 선행조건: 사용자 요청 및 Color.soda400(#00BDF7) 정의 확인 완료.

Task 3.1 참여 버튼 색상 토큰 적용

Goal 실행 P3-T1: 참여 버튼 배경 한 줄만 Color.soda400으로 변경한다. Files: SodaLive/Sources/Settings/Event/EventDetailView.swift. 완료 증거: 소스 확인 및 아래 Swift parse의 exit 0. 상수 스타일 변경으로 새 테스트는 추가하지 않는다.

  • 소스 수정 전에 EVT-006과 Task 3.1을 기록한다.
  • .background(Color(hex: "3e737c"))만 .background(Color.soda400)으로 변경하고 기존 두 radius·텍스트·레이아웃·로직을 보존한다.
  • swiftc -frontend -parse SodaLive/Sources/Settings/Event/EventDetailView.swift의 출력과 종료 코드를 기록한다.
  • [blocked] 빌드·실제 렌더 QA: 빌드 120초 제한으로 중단, 화면 조작 도구 부재로 렌더 QA 미실행.

P3-T1 검증 기록 - 2026-10-30

  • 참여 버튼 배경 상수 한 줄만 Color.soda400으로 변경했다. 소스를 다시 읽어 .cornerRadius(10)과 외곽 .cornerRadius(16.7, corners: [.topLeft, .topRight]), 나머지 텍스트·레이아웃·로직이 유지됨을 확인했다.
  • swiftc -frontend -parse SodaLive/Sources/Settings/Event/EventDetailView.swift: 출력 없음, exit 0.
  • 빌드·실제 렌더 QA는 수행하지 않았으며 미검증이다. 상수 스타일 변경으로 새 테스트는 추가하지 않았다.
  • 상위 실행자 재검증: Swift parse exit 0, bash work/tests/check-event-detail.sh의 production API/VM/DTO 및 ID-only 라우팅 검사 모두 PASS, exit 0.
  • xcodebuild -quiet -workspace SodaLive.xcworkspace -scheme SodaLive -configuration Debug -destination 'generic/platform=iOS Simulator' -disableAutomaticPackageResolution CODE_SIGNING_ALLOWED=NO build: 120초 timeout으로 BUILD INTERRUPTED. 빌드 성공 여부는 미확정이다. lsp_diagnostics와 네이티브 화면 조작 도구가 없어 LSP·실화면 QA는 수행하지 않았다.