docs(chat): 날짜 구분선 요구사항과 검증을 기록한다
@@ -0,0 +1,22 @@
|
||||
# 네이티브 날짜 구분선 캡처
|
||||
|
||||
- 환경: iPhone SE (3rd generation), iOS 18.3, 375×667pt / PNG 750×1334px.
|
||||
- 캡처: 실제 SwiftUI 날짜 구분선·formatter·모델·앱 폰트·테마를 직접 컴파일한 임시 네이티브 하네스. `xcrun simctl io screenshot`으로 촬영했다.
|
||||
- 조합: `ko_KR`, `en_US`, `ja_JP` × `normal`, `accessibility3` × `dark`, `light`, 총 12장.
|
||||
- 가용 폭: 기존 채팅과 같은 좌우 24pt 여백, 날짜 폭 327pt.
|
||||
- 최종 소스의 `SwiftUI.Font` 명시 후 다시 컴파일하고 12장 모두 재촬영했다. `production-after.sha256`의 원본 소스 9개와 현재 소스 일치를 확인했다.
|
||||
- 실제 앱 smoke 실행의 추적 권한 팝업이 남은 중간 캡처는 폐기했다. 작업 소유 시뮬레이터의 실제 앱 제거·재부팅으로 가림을 없애고 다시 촬영한 현재 12장 모두 독립 시각 재검토 PASS다.
|
||||
- 원본 폰트: Pretendard-Regular, NotoSansJP-Regular. 영어는 시스템 caption. locale별 폰트 등록과 날짜별 프레임을 실행 중 검사했다.
|
||||
- 날짜 항목과 날짜 계산은 원본 production 코드다. 주변 말풍선·상단 설명은 합성 QA UI이며 실제 `UserCreatorChatRoomView`가 아니다.
|
||||
- 전체 앱도 별도로 빌드·설치·실행했으나, 이 캡처로 실제 DM 로그인·paging·ACK·VoiceOver·스크롤 연속성의 통과를 주장하지 않는다.
|
||||
- 실제 채팅은 검정 배경을 사용하므로 light/dark 모두 같은 검정 배경이다. 별도 시각 목업이 없어 pixel-diff의 동일성 목표는 해당 없다.
|
||||
|
||||
## 관찰값
|
||||
|
||||
| locale | normal 날짜 높이 | accessibility3 날짜 높이 | 결과 |
|
||||
|---|---:|---:|---|
|
||||
| ko_KR | 14.5pt | 35pt | 전체 날짜 한 줄 |
|
||||
| en_US | 14.5pt | 77.5pt | 큰 글자에서 두 줄, 전체 필드 유지 |
|
||||
| ja_JP | 17.5pt | 42pt | 전체 날짜 한 줄 |
|
||||
|
||||
기능 판정·미검증 항목·정리 결과는 [리뷰 리포트](../phase1-chat-date-separators.md)에 기록한다. 임시 앱·시뮬레이터·컴파일 캐시는 증거를 옮긴 뒤 제거한다.
|
||||
@@ -0,0 +1 @@
|
||||
PASS: 113 assertions
|
||||
|
After Width: | Height: | Size: 129 KiB |
|
After Width: | Height: | Size: 129 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 78 KiB |
@@ -0,0 +1,2 @@
|
||||
FAIL: Gregorian UTC fixture ko_KR: expected '2026년 10월 16일 금요일', got ''
|
||||
EXIT_CODE: 1
|
||||
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 70 KiB |
@@ -0,0 +1,9 @@
|
||||
b7428e768adf7fbe2ebb356505594e5ba1325213d2d53aa624651dc230c4d05e /Users/klaus/Develop/sodalive/iOS/SodaLive/SodaLive/Sources/V2/Main/Chat/UserCreatorChat/Components/UserCreatorChatDateSeparatorView.swift
|
||||
a5c0de9b1b1fdb682708035b1f5fde6e3e2e231a6696ba6f40134caff25b647e /Users/klaus/Develop/sodalive/iOS/SodaLive/SodaLive/Sources/V2/Main/Chat/UserCreatorChat/Models/UserCreatorChatDatePresentation.swift
|
||||
34bddad5cb9cc1791fad5b0d3c84461d4d1f536035cdfd2b184a6989330ac80c /Users/klaus/Develop/sodalive/iOS/SodaLive/SodaLive/Sources/V2/Main/Chat/UserCreatorChat/Models/UserCreatorChatDisplayMessage.swift
|
||||
dba97c4663dd64673d79953b5687ef10fbd4cd358e3b2cdcd5c07ab9f26ee5c3 /Users/klaus/Develop/sodalive/iOS/SodaLive/SodaLive/Sources/V2/Main/Chat/UserCreatorChat/Models/UserCreatorChatModels.swift
|
||||
086fb0a19d884124a4cca638f7c8483de724ee31a61603b2cbd489aabf26a6c6 /Users/klaus/Develop/sodalive/iOS/SodaLive/SodaLive/Sources/Extensions/FontModifier.swift
|
||||
747347d86ade888fe9c1d30629285b4a71991bc0f21189a0d4b76ad314c32364 /Users/klaus/Develop/sodalive/iOS/SodaLive/SodaLive/Sources/Extensions/ColorExtension.swift
|
||||
0f50ec7d3e77e0813fd1a806440c01baf96f8fdfa2a41faccd6dc4df52cf647a /Users/klaus/Develop/sodalive/iOS/SodaLive/SodaLive/Sources/UI/Theme/Color.swift
|
||||
372a73b821236c15449fa022cd628f61556f1381a16f234a4b77e833c2e588c1 /Users/klaus/Develop/sodalive/iOS/SodaLive/SodaLive/Sources/UI/Theme/Spacing.swift
|
||||
cbb8e24dc17b352d30adf3a6cd2b190532f059a02801ecabf7392a013914352c /Users/klaus/Develop/sodalive/iOS/SodaLive/SodaLive/Sources/Settings/Language/Models/LanguageOption.swift
|
||||
@@ -0,0 +1 @@
|
||||
FAIL: single TEXT message must have its first separatorDate
|
||||
@@ -0,0 +1,111 @@
|
||||
# Phase 1 채팅 날짜 구분선 검증 및 리뷰
|
||||
|
||||
## 1. 리뷰 정보
|
||||
|
||||
| 항목 | 내용 |
|
||||
|---|---|
|
||||
| 대상 | P1-T1, P1-T2, P1-GATE |
|
||||
| 기준 | feat/dm-date-separators, 시작 3bd75f1 / formatter e765c3c / 화면 연결 7a6d12e |
|
||||
| 일자 | 2026-10-16 |
|
||||
| 기준 문서 | [PRD](../prd.md), [계획](../plan-task.md) |
|
||||
| 상태 | 코드 검토 승인 / 실제 DM·접근성 Gate 외부 조건 대기 |
|
||||
|
||||
## 2. 목적과 범위
|
||||
|
||||
DATE-001~008의 날짜 문자열, 현지 날짜 경계, 페이지 병합, ACK 시각 교체, 표시 TEXT 범위와 비고정 UI를 검증한다. 네트워크·인증·기존 메시지 시각·VOICE UI 변경은 제외한다.
|
||||
|
||||
## 3. 판정 기준
|
||||
|
||||
요구사항 위반과 기존 paging/scroll 회귀는 차단 항목이다. 자동 스냅샷 검사와 실제 서버 QA를 구분하며, 수행하지 못한 확인은 통과로 기록하지 않는다. 구현 결함이 확정되면 수정 전에 계획에 회귀 Task를 추가한다.
|
||||
|
||||
## 4. 검토 근거와 환경
|
||||
|
||||
- Xcode 26.0 (17A324), macOS, Swift 5 language mode, 최소 iOS 16.6.
|
||||
- 실제 앱 타깃: SodaLive / SodaLive-dev. XCTest 타깃 없음. 기존 work/tests standalone Swift checker 사용.
|
||||
- 앱 루트의 locale 주입, DM View의 첫/마지막 메시지 paging·scroll hook, ViewModel의 기존 ACK 교체 로직을 기준으로 한다.
|
||||
- 현재 도구 세트에 LSP diagnostics와 네이티브 GUI 입력 드라이버가 없다. 컴파일러 검증과 가능한 네이티브 렌더 캡처를 사용하되 동등하지 않은 검증은 구분한다.
|
||||
|
||||
## 5. 실행한 검증
|
||||
|
||||
| 검증 | 결과 | 근거 |
|
||||
|---|---|---|
|
||||
| xcodebuild -version | 통과 | Xcode 26.0, 17A324 |
|
||||
| xcodebuild -workspace SodaLive.xcworkspace -list -disableAutomaticPackageResolution | 통과 | 두 앱 스킴 확인, exit 0. DVTDeviceOperation build-number 경고 있음 |
|
||||
| 날짜 formatter / grouping checker | 통과 | 의도한 RED 이후 최종 `PASS: 113 assertions`, exit 0. 재개 후 재실행도 동일 |
|
||||
| 기존 work/tests 회귀 | 통과 | 기존 11개 스크립트 지원 모드 18회 + 신규 날짜 checker 1회, 최종 19회 모두 exit 0 |
|
||||
| 두 앱 타깃 빌드 | 통과 | SodaLive generic iOS / SodaLive-dev simulator 최종 빌드 모두 exit 0. CODE_SIGNING_ALLOWED=NO |
|
||||
| plutil / diff whitespace | 통과 | project.pbxproj OK, git diff --check exit 0 |
|
||||
| 네이티브 렌더링 | 컴포넌트 한정 통과 | 실제 production 소스·폰트 사용, 3언어×2글자크기×2테마 12장. 최종 소스9개 해시 일치 확인 |
|
||||
| 실제 앱 설치·실행 | 통과 | 소유된 iPhone SE3/iOS18.3에 개발 앱 설치, launch 성공 및 홈 화면 표시 확인 |
|
||||
| 실제 DM 서버·paging·ACK QA | 외부 조건 대기 | 안전하게 사용할 테스트 계정과 접근 가능한 roomId가 제공되지 않음 |
|
||||
|
||||
## 6. 발견 사항
|
||||
|
||||
잔여 확정 코드 결함 없음. Oracle 코드 리뷰는 APPROVE다. 이것은 실서버 통합 및 VoiceOver 상호작용까지 검증한 승인이 아니다.
|
||||
|
||||
| ID | 상태 | 내용 | 재개 조건 |
|
||||
|---|---|---|---|
|
||||
| QA-001 | 보류 | 실제 DM 대화 진입과 서버 ACK/과거 페이지 검증에는 인증과 테스트 방 필요 | 사용자가 승인한 테스트 계정·roomId 및 날짜가 다른 이력 제공 |
|
||||
| QA-002 | 보류 | lsp_diagnostics 도구 없음 | native Swift compiler/build 결과와 별도로 도구 가용 시 실행 |
|
||||
| QA-003 | 보류 | 실제 VoiceOver 읽기와 화면 스크롤 제스처 미실행 | GUI 접근 가능한 기기에서 날짜 1회 읽기·비고정 스크롤 확인 |
|
||||
| BUILD-001 | 수정 검증 완료 | 새 dateFont의 `Font`가 기존 앱 enum과 충돌, 두 타깃 컴파일 실패 | T2 진행 중 `SwiftUI.Font` 한정 후 두 타깃 동일 명령 exit 0 |
|
||||
| EVIDENCE-001 | 교정 완료 | 초기 캡처 소스 해시가 최종 폰트 타입 한정 전 소스와 일치 | 최종 소스로 12장 재촬영, 재개 시 소스9개 SHA-256 모두 OK |
|
||||
| EVIDENCE-002 | 수정 검증 완료 | 실제 앱 smoke 실행의 시스템 추적 권한 팝업이 후속 캡처의 날짜를 가림 | 소유된 시뮬레이터에서 실제 앱 제거·재부팅 후 12장 전체 재촬영, 독립 재검토 12/12 PASS |
|
||||
|
||||
## 7. 계획 연결
|
||||
|
||||
독립 코드 리뷰에서 신규 회귀 수정이 필요한 발견 사항은 없었다. BUILD-001은 P1-T2 미완료 상태에서 컴파일로 발견해 수정한 항목이다. 필수 실서버 QA가 미완료이므로 P1-GATE를 완료 처리하지 않는다.
|
||||
|
||||
## 8. 종료 판정
|
||||
|
||||
구현·자동 검사·두 타깃 빌드 완료, 코드 범위 APPROVE. 전체 P1-GATE는 QA-001·003과 LSP 도구 가용성 확인이 남아 BLOCKED다. 테스트 방을 제공받지 않았으므로 개인 토큰을 읽거나 임의 roomId에 접근해 검증을 우회하지 않았다.
|
||||
|
||||
## 9. 후속 검증 기록
|
||||
|
||||
새 실행 결과와 리뷰 판정은 이 문서에 누적한다.
|
||||
|
||||
### 자동 검사 및 빌드
|
||||
|
||||
- formatter RED: `expected '2026년 10월 16일 금요일', got ''`, exit 1. rows RED: `FAIL: single TEXT message must have its first separatorDate`. 증거는 [formatter-red.log](evidence/formatter-red.log), [rows-red.log](evidence/rows-red.log).
|
||||
- GREEN: `sh work/tests/check-user-creator-chat-date-presentation.sh` → 113 assertions, exit 0. [최종 로그](evidence/checker-final.log).
|
||||
- `plutil -lint SodaLive.xcodeproj/project.pbxproj` → OK. 신규 소스 두 개는 양쪽 앱 타깃에 각각 등록됐다.
|
||||
- `xcodebuild -quiet -workspace SodaLive.xcworkspace -scheme SodaLive -configuration Debug -destination 'generic/platform=iOS' -derivedDataPath "$RUN_TMP/standard-build" CODE_SIGNING_ALLOWED=NO build` → 최종 exit 0.
|
||||
- `xcodebuild -quiet -workspace SodaLive.xcworkspace -scheme SodaLive-dev -configuration Debug -destination 'generic/platform=iOS Simulator' -derivedDataPath "$RUN_TMP/simulator-build" CODE_SIGNING_ALLOWED=NO build` → 최종 exit 0.
|
||||
- 최초 simulator 빌드는 600초 제한으로 중단됐다. 캐시를 유지해 재개한 전체 컴파일이 BUILD-001을 발견했고, 타입 한정 수정 뒤 두 빌드가 성공했다.
|
||||
- 기존 SDK deprecated/Sendable 경고, 기존 중복 Sources 등록 경고, Firebase dSYM 설정 경고, DVTDeviceOperation 경고는 변경 범위 밖이다. 이번 작업에서 임의 수정하지 않았다.
|
||||
|
||||
최종 회귀 실행 목록(모두 exit 0):
|
||||
|
||||
| 스크립트 | 실행 모드 |
|
||||
|---|---|
|
||||
| check-app-deep-link-gift-detail.sh | 기본 |
|
||||
| check-auth-content-settings-exit.sh | 기본 |
|
||||
| check-auth-verification-mock.sh | 기본, 내부 Debug/Release 심볼 검사 포함 |
|
||||
| check-gift-address-search.sh | 기본, baseline |
|
||||
| check-gift-contact-input.sh | 기본 |
|
||||
| check-gift-decoding-contract.sh | 기본 |
|
||||
| check-gift-detail-cancel-loading.sh | 기본 |
|
||||
| check-gift-detail-talk-inquiry.sh | 기본 |
|
||||
| check-gift-phase11.sh | 기본 all, profile, policy, button |
|
||||
| check-gift-recipient-address.sh | 기본 |
|
||||
| check-received-gift-detail.sh | 기본 privacy, foundation, recipient-form, received-states |
|
||||
| check-user-creator-chat-date-presentation.sh | 기본, 113 assertions |
|
||||
|
||||
모든 스크립트는 `bash work/tests/이름.sh 모드`로 실행했다. 기본 모드는 인자를 생략했다. Auth 검사에 사용되는 HOME·CFFIXED_USER_HOME 및 compiler cache는 소유된 임시 폴더로 격리했다. 기존 스크립트/fixture21개는 기준선 단계 SHA-256 불변 확인, 최종 git diff에서도 변경 없음이다.
|
||||
|
||||
### 네이티브 증거 범위
|
||||
|
||||
- [캡처 매트릭스와 관찰값](evidence/README.md): 12개 PNG와 [원본 소스 해시](evidence/production-after.sha256)를 보존한다.
|
||||
- 실제 `UserCreatorChatDateSeparatorView`, formatter, 모델, `FontModifier`, 테마·간격, LanguageOption을 직접 컴파일했다. I18n shim은 사용하지 않는 언어 설정 이름 네 개뿐이다. 날짜 코드를 대체하지 않았다.
|
||||
- Native harness는 UIKit 윈도우에 SwiftUI를 올리고 `simctl io screenshot`으로 촬영했다. 원본 폰트 등록·날짜 프레임 폭327pt·3개 합성 메시지/2개 날짜 구분을 실행 중 확인했다.
|
||||
- 큰 영어 날짜는 두 줄로 확장하고, 한·일 날짜는 한 줄이다. 날짜 잘림·대체 글리프는 관찰되지 않았다. 실제 채팅 배경과 동일한 검정 배경을 light/dark 모두 유지한다.
|
||||
- 주변 메시지와 상단 QA 설명은 합성 UI다. 실제 RoomView의 bottom anchor, 페이지 추가, ACK 이동 및 VoiceOver 조작을 검증했다고 주장하지 않는다.
|
||||
- 이전 독립 코드/시각 리뷰는 코드 APPROVE 및 컴포넌트 한정 PASS였다. 최종 소스 해시와 불일치했던 초기 캡처는 최종 증거로 사용하지 않고 재촬영했다.
|
||||
- 재개 후 독립 검토는 새 캡처 12장에 실제 앱의 추적 권한 팝업이 남아 날짜가 가려진 증거 결함을 발견했다. 앱 프로세스 종료만으로 팝업이 사라지지 않아, 사용자가 아닌 이 작업 소유의 시뮬레이터에서 실제 앱을 제거하고 재부팅했다. 권한 허용을 임의 선택하지 않았다. 팝업 없는 영어 큰 글자 probe를 직접 확인한 뒤 같은 하네스의 12장을 모두 다시 촬영했다. 제품 소스는 추가 변경하지 않았다.
|
||||
- 최종 독립 재검토(`ses_eae4fc5c2ffe9q4b4Mh24gmGn7`): 수정된 PNG 12/12를 직접 다시 열고 모든 프레임의 두 날짜가 온전하게 보임을 확인해 컴포넌트 시각 PASS 판정. 잘림·말줄임·깨진 문자·고립 음절·합성 말풍선과의 겹침 없음. 잔여 시각 차단 사항과 제품 코드 수정 요구 없음. 실제 RoomView·paging·ACK·VoiceOver는 승인 범위 밖이다.
|
||||
|
||||
### 자원 정리
|
||||
|
||||
- 하네스 앱은 촬영 스크립트 종료 시 terminate했다. 실제 개발 앱은 팝업 복구 과정에서 작업 소유 시뮬레이터에서만 제거했다.
|
||||
- 소유된 simulator `809AF3D0-7644-4AF0-A773-4E0E487406A4`를 shutdown/delete한 뒤 custom set의 devices 목록에 기기가 없음을 확인했다. `pgrep -x NativeDateQA`도 프로세스 없음을 확인했다.
|
||||
- 최종 리뷰 결과와 캡처·검사 증거를 저장소에 보존한 뒤 작업 전용 `dm-run.OwYrK5` 전체(두 DerivedData, checker 캐시, 하네스 앱/스크립트, custom simulator set)를 제거했다. 경로 부재 검사 PASS, 관련 xcodebuild/swift-frontend/NativeDateQA 실행 프로세스 없음. 작업 메모도 삭제했다. 사용자 시뮬레이터·공유 캐시는 제거하지 않았다.
|
||||