257 Commits

Author SHA1 Message Date
songyc macbook
623217b907 fix(l10n): natural English word order for quest summaries + help refresh
- 전체 점검(코드 정독 + 폰·패드·워치 시뮬 검증)에서 발견된 번역·도움말 보완
- 다짐 요약 en 어순 수정: "30m Reach at least" → "Reach at least 30m" — 포맷 키 '%@ · %@ %@'의 en을 위치 지정자(%1$@ · %3$@ %2$@)로 재배열, ko/ja 불변
- 시리 다짐 엔티티 부제가 일반 보간이라 카탈로그를 안 타던 것을 String(localized:)로 교정 — 위젯 카탈로그에 같은 키 번역 추가
- 도움말 일기 항목에 달력 기분 사진 배경 안내 한 문장 추가 (ko/en/ja, stale 키 정리)
- CLAUDE.md §14: -premium 인자가 콜드 스타트 동안만 유효함(지속은 DEBUG 토글) 명시
- 검증: 9개 카탈로그 missing/stale 클린, 인텐트 스모크 10/10, progressSelfTest 37건 PASS, streak 덤프 정상, 3개 스킴(iOS Debug/Store·워치) 빌드 성공, en 목표 탭 스크린샷으로 어순 확인

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014CkLDi8Lr21vGqo4SjZaTp
2026-07-18 00:31:11 +09:00
songyc macbook
a400a71896 feat(ui): unify time wheels + diary calendar mood-photo backlayer
- 다짐 '마감 시각'·설정 '하루 시작 시간'의 컴팩트 시각 픽커도 RecordTimeWheel(시·분 전용)로 교체 — 기록 편집기와 같은 팝오버 커밋 유실 기전 제거, 앱의 시각 다이얼 전부 상시 노출 휠로 통일
- 일기 달력: 기분 사진이 있는 날짜는 셀 배경(백레이어)에 사진 썸네일 표시 — 이모지/연필 마커·오늘 표시는 그대로 위에 유지, 사진 없으면 기존과 동일. ImageIO ≤220px 축소 + NSCache(DiaryMoodThumbs)로 한 달치 렌더 부담 최소화, 검은 스크림 0.16+흰 날짜·마커 그림자로 가독성 확보
- 사진만 있는 엔트리는 hasContent가 moodImageData를 포함해 빈 엔트리 정리에서 보존됨(기존 로직 확인)
- 검증 인자 -diarySeedPhoto 신설(오늘=이모지+사진·어제=사진만) — iPad 시뮬 달력 스크린샷으로 백레이어·마커 확인, 마감 시각·하루 시작 시간 휠 스크린샷 확인
- l10n 무변화(기존 키 재사용, 카탈로그 클린). CLAUDE.md §6.5·§6.7·§14 갱신. Debug/Store 두 스킴 빌드 성공

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014CkLDi8Lr21vGqo4SjZaTp
2026-07-18 00:03:04 +09:00
songyc macbook
9825be505f fix(history): record time editing — always-visible wheel dials
- 기록 수정·추가 시트 4곳의 시각 입력을 컴팩트 팝오버에서 상시 노출 휠 다이얼(RecordTimeWheel)로 교체 — 팝오버 다이얼이 감속 중 닫히면 정착값이 바인딩에 반영되지 않던 실기기 보고 수정. 다이얼 = 표시 그 자체라 저장 전 재확인 불필요
- 종료 시각의 in: startAt... 범위 제약 제거 — 초 단위 하한 근처 선택을 소리 없이 되감던 스냅백 원인. 검증은 종료<시작 빨간 경고 + 저장/추가 버튼 비활성으로 대체 (숨은 보정 제거)
- 편집 상태 분 단위 절사(flooredToMinute) — 실측정 기록의 초 찌꺼기(14:32:47)로 다이얼상 1시간이 "59분"으로 표시되던 어긋남 수정. 저장은 화면 값 그대로
- 검증 인자 신설: -recordShowEditor session|count(기록 탭 최신 기록 수정 시트), -recordAddFor "이름"(모음 탭 기록 직접 입력 시트)
- l10n: 경고 문구 1키 ko/en/ja, 카탈로그 missing/stale 클린. CLAUDE.md §6.5·§14 갱신
- 검증: Debug/Store 두 스킴 빌드, 수정·추가·횟수 시트 시뮬 스크린샷, -progressSelfTest 37건 ALL PASS

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014CkLDi8Lr21vGqo4SjZaTp
2026-07-17 23:08:09 +09:00
songyc macbook
a881646b49 docs(claude): v2.2 — session handover refresh for a fresh start
- 문서 버전 v2.2(2026-07-17)로 갱신
- §1 현재 상태: 동결 이후 수정 라운드 전부(실기기 확인 완료 포함)·Marketing/ 자료 완비·사업자 등록/통신판매업 대기·버그 대응 루틴을 한 행으로 집약 — 새 세션이 이 행만 읽어도 현 시점 파악 가능
- §2.2: 마케팅 스크린샷용 시뮬레이터 4종 UDID 추가 + 운영 함정 2건 명시(xcodebuild 병렬 실행 시 위장 실패, install 직후 launch의 런치 인자 무시)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-17 21:14:15 +09:00
songyc macbook
c0aef1271c docs(marketing): framed promo screenshots (24) + compositor tool
- 홍보 문구 합성판 추가 — 브랜드 배경(웜 화이트→그린 그라데이션) + 헤드라인/서브 문구(ko/en/ja, 화면별 8종) + 골드 포인트 바 + 둥근 모서리 카드(그림자·헤어라인)로 합성. 캔버스는 ASC 규격 그대로(1320×2868 / 2064×2752)라 framed 세트를 바로 업로드 가능 — 원본 세트는 예비·재합성 소스로 유지
- Marketing/tools/frame_screenshots.swift — AppKit 기반 합성 도구(재현 가능): 문구·색 상단 정의, 텍스트는 폭 맞춤 자동 축소, 원본 재촬영 후 재실행만 하면 됨. 워치는 캔버스가 작아 원본 유지(관행)
- README: framed 우선 업로드 안내 + 문구 오버레이 규정 메모 + iPad 상태바 날짜(시뮬 시스템 언어) 알려진 티 기록

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-17 18:07:19 +09:00
songyc macbook
3ec7b43adc docs(marketing): Apple Watch screenshots (ko/en/ja) + capture recipe
- 워치 앱이 포함된 앱은 ASC에서 워치 스크린샷이 필수 — Series 11 46mm(416×496px) 규격으로 3개 언어 각 1장(앱 첫 화면: 측정 중 타이머·즐겨찾기·꼬리표) 추가
- 페어링 시뮬레이터의 빨간 '아이폰 연결 끊김' 상태바 아이콘 문제를 해결하는 촬영법 확립: 페어링 워치가 받은 스냅숏 캐시(App Group plist)를 비페어링 'MarketingWatch' 시뮬레이터에 종료 상태로 복사 후 부팅·촬영 (cfprefsd 캐시 주의, 아이폰 앱 삭제 시 워치 앱 동반 삭제 주의) — README에 절차 기록
- README: 폴더 구조·필수 슬롯에 워치 반영

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-17 02:29:57 +09:00
songyc macbook
e6fc272908 fix(l10n): unify Japanese app name to "Haru Danim" in 10 leftover spots
- 워치 스크린샷 촬영 중 발견: 워치 앱 제목 ja가 옛 표기 'ハルダニム' — 과거 결정(전 타깃 ja 앱 이름 = 'Haru Danim', InfoPlist는 이미 통일)과 어긋남
- 전수 스캔으로 카탈로그 4곳 총 10건 통일: 워치 앱 제목, 워치 컴플리케이션 '하루 다님' 헤딩, 잠금화면 위젯 inline 문구 2종(IOS·위젯 카탈로그 각각), 시리·제어 센터 도움말 본문 3건 — AppShortcuts의 ${applicationName} 해석(Haru Danim)과도 일치하게 됨
- 검증: 전 카탈로그 'ハルダニム' 0건, ja 워치 스크린샷에서 'Haru Danim' 표기 확인, Debug·Store·워치 빌드 성공

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-17 02:29:57 +09:00
songyc macbook
ba3c7d4cf2 docs(marketing): App Store submission kit — texts + 24 screenshots
- Marketing/AppStore: 앱 설명(ko/en/ja, 링크·자동 갱신 고지 포함)·키워드(100자 이내 검증)·프로모션 텍스트(170자 이내)·v1.0 새로운 기능·인앱 상품 3종 메타데이터+등록 체크리스트
- Marketing/Screenshots: 아이폰 6.9"(1320×2868, iPhone 17 Pro Max 심) × ko/en/ja × 4장(모음·목표·타임테이블·주간 통계) + 아이패드 13"(2064×2752, iPad Pro 13" M5 심) × ko/en/ja × 4장(모음·일기 달력·하루 정리·펜슬 노트) — 로케일마다 재설치·재시드, 상태바 9:41 오버라이드, en/ja 데이터 현지화 확인
- Marketing/README.md: 폴더 구성·ASC 붙여넣기 맵핑·스크린샷 재생성 절차·등록일 체크리스트 + **유지보수 규칙(앱 변경이 자료에 영향 주면 요청 없이 함께 갱신 — 사용자 지시)**
- CLAUDE.md: 프로젝트 구조에 Marketing/ 추가(동기화 규칙 명시), §14 시드 이름 로케일 추종 주의 기재

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-17 02:09:37 +09:00
songyc macbook
39027eeb4a chore(debug): localize demo seed names for locale marketing screenshots
- 데모 시드(-seedDemo·-diarySeed)의 행동·꼬리표·목표 이름과 메모·할 일을 String(localized:)로 — 마케팅 스크린샷을 en/ja 로케일로 찍을 때 한국어 데이터가 박히지 않게 (DEBUG 전용, ko 기본 동작 불변)
- 인텐트 스모크 테스트의 이름 조회도 현지화 경유로 바꿔 어느 로케일에서든 동작
- 신규 17키 en/ja 번역 완비 (카탈로그 783키 missing/stale 0), Debug·Store 빌드 성공

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-17 02:09:36 +09:00
songyc macbook
6f28add94d docs(claude): business registered — awaiting e-commerce report processing
- §1 현재 상태 갱신: 사업자 등록 완료, 통신판매업 신고 처리 대기(2~3일) — 처리 후 ASC 등록·유료 계약 진행 예정
- 동결 이후 진행된 버그 수정·현지화·워치 필터 라운드 요약을 상태 행에 반영

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-17 01:02:13 +09:00
songyc macbook
6880983b54 feat(watch): per-goal opt-in filter for complication list
- 목표 편집에 '애플워치에서 보기' 토글 추가 (iPhone 전용 — 워치가 iPhone과 페어링되므로 iPad에서는 숨김·무의미, 기본 꺼짐) — 목표·다짐이 늘면 컴플리케이션 목록이 폭증하는 문제의 옵트인 해법 (사용자 요청)
- 저장은 기기 로컬 LocalPrefs `local.watchGoals` (§15-3 노출 설정 원칙, pinnedGoals 선례) — CloudKit 스키마 무변경·페이로드 무변경으로 리스크 최소화
- 필터는 WatchSyncManager.makeSnapshot 한 곳: 스냅숏의 목표 = 진행 중 ∩ 체크됨 → 목록(recommendations)·표시 모두 자동 반영, 완료 목표는 기존 진행 중 조건으로 자동 제외. 행동·측정 중 상태(워치 앱 화면·현재 현황·iPad 기록의 동기화 경로)는 필터와 무관 — 지연 추가 0
- 검증(페어링 시뮬레이터 E2E): -watchGoals 1 → 워치 컴플리케이션에 토익 목표+영어 공부 다짐만 표시, -watchGoals 0 → '목표 없음'/'다짐 없음' 빈 상태로 우아하게 처리(크래시 없음), 현재 현황(독서 타이머)은 필터와 무관하게 정상 수신. 아이폰 편집기 토글 렌더 확인. Debug·Store·워치 3스킴 빌드 성공
- 도움말 컴플리케이션 항목 갱신 + 신규 문구 en/ja 완비(카탈로그 766키 클린), §14에 -watchGoals 인자, §5.2/§6.4/§11 문서화
- 주의: 기본 꺼짐이라 업데이트 직후 기존에 페이스에 올린 목표·다짐 컴플리케이션은 빈 상태가 됨 — 목표 편집에서 원하는 목표를 한 번 켜 주면 복구

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-16 23:48:59 +09:00
songyc macbook
2a176fa8a2 fix(quest): count scheduled days only for daily-quest spans + rest-day state
진행률 검증 보고에서 확정한 결정 반영 (사용자 위임):

- [계산 수정] 하루 단위 다짐의 주/월 집계를 **방향 무관 수행일 기록만** 합산 — 목표량(scaledTarget)이 수행일 수 환산인데 '이하 유지'만 비수행일 기록까지 값에 섞여 분모·분자가 어긋나던 비대칭 해소 (월수금 1시간 이하 다짐이 목요일 시청으로 한도 초과 표시되던 문제). atLeast의 하루 기여 캡·마감 창 클립은 기존 유지
- [표시 수정] 수행일 아닌 날(요일·날짜 다짐의 쉬는 날, 기간 밖 custom)의 '하루' 게이지를 '수행일 아님' 상태로 — 쉬는 날 기록은 주/월 집계에 안 잡히는 값이라 퍼센트(예 133%)로 보여주면 "오늘 채웠다"는 오해 유발. 목표 탭 행·모음 카드(문구+빈 바), 위젯 ③(문구·누적값 숨김)·②(— 대시)·④(링 흐림, 스냅숏 isRestDay), 시리 '오늘' 조회("오늘은 수행일이 아니에요") 공유. 워치·잠금화면 점은 공간 제약으로 수치 유지(문서화)
- [의도 확정·유지] atMost 하루 게이지의 환산 한도 페이스 경고 / 다짐 생성 이전 기록 인정 / 월 경계 주 혼입 / 적용일 없는 달 0% / custom 종료 후 게이지 — CLAUDE.md §4.2에 트레이드오프로 명시
- 검증: -progressSelfTest 37건 ALL PASS(E 비수행일 제외·M 비대칭 수정·N 기간 밖 판정 신규), 목표 탭 스크린샷(달리기 월수금: 하루 '수행일 아님'/주간 0%/월간 7%), 위젯 미리보기 렌더 무결, Debug·Store·워치 3스킴 빌드 성공
- 도움말 '진행률 읽는 법' 전면 보강(수행일 집계·페이스 캡·이하 유지 이분법+하루 경고) en/ja 완비, 신규 키 2종('수행일 아님', 시리 응답) IOS·위젯 카탈로그 클린(763/213키)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-16 22:59:15 +09:00
songyc macbook
3ae49faad7 fix(quest): cap prorated span display at 100% — weekly quest showed 350% daily
- 보고된 버그: 주 2회 다짐을 목요일에 1회 수행 → 목표 탭 하루 진행률 350% (1 ÷ 주목표 2/7). 주기와 다른 span의 환산 목표는 페이스 가이드일 뿐인데 초과분까지 퍼센트로 표기되던 왜곡
- 수정: spanProgress에서 '이상 달성'이면서 환산 목표 span일 때 값을 목표에서 캡 (usesScaledTarget 분기) — 자기 주기 span(하루 다짐의 '하루' 200% 등)과 특정 기간 다짐(환산 없음)은 초과 표기 유지, '이하 유지'는 값 무캡(UI 초과 판정·페이스 경고 유지). 게이지(ratio)·달성 판정·연속·목표 종료 판정은 원래 캡·별도 경로라 무영향 — 바뀌는 것은 퍼센트 문구뿐
- 검증 도구 신설: -progressSelfTest (DEBUG) — 인메모리 컨테이너에 12시나리오·33검증(보고 케이스, 주간/월간/요일 스케줄/마감/atMost/특정 기간/잔존 deadline/무기록 + 목표 합산 회귀) 구성해 손계산 기대값과 대조, ALL PASS. 설정·날짜 고정이라 언제 실행해도 동일 판정
- 화면 확인: 목표 탭 '꾸준한 달리기'(주 2시간) 하루 233%→100%, 주간 67%·월간 30% 유지, 매일 다짐 117%/133%(자기 주기)·atMost·마감 다짐 표기 불변
- 도움말 '진행률 읽는 법'에 페이스 기준 설명 추가(en/ja 완비), CLAUDE.md §4.2 규칙·§14 인자 기재
- §2.3 l10n 루틴 강화: stringsdata를 Objects-normal/arm64로 한정 — x86_64·Release 등 낡은 구성 파일이 수정 전 문구를 계속 추출시키는 오염 발견·수정

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-16 22:35:23 +09:00
songyc macbook
bdc771455b feat(l10n): localize CSV header row per language
- CSV 열 이름도 언어별 현지화 (파일명 현지화 b17a199의 후속, 사용자 결정) — 스프레드시트에서 열 이름은 곧 UI. 값의 rawValue(time/count, inProgress 등)는 데이터라 언어 무관 유지
- 기존 키 최대 재사용(이름/시각/수량/메모/방향/종료일/꼬리표/즐겨찾기/시작/종료 + '추적 방식' — ko 헤더만 '추적방식'→'추적 방식'으로 공백 하나 추가됨), 신규 10키(행동id/만든날/초/내용/시작일/상태/달성기준%/대상/주기/목표량) en/ja 완비 — 카탈로그 761키 missing/stale 0
- 검증(시뮬레이터 실헤더): en "id,Name,Tracking type,Tags,Favorite,Created" 등 5파일, ja "id,名前,計測方式,タグ,お気に入り,作成日" 등 5파일, ko 회귀 정상. Debug·Store 빌드 성공

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-16 10:28:53 +09:00
songyc macbook
b17a199b53 feat(l10n): localize export file names per language
- 내보내기 파일명을 언어별로 현지화 — 수신 환경(PC·클라우드·메일)이 한글 파일명을 지원하지 않을 수 있음 (사용자 결정). ko는 기존 그대로("하루다님-기록-…"), en/ja는 라틴 접두 "HaruDanim-" + 그 언어의 종류 단어 (History/記録, Diary/日記, Stats/統計, Actions/アクション 등)
- 대상 전부: 기록·통계 리포트 PNG(ExportSnapshot.fileName + 슬러그 3종), 일기 PDF·스티치 PNG(슬러그 3종 포함), CSV 5종(행동·목표·다짐은 기존 키 재사용, 시간기록·횟수기록 신규 키). CSV 헤더는 데이터로 보고 한국어 유지
- 카탈로그 신규 11키 en/ja 완비(751키 missing/stale 0), CLAUDE.md §7에 규칙 기재
- 검증(시뮬레이터 실파일명): en CSV 5종 "HaruDanim-Actions/TimeRecords/CountRecords/Goals/Quest.csv", en 리포트 "HaruDanim-History-2026-07-16.png", iPad en 일기 "HaruDanim-Diary-2026-07-15~2026-07-16.pdf"(기간 슬러그), ko 회귀 "하루다님-행동.csv" 등 5종 그대로. Debug·Store 빌드 성공

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-16 10:22:01 +09:00
songyc macbook
4e07a90a1b fix(l10n): translate 독서 sample in watch-app catalog too
- 컴플리케이션 뷰(StatusComplication.swift)는 미리보기용으로 워치 앱 타깃에도 포함되어, placeholder 지역화(fced5d1) 때 워치 앱 카탈로그에도 '독서' 키가 추출됨 — 워치위젯 카탈로그만 채우고 이쪽을 놓쳤던 것 보충 (en Reading / ja 読書, 동일 값)
- xcstringstool sync로 포맷 정규화, 워치 카탈로그 49키 missing/stale 0, 워치 빌드 성공

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-16 09:08:13 +09:00
songyc macbook
df6c03e18c fix(widget): NowRunning stop button opened the app instead of stopping
- ⑥ 현재 진행 중 위젯의 종료 버튼 탭이 인텐트 대신 앱 열기로 새던 원인 = 버튼 라벨(정지 아이콘)에 붙어 있던 invalidatableContent() — §10에 문서화된 금지 패턴(invalidatable 래스터 서브트리는 별도 레이어로 분리돼 Button(intent:) 히트 영역에서 빠짐, ③ 링 실기기 버그와 동일 기전)을 이 버튼만 어기고 있었음
- 아이콘의 invalidatableContent() 한 줄 제거 (외형·레이아웃 불변) — 탭 접수 깜빡임 피드백은 바로 옆 타이머 텍스트의 invalidatableContent가 기존대로 담당(①③과 같은 패턴). 소형·중형 대표 카드·대형 나열 행 모두 같은 NowRunningStopButton이라 한 번에 수정
- CLAUDE.md §10 경고문에 ⑥ 재현 사례 병기
- 검증: Debug·Store·워치 3스킴 빌드 성공, 위젯 미리보기 렌더 수정 전과 동일. 히트 영역 자체는 홈 화면 UI라 실기기 탭 확인 필요

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-16 09:06:18 +09:00
songyc macbook
232e8c504d fix(watch): list every goal & quest in complication recommendations
- 페이스 편집기에 3번째 목표부터(다짐은 첫 목표의 2개까지만) 안 뜨던 원인 = recommendations()의 prefix(2) 하드캡 — 워치는 컴플리케이션 파라미터 편집 UI가 없어 추천 목록이 곧 선택지의 전부라, 캡에 걸린 목표·다짐은 페이스에 추가할 방법 자체가 없었음 (보고된 13개 = 현재현황 1 + 목표 2×3기간 + 다짐 2×3기간과 정확히 일치)
- 목표·다짐 달성률 둘 다 상한 제거: 진행 중 목표 전부 × 3기간, 다짐 전부 × 3기간 나열
- 워치 앱이 스냅숏을 적용할 때 invalidateConfigurationRecommendations() 호출 추가 — 이후 아이폰에서 목표를 새로 만들어도 시스템 임의 재조회를 기다리지 않고 목록에 자동 반영
- CLAUDE.md §11에 "추천 목록 = 선택지 전부, 상한 금지" 규칙 명시
- 검증: 워치·Debug·Store 3스킴 빌드 성공, 워치 심 -complicationPreview 렌더 정상 (추천 목록 자체는 페이스 편집 UI라 헤드리스 확인 불가 — 실기기 확인 필요)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-16 05:33:15 +09:00
songyc macbook
fef25f30d0 docs(claude): future-dated records excluded from streaks is intended
- §6.4 연속 달성에 명시: 미래 시각 기록(수동 입력)은 진행률·게이지에 즉시 반영되지만 연속 계산은 now까지만 집계 — 선기록으로 연속이 미리 쌓이지 않게 하는 의도된 동작(사용자 결정, 고치지 말 것)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-16 02:53:44 +09:00
songyc macbook
fced5d1958 fix(l10n): localize widget/complication placeholder sample labels
- placeholder()의 생 한국어 리터럴 6곳을 String(localized:)로: ③다짐 링·④다짐 현황·잠금화면 위젯의 spanLabel "오늘"(기존 키 재사용), 워치 목표/다짐 달성률 "목표"/"하루"(기존 키 재사용), 워치 현재 현황 샘플 "독서"(워치위젯 카탈로그 신규 1키 — en Reading/ja 読書, iOS 위젯 카탈로그와 동일 값)
- placeholder는 갤러리/로딩 스켈레톤 전용 경로라 타임라인 예산·버튼 반응성·갱신 경로 무영향 — ①⑤ 위젯 placeholder가 이미 쓰던 패턴과 동일
- 검증: Debug·Store·워치 3스킴 빌드 성공, 전 카탈로그 missing/stale 0

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-16 02:53:43 +09:00
songyc macbook
2b6ca94f09 docs(help): add short-session-ignore and note-prompt topics
- 모음 탭 그룹에 도움말 2개 추가: '짧은 기록 무시'(측정 시작·종료 다음 — 3초~1분 기준, 위젯·워치·시리 종료에도 적용됨을 안내), '기록에 메모 남기기'(길게 누르기 메뉴 다음 — 행동별 토글·건너뛰기·기기 로컬 저장·기록 탭 노란 표시·수정 시 메모 편집 안내)
- 새 문자열 3키 en/ja 번역 채움 (설정 항목명은 기존 카탈로그 번역 'Ignore short sessions'/'Show note prompt when recording' 그대로 인용, 제목 '짧은 기록 무시'는 기존 키 재사용)
- 검증: -helpPreview ko/en 스크린샷 — 두 주제 모두 의도한 위치에 렌더

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-16 02:53:43 +09:00
songyc macbook
0c87375d53 docs(claude): add missing -widgetRenderMode arg + seedDemo streak precondition
- §14 설정/기타 행에 코드에는 있으나 표에 빠져 있던 -widgetRenderMode accented|vibrant 보충
- §14 seedDemo 기대값(아침 루틴 연속 1일)에 실행 시각 전제 명시 — 시드 기록이 고정 시각이라 오전 7:30 이전 실행 시 연속 0일이 정상 (전수 점검 중 새벽 실행에서 확인)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-16 02:38:05 +09:00
songyc macbook
7a6731a1f5 fix(l10n): wrap four raw Korean literals missed by catalog extraction
- 기록 탭 목록의 진행 중 세션 표기 "진행 중"이 문자열 보간 안 String 리터럴이라 영어·일본어 UI에 한국어로 노출되던 것 수정 — String(localized:)로 기존 카탈로그 키 재사용 (시뮬레이터 en "In progress" / ko "진행 중" 스크린샷 검증)
- 같은 패턴 3곳 동일 수정: 꼬리표 편집 미리보기 행 "미리 보기"(String 삼항), 시리 다짐 엔티티 부제 "목표 없음"(?? 폴백), 워치 행동 목록 제목 "꼬리표 없음"(String 파라미터) — 전부 기존 번역 키 재사용이라 카탈로그 변경 없음(xcstringstool sync 무변화 확인)
- 검증: Debug·Store·워치 3스킴 빌드 성공, 시리 인텐트 스모크 테스트 10/10, streak-dump 수치 손검산 일치

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-16 02:38:05 +09:00
songyc macbook
063a7a2d7f docs(claude): record release-freeze status + watch simulator UDIDs
- §1에 '현재 상태 (2026-07-16)' 행 추가 — 기능 동결, RC 커밋 f05e611, 실기기 이상 없음, 사업자 승인 대기
- §2.2 자주 쓰는 시뮬레이터에 워치 UDID 2종(watchOS 11.5 / 26.2) 기재
- 문서 버전 v2.1 (2026-07-16)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-16 02:12:56 +09:00
songyc macbook
f05e6113a1 chore(release): privacy manifests for all 4 bundles + lower minimum OS to 26.0/10.0
유료 앱 출시 패키지 점검에서 발견한 두 가지 보완:

1) PrivacyInfo.xcprivacy 추가 (iOS 앱·위젯 확장·워치 앱·워치 위젯 확장) —
   required-reason API 선언(ITMS-91053 대응): UserDefaults 카테고리에
   CA92.1(앱 자체 설정) + 1C8F.1(App Group 공유), 수집 데이터·트래킹 없음
   (ASC '데이터 수집 안 함' 선택과 일치). 파일 타임스탬프·부팅 시간·디스크
   용량·키보드 목록 API는 전수 grep으로 미사용 확인. 앱 타깃이 위젯 폴더를,
   워치 앱 타깃이 워치위젯 폴더를 동기화(미리보기 화면용)하고 있어 매니페스트가
   이중 복사되던 충돌은 membershipException 2건으로 해소 — 번들마다 자기
   매니페스트 1개씩 포함됨을 빌드 산출물로 확인.

2) 배포 타깃 하향: iOS/iPadOS 26.5 → 26.0 (리퀴드 글라스 glassEffect가 26.0
   하한이라 그 이상 낮출 수 없음), watchOS 26.0 → 10.0. 컴파일러 availability
   검사가 오류 0건으로 통과 = 해당 버전 지원 보증. 검증: Debug·Store·워치 스킴
   빌드 성공, MinimumOSVersion 각인(26.0/10.0) 확인, watchOS 11.5 시뮬레이터
   실기동(기존 최소치로는 설치 불가였던 OS) + 26.2 시뮬레이터 실기동, 아이폰
   시뮬레이터 부팅 확인. Series 4·5·SE(1세대) 등 watchOS 10~11 워치 사용자와
   iOS 26.0~26.4 기기가 지원 범위에 들어옴.

CLAUDE.md §1에 최소 OS와 매니페스트 완비 상태 기록.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-15 19:05:09 +09:00
songyc macbook
6738fe4b7e docs(claude): watch verification route + widget ③ deadline-value note
출시 전 최종 점검에서 발견한 문서 어긋남 정리:
- §2.1/2.2: 워치·위젯 개별 스킴 존재 명시 + 워치 UI 검증 방법(워치 스킴 →
  watchOS 26 시뮬레이터 + -complicationPreview) 추가 — 이번에 실제 검증한 경로
- §10 ③: 누적값 라벨 설명에 마감 시각 다짐의 창 안 값(spanRawValue) 예외 반영

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-15 18:48:49 +09:00
songyc macbook
01399afa2c chore(debug): -questShowEditor launch arg — open quest editor headlessly
다짐 편집기를 여는 검증용 런치 인자 추가 (DEBUG 전용, §14 관례).
마감 시각이 있는 다짐을 우선 열어 새 마감 UI(토글·시간 선택·footer)의
스크린샷 검증이 CLI로 가능해진다. 없으면 첫 다짐의 편집기를 연다.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-15 18:26:58 +09:00
songyc macbook
6a486a4fbd feat(quest): daily quest deadline time — clip the day's measurement window
하루 단위 다짐에 '마감 시각까지만 집계' 옵션 추가 (최소판 설계):

- 모델: Quest.deadlineMinutes(-1=없음) 필드 1개 — CloudKit 안전(기본값), 주기가
  하루 단위가 아니면 값이 남아도 무시(hasDeadline이 주기·범위를 함께 검사)
- 의미론: 마감 = 그날 집계 창의 끝. dayMeasurementRange(forKey:) 단일 구현을
  주기 범위(current/judgment)·주/월 span 하루 루프(spanValue)·연속 버킷팅
  (perDayValues)·위젯 누적 라벨(spanRawValue)·일기 카드가 공유한다.
  원본 기록은 불변 — 마감 뒤 기록은 남되 그 다짐에만 미집계. 시간형은 기존
  겹침 클리핑이 마감을 걸친 세션을 부분 인정(추가 코드 0). '이하 유지'는
  마감까지 한도 안이면 그날 달성으로 고정.
- 경계 규칙: 마감은 그 논리적 하루(24h) 안에서 그 시계 시각의 등장 지점 —
  하루 시작보다 이른 시각은 다음 달력일 새벽, 시작과 같은 시각은 +24h(온전한
  하루)로 0길이 창이 수학적으로 불가능(에디터 검증 불필요, 오류 상태 없음)
- 의도된 최소화: '마감 지남' 전용 표시 없음(게이지 값이 마감 시점에 연속이라
  위젯 타임라인 마감 경계 불필요 — 위젯·워치·시리는 코드 변경 0으로 자동 일관),
  연속 달성은 값 클리핑만(오늘 놓친 끊김 반영은 내일부터 — 유예 규칙 유지),
  주간/월간/기간 마감은 미지원
- UI: 다짐 에디터 토글+시간 선택(하루 단위만, footer 설명), 주기 문구에
  "· 오전 8:00까지" 표기(목표 탭·시리 요약·CSV 자동 반영), 일기 카드
  "하루 목표 · 오전 8:00까지", 도움말 항목 추가, ko/en/ja 번역
- 검증: seedDemo에 마감 다짐 시드(창 안/밖/어제 실패 케이스) — 하루 100%
  (창 밖 기록 포함 시 200%가 되는 함정 통과), 주간 29%(=2/7)·월간 6%(=2/31)
  수기 계산과 정확 일치, streak-dump 연속 1일(어제 실패로 끊김) 확인,
  마감 없는 다짐 전부 기존 수치 유지(경로가 hasDeadline 가드로 완전 동일),
  일기 카드 1회/1회(원본 합계는 그대로), 영어 로케일 "By 8:00 AM" 렌더,
  Debug·Store 빌드 성공, 카탈로그 9종 missing/stale 0

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-15 17:52:18 +09:00
songyc macbook
b399ee02fe refactor(history): unify calendar popover date mapping with startOfDay-as-key rule
기록 탭 달력 팝오버의 선택일 변환을 정오 경유(dayKey(for: 12:00))에서
"선택 달력일의 startOfDay를 키로 직접 사용"으로 통일 — 일기 내보내기 수정과
같은 규칙(CLAUDE.md §4.1). 현실적 설정(하루 시작이 자정~오전)에서는 동작이
완전히 동일하고, 하루 시작이 오후로 설정된 엣지에서만 전날로 밀리던 것이
고른 날짜 그대로로 바로잡힌다. 이로써 정오 매핑 패턴은 코드에서 사라짐.

검증: 하루 시작 00:00/06:00/18:00 수치 비교(앞 둘 동일, 18:00만 7/14→7/15로
교정), Debug·Store 빌드 성공, 기록 탭 렌더 확인.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-15 16:21:05 +09:00
songyc macbook
28e649c2de chore(git): untrack Expiranner xcuserdata (already gitignored)
루트 .gitignore의 **/xcuserdata/ 규칙보다 먼저 커밋돼 계속 추적되던
Expiranner의 Xcode 사용자 상태 파일(UserInterfaceState.xcuserstate,
xcschememanagement.plist)을 인덱스에서만 제거 — 로컬 파일은 유지되고
이후 변동이 git status에 잡히지 않는다.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-15 16:07:46 +09:00
songyc macbook
05b2d392c8 fix(diary): calendar month drift + export date picks off-by-one at custom day start
'하루 시작 시간'이 자정보다 늦게 설정된 경우의 논리적 하루 경계 버그 2건:

- 달력: monthAnchor(자정 키)를 monthRange(containing:)에 그대로 넣어
  매달 1일에 이전 달 그리드가 그려지고 헤더(현재 달)와 불일치했다.
  키를 dayRange(forKey:).lowerBound로 실제 시각으로 변환해 전달
  (기록·통계 탭이 쓰는 기존 패턴). monthSummary 카운트도 동일 수정.
- 내보내기: '날짜 지정'(MultiDatePicker)의 선택일(자정 Date)을 dayKey(for:)에
  넣어 전날 일기가 내보내졌다. DiaryEntry.dayKey가 "달력일의 자정"이므로
  선택 달력일의 startOfDay를 키로 직접 사용 — 하루 시작 시간이 몇 시든 안전.
  '구간 지정'도 같은 원리로 통일(표시된 달력일 = 내보내는 일기 날짜 보장).

CLAUDE.md §4.1에 재발 방지 규칙 추가: 자정 키를 dayKey(for:)/~Range(containing:)에
재투입 금지, 달력 UI 선택일은 startOfDay를 키로 직접 사용.

검증: 하루 시작 00:00/06:00/18:00 전부 수치 검증(수정 전 06:00에서 이전 달·전날
재현 확인), Debug·Store 빌드 성공, iPad 시뮬레이터에 하루 시작 06:00 주입 후
달력(7월 헤더·그리드 일치, 마커 2건)과 내보내기 시트("일기를 쓴 날 2일") 확인.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-15 16:07:05 +09:00
songyc macbook
3f518aa91b chore(l10n): purge stale catalog entries + per-target stringsdata sync routine
전체 코드 점검 중 발견한 번역 카탈로그 정리:
- IOS 카탈로그의 stale 항목 2건 삭제 — "다른 행동 %lld개도 함께 추적 중"은
  위젯 타깃 전용 문자열(위젯 카탈로그에 번역 완료 상태로 존재)이고,
  "프리미엄 상태 (테스트)"는 DEBUG 전용 문구
- DEBUG 프리미엄 토글 라벨을 Text(verbatim:)으로 — 개발용 문구는 카탈로그로
  추출하지 않는 컨벤션(§15-6)에 맞춤 (같은 섹션의 다른 문구와 동일)
- CLAUDE.md l10n 루틴 수정: 카탈로그마다 자기 타깃의 stringsdata만 sync하도록
  경로 필터 추가 — 전 타깃을 한꺼번에 넣으면 위젯 전용 문자열이 IOS 카탈로그에
  미번역으로 재유입되던 오염의 근본 원인 제거 (이번 stale의 발생 경로)

검증: 전 카탈로그(9개) missing/stale 0건, 카탈로그 의미 diff = stale 2건 삭제뿐
(번역 변경 없음), Debug·Store 스킴 빌드 성공

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-15 15:52:10 +09:00
songyc macbook
aa1c098d98 chore(l10n): Xcode re-save of string catalog — formatting + stale marks
- 키 정렬/공백 스타일 정규화 (Xcode 자동 재저장)
- 미사용 문자열 2건에 extractionState: stale 표시
- 번역 내용 추가/삭제 없음

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 02:56:13 +09:00
songyc macbook
3067877d37 fix(diary): make full template row tappable in page chooser sheet
페이지 추가 시트의 '내 양식' 목록에서 한 쪽짜리 양식(사진·1쪽 PDF) 행이
왼쪽(썸네일·이름)만 눌리고 오른쪽 절반은 반응하지 않던 문제 수정.
DiaryTemplateRowLabel이 내용물 폭만 차지해 plain 버튼의 contentShape도
그 좁은 라벨에만 적용됐던 것 — 라벨을 frame(maxWidth: .infinity)로 행
전체 폭으로 넓힌 뒤 contentShape(Rectangle())를 적용해 행 어디를 눌러도
동작하게 했다. 여러 쪽 PDF 행(NavigationLink)은 원래 전체 폭이 눌려
변경 없음.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-15 01:48:09 +09:00
songyc macbook
1e50485537 fix(widget): quest ring tap dead zone — drop invalidatableContent from shape subtree
③ 다짐 진행률 위젯에서 링·중앙 아이콘 영역을 누르면 인텐트 대신 앱이
열리던 실기기 버그 수정. 원인은 링 ZStack(도형+아이콘)에 붙인
invalidatableContent() — invalidatable로 표시된 래스터 서브트리는 별도
레이어로 분리되며 Button(intent:)의 히트 영역에서 빠져, 셀 단위
contentShape(.rect)로도 살아나지 않는다. 정상 동작이 확인된 ① 위젯과
같은 패턴(텍스트 값에만 invalidatableContent)으로 통일하고, 탭 접수
피드백은 퍼센트·누적값 줄이 계속 담당한다. CLAUDE.md §10에 도형·아이콘
ZStack 금지 규칙 추가.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-15 01:42:36 +09:00
songyc macbook
9c9c24f7df feat(a11y): VoiceOver labels for icon-only buttons + combined action-cell narration
접근성 감사 ③ — 전 화면의 아이콘 전용 버튼과 텍스트 없는 시각
요소에 보이스오버 라벨 부여 (시각 UI 변화 없음):

- 모음 탭: 행동 버튼 셀을 label(이름)+value(측정 중/오늘 누적)로
  한 덩어리 낭독 — 아이콘·타이머가 따로 읽히지 않음. 진행 중 행의
  정지 버튼 "측정 종료".
- 기록 탭: 날짜 이동 화살표(이전/다음 날짜), 내보내기, 기록 필터,
  필터 칩 해제 버튼. 타임테이블의 색 블록·횟수 점은 "행동 이름 +
  시각(구간)" verbatim 라벨로 낭독 가능하게.
- 통계 탭: 기간 이동 화살표(이전/다음 기간), 내보내기, 통계 필터,
  필터 해제.
- 행동/꼬리표/목표 탭: + 추가 버튼(행동/꼬리표/목표 추가), ⋯ 메뉴.
- 일기: 달 이동 화살표(이전/다음 달), 내보내기, ⋯ 메뉴, 기분 타일
  ("오늘 기분"), 할 일 삭제 버튼.
- ⑥ 현재 진행 중 위젯: 종료 버튼 "측정 종료".
- CLAUDE.md §15에 컨벤션 추가: 아이콘 전용 버튼 accessibilityLabel
  필수, 복합 셀은 label+value 한 덩어리, 텍스트 없는 시각 요소는
  verbatim 라벨.

신규 문구 9종 ko/en/ja 번역 + 위젯 카탈로그 '측정 종료' 번역 복사
(전 카탈로그 missing 0/stale 0). Debug·Store 빌드 성공, 접근성
수식어는 시각 렌더링에 영향 없음(스모크 런치 확인). 실기기에서
보이스오버 켜고 핵심 흐름(행동 시작/종료·날짜 이동) 낭독 확인 권장.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 22:24:21 +09:00
songyc macbook
747aab109d perf(history,stats,diary): range-bounded queries + one-pass stat buckets; declare encryption exemption
배포 잔여 ①-(2) + 성능 백로그 ② 처리:

1) ITSAppUsesNonExemptEncryption=NO (IOS/Info.plist)
   OS 표준 암호화(HTTPS·iCloud)만 사용 — 면제 선언으로 업로드마다
   뜨는 수출 규정 질문 생략. 빌드 산출물 plist에서 키 확인.

2) 기록·통계·일기 기록 조회를 날짜 범위로 제한 (전량 로드 제거)
   예전에는 4개 화면(기록/통계/일기 요약/일기 내보내기)이 모든
   TimeSession·CountEntry를 @Query로 올려 메모리에서 걸렀다 —
   기록이 수만 건으로 쌓이면 탭 진입·날짜 이동이 느려지는 구조.
   - HistoryRecordsView 신설: 선택 날짜가 속한 '주' 범위만 조회
     (목록·타임테이블 두 모드를 한 쿼리로 커버). 하루 경계 걸침·
     진행 중 세션은 "시작 < 범위끝 AND (종료 없음 OR 종료 > 범위
     시작)" 겹침 조건으로 포함. 날짜가 바뀌면 새 조건으로 재생성
     (SwiftData 동적 쿼리 패턴). 내보내기 시트도 이 범위 데이터 사용.
   - StatsChartsView 신설: 기간(하루/주/월) 범위 조회 + **1회 버킷
     집계**(StatsData) — 조회된 기록을 splitByDay로 한 번만 순회해
     행동별·하루별 버킷을 만들고 모든 카드(꺾은선·막대·표·꼬리표
     집계)가 공유. 카드마다 Aggregator로 전체 기록을 재순회하던
     O(카드×행동×기록) 비용 제거. 집계 규칙은 기존과 동일.
   - DiarySummaryPage: 해당 날짜 범위만 조회하는 init 추가.
   - DiaryExportSheet: 전량 @Query 대신 렌더 대상 날짜별 on-demand
     fetch로 전환.

3) -seedBulk DEBUG 인자 신설: 과거 500일 약 1만 건(세션 2,032 +
   횟수 8,039 실측) 생성 — 규모 검증용.

검증: 변경 전/후 스크린샷 비교 — 주간 타임테이블(자정 걸침 세션
포함)·월간 통계 차트가 픽셀 단위 동일(집계 등가성), 벌크 1만 건
상태에서 월간 통계 즉시 렌더 + 벌크 시리즈 정상 표시. Debug·Store
빌드 성공, 카탈로그 missing 0/stale 0(신규 문구 없음). CLAUDE.md
§1·§6.5·§6.6·§14 갱신.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 22:07:16 +09:00
songyc macbook
09d0b86ebc feat(premium): privacy policy + terms links on the paywall (review guideline 3.1.2)
배포 잔여 ①-(1) 처리 — 자동 갱신 구독 심사 필수 요건:

- Docs/PRIVACY.md 신설: 개인정보처리방침 ko/en/ja 3개 국어.
  핵심 내용 — 개인정보 수집 없음(서버·계정·광고·분석 SDK 없음),
  모든 데이터는 기기 + 사용자 본인의 iCloud 비공개 DB에만 저장
  (개발자 접근 불가), 결제는 App Store 처리, 권한(캘린더·사진·
  알림) 용도 명시, 데이터 삭제 방법, 문의처 songyc.eng@gmail.com.
  → github.com/notalentprogrammer/HaruDanim 저장소 main 브랜치에
  PRIVACY.md로 업로드하면 앱에 박힌 링크가 활성화된다.
- 결제 화면(PremiumView)에 '약관과 정책' 섹션 추가:
  개인정보처리방침(위 GitHub URL) + 이용약관(Apple 표준 EULA —
  커스텀 EULA 미제공 시 자동 적용되는 표준 계약으로 갈음, 3.1.2 허용).
  외부 링크 화살표 표시, 신규 문구 4종 ko/en/ja 번역.
- CLAUDE.md §1 배포 잔여 갱신 (남은 코드 측 작업은
  ITSAppUsesNonExemptEncryption 1건, ASC 등록 시 앱 설명에도
  두 링크 기재 + 앱 개인정보 보호 '데이터 수집 안 함' 선택 메모).

검증: Debug·Store 빌드 성공, iPad 시뮬레이터 결제 화면에서
섹션·링크·푸터 표시 확인. 카탈로그 missing 0 / stale 0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 21:43:04 +09:00
songyc macbook
fd4e198fe4 fix(goal,diary): pro-rated mid-period judgment, day-key edge, template render retries
재분석에서 나온 잔여 항목 일괄 처리:

1) 판정 하루 키 엣지 (A)
   judgmentReference가 종료일 '정오'를 경유해 논리적 하루를 찾던
   것을 달력일 키 직접 조회로 변경 — '하루 시작 시간'을 12시 이후로
   설정한 경우에도 판정 범위가 전날로 밀리지 않는다.

2) 주기 중간 종료 판정 (B — 설계 결정: 경과일 비례)
   종료 판정 전용 QuestProgress.judgment(asOf:) 신설, 판정 평균
   (questAchievementRatio)이 current() 대신 사용:
   - 값은 기준 시점까지의 누적으로 제한 — 종료일 이후 같은 주기의
     기록이 판정에 섞이지 않음
   - 주간/월간/특정 기간 다짐의 목표량·한도를 주기 내 경과일 비율로
     축소 — 수요일에 끝나는 목표의 주간 다짐이 남은 4일치 미달로
     깎이지 않고, '이하 유지' 한도도 같은 비율이라 대칭적으로 공정
   - 하루 단위 다짐은 축소 없음 (그날 목표는 온전히 채워야 달성)
   - 수동 종료(manualFinish)도 같은 함수를 타므로 주중 수동 종료의
     주간 다짐이 공정하게 판정됨. 표시 연산(combinedSpanRatio·
     spanProgress)은 불변.
   검증: 주간 2시간 다짐 목표를 주 시작일(월)에 종료 →
   화요일 기록 40분이 배제되고 비례 목표(≈17분) 기준으로 판정됨을
   DB에서 확인 (처음 실패는 '설치 직후 첫 실행 인자 무시' 시뮬레이터
   특성이 원인 — 코드 문제 아님, §2.2 문서화된 사항).

3) 양식 렌더 트레이드오프 (C)
   - 백그라운드 렌더 실패 시 renderedScale을 되돌려 다음 기회(줌·
     재표시)에 재시도되게 함
   - 썸네일 겸 첫 표시 플레이스홀더 해상도 320→512px — 본 렌더
     도착 전의 흐릿함 완화 (저장 증가는 수십 KB 수준)
   - 양식 관리의 사용 중 페이지 수를 행마다 재스캔하지 않고 1회 집계

빌드: Debug·Store·워치 3스킴 성공. CLAUDE.md §4.3에 주기 중간
종료 판정 규칙 추가. 신규 사용자 문구 없음(카탈로그 변경 없음).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 20:13:09 +09:00
songyc macbook
f70e6a1c06 fix(goal,watch,diary): judge goals as of their end date + watch l10n + template render polish
전체 재분석에서 확정한 4건 + 양식 개선 2건:

1) 목표 자동 판정 기준 시점 (핵심 수정)
   기존에는 판정이 "실행되는 시점의 현재 주기" 기준이라, 종료일
   며칠 뒤에 앱을 열면 목표 기간 밖의 데이터로 달성/미달성이
   갈렸다. 이제 자동 판정(evaluateIfEnded)은 **종료일이 속한
   논리적 하루의 마지막 순간**(judgmentReference) 기준 — 늦게
   실행해도, 종료일을 과거로 고쳐도 종료일까지의 기록으로 판정.
   (하루 시작 시간 설정으로 기준이 미래가 되는 경우 now로 상한)
   수동 종료는 종료일 없는 목표 전용이므로 기존대로 "지금" 기준.
   목표 편집 시 종료일 변경 처리: 진행 중 목표는 저장 즉시 판정,
   완료된 목표의 종료일을 바꾸면 '진행 중'으로 재개 후 재판정
   (미래/없음 → 진행 중 복귀, 다른 과거 날짜 → 그 시점 기준 재판정).
   검증: -endGoalYesterday로 어제 종료 → 종료일 기준 '달성' 판정 확인.

2) 워치 컴플리케이션 지역화 2건
   - 다짐 달성률 rectangular의 기간 라벨("하루/주간/월간")이 String
     파라미터라 미추출 → en/ja에서 한국어 노출 → String(localized:)
   - 빈 상태 문구("목표 없음"/"다짐 없음") 동일 문제 → 추출 + 워치
     앱/워치 위젯 카탈로그에 en/ja 번역 추가 (타깃별 stringsdata로
     sync — 카탈로그 오염 없음, 전 카탈로그 missing 0)

3) 배포 체크리스트: CloudKit 프로덕션 스키마 배포 항목을 CLAUDE.md
   §1에 추가 (DiaryTemplate 등 새 레코드 타입은 출시 전 대시보드
   Deploy Schema to Production 필수)

4) 일기 양식 렌더 개선
   - 첫 렌더 비동기화: 저장된 썸네일을 플레이스홀더로 즉시 깔고
     본 렌더(2×)를 백그라운드로 — 복잡한 벡터 PDF도 페이지 넘김이
     걸리지 않음
   - 비활성 페이지 고해상도 강등: 화면 밖 페이지는 래스터를 2×로
     상한(allowsHighResolution) — TabView가 이웃 페이지를 유지해도
     양식 여러 장의 메모리 사용을 절약, 활성 복귀 시 원래 배율 복원
   검증: 양식 페이지 2× 프로그램 줌에서 점 노트 선명(회귀 없음),
   시드 필기 페이지 획 유지 확인.

빌드: Debug·Store·워치 스킴 모두 성공. 도움말(목표 판정 문구
갱신 — 종료일 기준·재판정 규칙 안내)과 CLAUDE.md §4.3 갱신,
문구 수정 stale 1건 삭제 및 ko/en/ja 번역 완료.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 19:44:02 +09:00
songyc macbook
bdb97e3c9f feat(diary): imported page templates — PDF/photo backgrounds with per-page picker
일기 노트 페이지 양식(속지) 기능 (합의된 설계 그대로):

- 모델: DiaryTemplate 신설(원본 externalStorage — 여러 쪽 PDF도
  통째 1개만 저장 + pageCount) + DiaryPage.templateID/
  templatePageIndex(기본값 있는 새 필드, uuid 문자열 참조 —
  CloudKit 규칙·동기화 순서에 안전). 스키마에 등록.
- 양식 관리: 달력 툴바에서 진입 — PDF(파일, ≤20MB)·사진 가져오기,
  이름 변경·삭제(사용 중 페이지 수 경고 → 빈 캔버스 폴백, 필기 보존),
  첫 쪽 썸네일 저장. 쪽 상한 24쪽(초과분 안내).
- 페이지 추가: 양식이 있으면 [빈 캔버스/줄 노트/내 양식] 선택 시트,
  여러 쪽 PDF는 2단계 쪽 썸네일 선택(지연 생성). 양식이 없으면
  기존처럼 즉시 추가 — 흔한 경로의 반응성 유지.
- 렌더: 페이지 논리 좌표(768×1024)에 aspect-fit — 필기 좌표계 불변.
  PDF는 벡터 원본을 보존하고 줌 종료 시 현재 배율로 백그라운드
  재래스터(펜슬 캔버스 선명도 훅에 함께 연결 — 확대해도 흐림 없음).
  이미지는 가져올 때 긴 변 3072px 리샘플(필기 래스터 상한 3×와 동일).
  양식 페이지는 줄 노트 토글 숨김(상호 배타), 양식만 깔린 페이지도
  작성함 취급(hasContent). PencilKit 캔버스 코드는 건드리지 않음.
- 내보내기(PDF/PNG)에도 양식 배경 동일 반영.

검증(iPad 시뮬레이터, -diarySeedTemplate 등 신규 DEBUG 인자):
양식 관리·페이지 선택 시트·양식 페이지 렌더(2× 프로그램 줌에서
점 노트 선명) 스크린샷 + 이미지 내보내기 산출물에 양식 포함 확인.
Debug·Store 빌드 성공, 신규 문자열 22종 ko/en/ja(missing 0).
도움말 '나만의 양식(속지)' 항목 추가, CLAUDE.md §3·§6.7·§14 갱신.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 19:10:50 +09:00
songyc macbook
7a6a2aeb54 feat(diary): dashed calendar event blocks for visibility + per-date goal filter on the summary page
일기 요약 페이지 개선 2건:

1) 캘린더 일정 블록 가시성
   기존 옅은 채움(0.14)+실선 외곽선은 배경과 겹쳐 잘 안 보였다.
   구분 방향은 유지하되(꼬리표 색과 캘린더 색이 같아도 헷갈리지 않게)
   구분 수단을 '농도'에서 '스타일'로 변경 — 채움을 0.3으로 올려
   또렷하게 하고, 행동 블록(불투명 채움)과는 점선 테두리(1.5pt)로
   구분한다. 화면과 일기 내보내기(PDF/PNG)가 같은 뷰를 쓰므로 함께 반영.

2) '이 날의 목표' 필터
   카드 우상단에 타임테이블 필터와 같은 모양의 필터 버튼 추가 —
   그날 진행 중인 목표 중 보고 싶은 것만 선택(숨긴 개수 노란 배지).
   선택은 날짜별로 DiaryEntry.hiddenGoalIDs(uuid 문자열, 기본값 있는
   새 필드 — CloudKit 규칙 준수)에 저장되어 기기 간 동기화에 안전.
   시트는 전체 선택/해제 + 개별 체크(캘린더 일정 선택과 동일 패턴),
   열람 전용(프리미엄 만료)에서는 버튼 숨김, 빈 엔트리 정리 조건에도
   목표 필터 선택 보존 추가. 모두 숨기면 안내 문구 표시.

검증: Debug·Store 빌드 성공, iPad 시뮬레이터에서 점선 캘린더 블록·
필터 버튼·팝업(첫 목표 숨김 → 카드 제외 + 배지 1) 스크린샷 확인.
신규 문자열 ko/en/ja 번역(missing 0, 문구 수정 stale 1건 삭제).
DEBUG 인자 -diaryHideFirstGoal/-diaryShowGoalFilter 추가.
도움말(일정·필터 항목)과 CLAUDE.md(§3·§6.7·§14) 갱신.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 18:39:46 +09:00
songyc macbook
e652aff0e9 fix(review): tracking-type lock on edit, week-label l10n, premium feature list, catalog hygiene
전체 코드 최종 점검(보고)에서 지시받은 A·B·D 항목 처리:

A. 행동 수정 시 추적 방식 변경 잠금
   기존 행동을 수정할 때 추적 방식(시간↔횟수) 피커가 활성화되어
   있어 도움말("추적 방식은 바꿀 수 없으니")과 어긋났고, 바꾸면
   기존 기록이 화면·통계에서 보이지 않는 것처럼 되는 문제.
   → 수정 모드에서 피커 비활성 + "만들 때만 선택할 수 있어요"
   푸터 안내(ko/en/ja). 생성 시에는 기존과 동일.

B. 주차 라벨 지역화 2건
   - 통계 탭 월간 주차별 꺾은선 x축 "N주차"가 String(localized:)
     없이 하드코딩 — en/ja에서 한국어 노출 (내보내기와 불일치)
   - ⑤ 행동 통계 위젯 주 단위 라벨 "N주" — 같은 문제 + 앱과 표기
     불일치 → 둘 다 기존 번역 키 "%lld주차"(Week %lld/第%lld週) 사용

D. 결제 화면 기능 목록에 '제어 센터에서 실행' 항목 추가(ko/en/ja,
   도움말·CLAUDE.md와 일치) + Widgets/InfoPlist.xcstrings의
   CFBundleName을 IOS와 동일하게 shouldTranslate=false 처리.

C(시리 문구 미번역 의심)는 오탐 확인 — AppShortcuts 카탈로그는
stringSet(발화 변형) 구조로 ko/en/ja 모두 translated 상태.

검증: Debug·Store 빌드 성공, 영어 실행 통계 월간 화면에서
"Week 1~5" 표시 확인, 결제 화면에 제어 센터 항목 표시 확인,
전 카탈로그 missing 0·stale 0. CLAUDE.md §6.2 갱신.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 18:22:23 +09:00
songyc macbook
49cada45c7 feat(widget): add Now Tracking home widget — live timer with a stop button
새 홈 위젯 ⑥ '현재 진행 중'(HaruNowRunningWidget, 소형/중형/대형):

- 측정 중이 아니면 빈 상태 안내("지금 측정 중인 행동이 없어요")
- 측정이 시작되면 대표 행동(설정 '대표 시간 기준' — 다이나믹
  아일랜드와 같은 규칙)의 꼬리표 색 배경 위에 이름·시작 시각·
  실시간 타이머(Text(style:.timer))·종료 버튼을 표시
- 여러 개 측정 중이면 소형/중형은 "+N개 함께 추적 중", 대형은
  함께 측정 중인 행동을 줄로 나열하고 각각 종료 가능(4개 초과분은
  "외 N개"), 대표 하나뿐이면 오늘 누적(실시간)·시작 시각 카드
- 종료는 기존 RunActionIntent(시간형 토글) 재사용 — 짧은 기록
  무시 규칙·프리미엄 게이트·히트 영역(contentShape) 규칙 동일 적용
- 타임라인은 ①과 같은 예산 전략(주기 폴링 없음, 날짜 경계 안전망),
  탭 즉시 피드백(invalidatableContent), 틴트/클리어 렌더링 모드 대응
- 갤러리 미리보기는 측정 중이 아니어도 샘플로 모습 표시

검증: Debug·Store 빌드 성공, 앱 내 위젯 미리보기(-widgetPreview,
앵커 R/RL/RM/RE)로 소·중·대형/여러 개/빈 상태 스크린샷 확인.
l10n: 신규 문자열 ko/en/ja 번역(IOS·Widgets 카탈로그 missing 0,
stale 0 — 문구 수정으로 생긴 stale 1건 삭제, 잘못 stale로 남아
있던 위젯 전용 키 3건은 정상 상태로 복구). 도움말 위젯 항목과
CLAUDE.md §10에 ⑥ 추가.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 17:24:07 +09:00
songyc macbook
7720ed5925 fix(sync): receive CloudKit silent pushes so cross-device changes arrive while the app is open
다른 기기(아이폰↔아이패드)에서 측정을 시작/종료해도 사용 중인
기기에는 반영되지 않고, 모음 탭 새로고침 버튼을 눌러도 그대로이던
버그 수정. 앱을 나갔다 들어와야만 반영되던 증상의 원인.

원인: 푸시 엔타이틀먼트(aps-environment)는 있었지만
UIBackgroundModes에 remote-notification이 없어 CloudKit의
"데이터 바뀜" 무음 푸시가 앱에 전달되지 않았다. Core Data+CloudKit은
이 푸시로 가져오기(import)를 트리거하므로, 없으면 앱 실행/포그라운드
복귀 때만 가져온다. 새로고침 버튼은 로컬 스토어 재조회일 뿐이라
가져오기 전에는 옛 데이터만 보였다.

수정: iOS 타깃에 IOS/Info.plist 신설(UIBackgroundModes:
remote-notification)하고 INFOPLIST_FILE로 지정 — 생성 Info.plist
(GENERATE_INFOPLIST_FILE=YES)와 병합된다. IOS 동기화 그룹에
membershipException을 추가해 plist가 리소스로 중복 복사되지 않게 함.

검증: Debug·Store 빌드 성공, 두 빌드 산출물 Info.plist에
UIBackgroundModes=[remote-notification]과 기존 생성 키(표시 이름·
Live Activity) 병합 확인, 시뮬레이터 콜드 스타트 정상. 기기 간
동기화 도착은 실기기 2대에서 확인 필요.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 16:10:00 +09:00
songyc macbook
74dab79065 chore(l10n): normalize string catalog formatting (Xcode re-save, no content change)
Xcode가 카탈로그를 다시 저장하며 생긴 포맷 변화(콜론 앞 공백,
키 정렬 순서)만 반영. 키 추가/삭제 0, en/ja 번역 값 변경 0을
스크립트로 비교 확인함.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 16:09:41 +09:00
songyc macbook
9902d44848 feat(expiranner): rebuild as store-based expiry photo checker
- 매장 선택 → 연/월 → 월 캘린더(날짜별 제품 사진 썸네일) → 날짜 상세 플로우로 전면 재작성
- 스캔 플로우: 촬영 → 재촬영/사용 → 그 달 날짜만 선택 → 저장 후 카메라 자동 복귀 (손전등 지원)
- 날짜 상세 다중 선택 삭제 (전체 선택/해제 + 일괄 삭제 확인)
- 다크 전용 민트 테마, SwiftData 모델(Store ↔ ProductRecord, 원본+썸네일 분리 저장)
- 밝은 민트 앱 아이콘(SVG 원본 포함) + 런치 스크린/인앱 스플래시
- CLAUDE.md 새 구조 기준으로 재작성

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 15:53:14 +09:00
songyc macbook
6e0af0c33c fix(widget): make the whole interactive cell tappable, not just its visible content
인터랙티브 위젯(①행동 실행·③다짐 진행률)에서 셀의 일부 지점을
누르면 인텐트가 실행되지 않고 앱이 열리던 버그 수정.

원인: .plain 스타일 Button은 라벨의 투명한 영역(Spacer로 벌어진
공간, 여백, 링 안쪽)을 탭 판정에서 제외하는 경우가 있어, 해당
지점의 탭이 버튼에 잡히지 않고 위젯 기본 동작(앱 열기)으로 샜다.

수정: 두 위젯의 버튼 라벨 끝에 .contentShape(.rect)로 히트 영역을
셀 프레임 전체로 명시 — 아이콘·글자·프로그레스 링은 물론 셀 안
빈 공간까지 어디를 눌러도 인텐트가 실행된다. 시각적 변화 없음.
(③의 꼬리표 대상 다짐 셀은 표시 전용이라 기존대로 앱 열기)

검증: Debug·Store 빌드 성공, 위젯 미리보기 스크린샷으로 레이아웃
무영향 확인. CLAUDE.md §10에 히트 영역 규칙 추가.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 13:55:59 +09:00
songyc macbook
86bdf3d2d7 fix(sweep): full-app inspection fixes — watch command control reload, complication state key, bundle version, stale copy/catalog cleanup
전체 점검에서 발견한 저위험 문제들 일괄 수정:
- 워치 실행 명령 처리 경로에 ControlCenter.reloadAllControls() 추가
  (DataChange.commit과 동일 경로 유지 — 워치에서 시작/종료 시
  아이폰 제어 센터 토글이 낡은 상태로 남던 문제)
- 컴플리케이션 전용 전송 상태 키에 측정 시작 시각 포함
  (같은 행동을 종료 직후 디바운스 안에 재시작하면 상태 변화로
  인식하지 못해 컴플리케이션 타이머가 갱신되지 않던 엣지)
- 설정 탭 버전 표기를 하드코딩("1.0") 대신 번들
  CFBundleShortVersionString에서 읽도록 변경
- '대표 시간 기준' 설명의 낡은 문구 "(Live Activity 지원은 추후
  추가 예정)" 제거 — 실제 용처(다이나믹 아일랜드·잠금화면·워치
  컴플리케이션)로 갱신, en/ja 번역 포함
- 카탈로그 stale 항목 22개 정리 (IOS 20 + Widgets 2 — 과거 문구
  수정 때 남은 죽은 키), CLAUDE.md l10n 루틴에 stale 청소 단계 추가
- CLAUDE.md 남은 배포 작업에 코드 측 잔여 2건(약관 링크,
  ITSAppUsesNonExemptEncryption) 명시

검증: Debug·Store·워치 3스킴 빌드 성공, 전 카탈로그 missing 0,
인텐트 스모크 테스트 10개 통과, 스트릭 덤프 정상(시작일 하한 유지),
설정·모음 탭 스크린샷 확인.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 13:42:54 +09:00
songyc macbook
8818578758 feat(widget,watch): instant tap feedback + stale complication timer guard
체감 개선 2건 (사용자 리포트 기반):

1) 홈 위젯 버튼의 '안 눌렸나?' 문제 — ①행동 실행·③다짐 진행률
   위젯의 변하는 값(누적·퍼센트·링)에 invalidatableContent() 적용.
   탭 즉시 해당 값이 '갱신 중' 표시로 바뀌어, 새 타임라인 도착
   (1~3초, WidgetKit 구조상 단축 불가) 전에도 탭 접수가 보인다
   → 중복 탭으로 횟수가 여러 번 올라가는 문제 방지.

2) 워치 컴플리케이션 유령 타이머 — 종료 푸시가 유실되면 '측정 중'
   타이머가 무한히 흐르던 문제. 스냅숏 generatedAt 기준 2시간
   (runningTrustInterval)을 넘긴 '측정 중'은 '새로고침 필요' 표시로
   강등. 워치 앱을 열면 즉시 복구되고 진짜 장시간 측정도 다음
   스냅숏에 타이머가 돌아온다 (데이터 무영향).

검증: 위젯 미리보기 레이아웃 무영향 확인, 워치 미리보기에 강등
샘플 행 추가(-complicationScrollTo stale)로 원형/사각형 렌더링 확인.
새 문자열 4개 워치 앱·워치 위젯 카탈로그 ko/en/ja 번역.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 13:01:05 +09:00