655 Commits

Author SHA1 Message Date
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
songyc macbook
430ec89341 fix(diary): stop pencil strokes vanishing when zooming the note page
아이패드 일기 노트에서 필기 후 핀치줌하면 획이 사라지고, 다시 그리는
동안엔 잠깐 보였다가 획을 떼면 또 사라지던 버그 수정.

원인: 줌 배율이 바뀔 때마다 SharpPencilCanvasView가 PencilKit 내부의
모든 서브레이어에 contentsScale 변경 + setNeedsDisplay()를 강제했는데,
PencilKit의 획 타일 레이어는 렌더러가 contents를 직접 채우는 방식이라
setNeedsDisplay()가 기존 픽셀만 지우고 다시 그려 주지 않음. 그리는
동안엔 라이브 렌더로 보이다가 canvasViewDrawingDidChange →
applySharpness에서 다시 지워짐.

수정: 배율 적용을 뷰 수준 contentScaleFactor 재귀로 한정하고 레이어
직접 조작·setNeedsDisplay 제거 — PencilKit이 자기 타이밍에 새 배율로
재렌더링해 획이 유지되면서 선명도(5916e7의 목적)도 유지된다.

검증(iPad 시뮬레이터): 시드에 필기 획 2줄 추가 + -diaryZoomScale
런치 인자(프로그램 줌) 신설 → 수정 전 2배 줌에서 획 소실 재현,
수정 후 동일 조건에서 획 유지·선명 확인.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 03:12:42 +09:00
songyc macbook
973bb50cba feat(radial): double-tap the closed FAB to jump to a chosen tab
글래스 버블 메뉴가 닫힌 상태에서 FAB를 0.35초 안에 빠르게 두 번 누르면
설정한 탭으로 바로 이동하는 옵션. 첫 탭을 지연시키는 더블탭 제스처 인식은
메뉴 열림 반응성을 해치므로, 첫 탭은 즉시 메뉴를 열고 두 번째 탭에서만
분기한다 — 더블탭 시 버블이 피어나다 FAB로 흡수되며 화면이 바뀌는 연출.

- 설정(내비게이션, 버블 모드 전용): '두 번 눌러 바로 이동' 토글 +
  '이동할 탭' 피커 + 푸터 설명. settings.radialDoubleTapTab
  (rawValue, 빈 값=꺼짐, 기기 로컬)
- 검증용 런치 인자 -radialDoubleTapTest (2초 뒤 더블탭 재현) —
  통계 탭 이동 스크린샷으로 확인
- 도움말: 버블 메뉴 항목에 더블탭 문장 추가 + 누락돼 있던
  '홈 화면·잠금화면 위젯' 사용법 항목 신설
- l10n 6개 문자열 ko/en/ja, CLAUDE.md §6·§6.8·§14 갱신

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 02:54:14 +09:00
songyc macbook
24c3004ead feat(widget): show span accumulated value in quest ring widget
③ 다짐 진행률 위젯에서 '이하 유지' 다짐은 시작부터 링이 가득 차 있고
문구도 '오늘 한도 지킴'뿐이라 지금 몇 회/몇 시간 했는지 알 수 없던 문제.
퍼센트(또는 한도 지킴/초과) 문구와 연속 달성 문구 사이에 위젯 옵션의
진행률 기간 기준 실제 누적값 한 줄을 추가한다 ("1시간 20분" / "3회").
'이상 달성' 다짐에도 동일하게 표시. 주간·월간 진행률 캡과 무관한
원본 누적값이며, 다른 위젯(②④)과 나머지 레이아웃은 그대로.

- QuestCellSnapshot.valueLabel 추가 (spanRange 원본 값 포맷)
- QuestProgress.spanRange(_:now:) 헬퍼 추출
- 위젯 미리보기에 '이하 유지(소형)' 행 신설 (앵커 CM)
- l10n: '0분' ko/en/ja (IOS·Widgets 카탈로그)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 02:37:41 +09:00
songyc macbook
379ea6ebf4 fix(quest): bound streaks by the goal's start date
'이하 유지' 다짐은 기록 없는 날도 달성으로 집계되므로 연속 계산이
목표가 생기기 전 과거(스캔 상한 400일)까지 거슬러 올라가 '연속 401일'로
표시되던 버그 수정. 연속은 행동이 아니라 '목표 안 다짐'의 달성이므로
하한 = 목표 시작일:
- 하루 단위: 시작일이 속한 논리적 하루부터만 센다
- 주간/월간: 시작일이 걸친 부분 주기까지 포함, 그 이전 주기에서 중단

검증: 시드에 재현 목표(스크린 타임 관리, 3일 전 시작 + 초과 없는 이하
유지 다짐) 추가 → 기대값 연속 4일 확인. -streakDump 런치 인자 신설
(전 다짐의 연속 계산 결과를 Documents/streak-dump.txt로 덤프).

부수: 도움말에 '연속 달성 표시' 항목 추가(ko/en/ja). 지난 기능들의
문자열이 위젯·워치·InfoPlist 카탈로그에 미번역으로 남아 있던 것을
채움(제어 센터·연속 표기·즐겨찾기·캘린더 권한 문구) — l10n 루틴이
IOS 카탈로그만 확인하던 함정을 CLAUDE.md §2.3에 명시.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 01:42:13 +09:00
songyc macbook
ce8ca50feb docs(help): update help & CLAUDE.md for the new feature batch, l10n fill
- 도움말: 장시간 측정 알림(측정 토픽), CSV 백업(새 토픽), 일기 텍스트
  상자·페이지 순서, 워치 즐겨찾기, 제어 센터 실행(새 토픽), 만료 후
  데이터·일기 정책 문구 반영
- CLAUDE.md: §3 DiaryPageItem.text, §5.3 커밋 전파(컨트롤 리로드·워치
  디바운스·알림 동기화), §6.1 온보딩 빈 화면, §6.7 만료 열람 모드·텍스트
  상자·페이지 순서, §6.8 장시간 알림·데이터 내보내기, §8 만료 정책,
  §9 워치 즐겨찾기, §10 제어 센터 컨트롤, §12 컨트롤 인텐트, §14 새 인자
- 신규 문자열 49건 en/ja 번역 (missing: [])
- 최종 검증: Debug·Store·watchOS 3개 스킴 빌드 성공, 인텐트 스모크
  테스트 10개 시나리오 재통과

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 00:24:29 +09:00
songyc macbook
e4bba280ad feat(control): Control Center toggle for running an action (iOS 18 control)
제어 센터/잠금화면 하단/액션 버튼에 배치할 수 있는 '행동 실행' 컨트롤:
- 행동 하나를 골라(미선택 시 배치 첫 행동) 시간형은 시작/종료 토글,
  횟수형은 탭마다 +1 (토글 표시는 꺼짐으로 복귀)
- 전용 ToggleActionControlIntent(SetValueIntent + LiveActivityIntent) —
  앱 프로세스 실행이라 제어 센터에서 시작해도 다이나믹 아일랜드가 바로 뜸.
  단축어 앱에는 숨김(isDiscoverable=false), 프리미엄 게이트 적용
- DataChange.commit / IntentStore.performWrite에
  ControlCenter.reloadAllControls() 추가 — 앱/위젯/시리/워치 어느 경로로
  측정 상태가 바뀌어도 컨트롤 토글 표시가 따라온다

시뮬레이터에는 제어 센터에 컨트롤을 추가할 수단이 없어 빌드·인텐트
메타데이터 등록 확인까지 검증 (실기기에서 배치·토글 확인 필요).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 00:19:36 +09:00
songyc macbook
f22aea0f95 feat(onboarding): actionable empty state on the main tab
첫 실행의 빈 모음 탭이 안내 문구뿐이던 것을 개선:
- 도메인 개념 한 줄 소개 + '첫 행동 만들기'(행동 추가 시트 직행)
- '예시 행동으로 시작해 보기' — 즉시 써 볼 수 있는 예시 세트
  (꼬리표 생활·건강 + 독서/운동/물 마시기) 생성. 행동 추가와 같은
  경로(LocalPrefs 배치 등록 + DataChange.commit)를 쓰며 언제든 수정·삭제 가능

깨끗한 설치 상태 스크린샷으로 확인.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 00:17:42 +09:00
songyc macbook
d7b602f08b feat(export): raw data export to CSV from Settings
설정 → 데이터 → '데이터 내보내기': 행동·시간 기록·횟수 기록·목표·다짐을
CSV 5개 파일로 만들어 공유한다 (백업·이동·스프레드시트 분석용).
- 가공 없는 원본 값, 시각은 ISO 8601, 필드 이스케이프 처리,
  엑셀 한글 인식용 UTF-8 BOM
- 무료 사용자도 사용 가능 (iCloud 백업이 없는 무료 사용자의 백업 수단)
- 검증용 -dataExportPreview(화면 직행)·-dataExportRun(자동 생성 후
  Documents 복사) 추가. 시뮬레이터에서 5개 파일 생성·내용 확인

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 00:16:10 +09:00
songyc macbook
64c9f2d619 feat(diary): text boxes, page reorder, read-only browsing after expiry
- 텍스트 상자 요소: 노트 페이지 툴바에 '텍스트' 추가 — 키보드로 쓰는
  글 상자를 배치 요소로 올린다 (배치 모드에서 이동·크기 조절, 선택 시
  '글 수정'으로 내용·색 편집, 내보내기에도 그대로 렌더).
  DiaryPageItem에 text 필드 추가(kind .text, CloudKit 기본값 규칙 준수)
- 페이지 순서 변경: ⋯ 메뉴 → '페이지 순서 변경' 시트에서 노트 페이지를
  드래그로 재배열 (요약 페이지는 항상 첫 장)
- 프리미엄 만료 후 열람 허용: 이미 쓴 일기가 있으면 잠금 화면 대신
  달력을 열람 전용으로 연다 — 안내 배너 + 일기 있는 날짜만 활성,
  진입만으로 엔트리를 만들지 않고, 기분/할일/필기/필터/캘린더 등
  모든 편집 UI 비활성 (environment diaryReadOnly로 전파).
  일기를 쓴 적 없는 미구매 사용자는 기존 잠금 안내 유지

검증(iPad): 시드된 노트 페이지에서 텍스트 상자 렌더·툴바 확인,
-premium NO에서 배너/날짜 비활성/편집 UI 숨김 스크린샷 확인

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 00:13:11 +09:00
songyc macbook
59d6105d21 feat(tracking): long-running session alerts, timer cap fix, memo save
- 장시간 측정 알림: 측정이 설정한 시간(1/2/3/6/12시간, 기본 끔)을 넘기면
  로컬 알림으로 종료를 잊었음을 알려준다. LiveActivityManager.sync 길목에서
  진행 세션과 예약을 동기화하므로 앱·위젯·시리·워치 어느 경로로
  시작/종료/수정해도 예약이 따라가고, 세션이 끝나거나 설정이 바뀌면
  기존 예약이 제거된다 (식별자에 행동·시작시각·설정시간 포함).
  설정 탭 '측정' 섹션에서 켜는 순간 권한 요청.
- Live Activity 타이머 상한 30일 → 1년 (상한 도달로 타이머가 멈춰 보이던
  엣지 제거)
- 메모 시트(측정 종료/횟수 기록) 저장 시 명시적 context.save — autosave
  의존 제거
- 검증용 -longSessionAlertTestSeconds(시간 대신 N초 발화)·-alertDump
  (예약 상태를 Documents/session-alerts.txt로) 추가. 시뮬레이터에서
  예약 생성(진행 세션 2건)과 설정 해제 시 제거를 덤프로 확인

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-14 00:04:08 +09:00
songyc macbook
b980d7df7a feat(watch): favorites list on the first screen, debounced snapshot push
- 워치 첫 화면 최상단에 '즐겨찾기' 항목 추가 — 앱에서 즐겨찾기한 행동을
  태그를 거치지 않고 한 탭 만에 연다. WatchActionInfo.isFavorite는
  optional로 실어 구버전 캐시 스냅숏도 그대로 디코딩된다.
- 워치 스냅숏 전송 디바운스(350ms): 모든 커밋마다 목표×다짐×3기간
  진행률을 전부 재집계하던 것을, 연타 중에는 마지막 상태 한 번만
  계산해 보내도록 변경 (명령 응답 경로의 즉시 스냅숏은 그대로).

iOS·watchOS 스킴 빌드 확인.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 23:56:32 +09:00
songyc macbook
42b95c5d7f feat(quest): consecutive-achievement display on quests, plus wording fixes
다짐 단위 '연속 달성' 표기 추가 (QuestProgress.streak → QuestStreakInfo):
- 하루 단위 다짐: 적용일만 세는 연속 계산 — 매일이면 연속 일수,
  '매주 수요일'이면 수요일들만 이어서 센다 (4주 연속 = 연속 4일)
- 주간/월간 다짐: 주기 전체 달성 여부로 연속 N주/N달
- 특정 기간 다짐: 반복이 없어 표시하지 않음
- 진행 중인 오늘/이번 주기는 '이상 달성'이면 미달이어도 끊기지 않고
  건너뛰며, 채웠으면 포함. '이하 유지'는 한도를 넘는 순간 끊김
- 성능: 기록을 논리적 하루 키로 1회 버킷팅해 O(기록수+일수),
  소급 상한 400일

표기(기존 디자인·데이터는 그대로 두고 추가만, 0이면 숨김):
- 목표 탭 다짐 행: 이름 옆 불꽃 + "연속 N일" 배지 (노랑)
- 위젯 ③ 다짐 진행률: 퍼센트 아래 한 줄
- 위젯 ④ 다짐 현황: 이름 아래 작은 글씨
- 위젯 ② 목표+다짐 구성: 퍼센트 아래 6.5pt — 연속 표기가 있을 때만
  행 높이 14→19 (적응 채움이 자동 반영)
- 문구는 '스트릭' 대신 "연속 N일/주/달" (en은 streak, ja는 N日連続)

문구 정정: '몇째 주 요일' → '몇 번째 요일' — 구현(weekdayOrdinal)은
달력의 주차가 아니라 "그 달의 n번째 ◯요일"이므로 편집 화면 픽커와
주기 요약 문구를 실제 동작에 맞게 수정 (동작 변경 없음). en/ja 번역 포함.

검증: 시드 데이터로 목표 탭 배지 손계산 대조(독서 연속 3일 — 3일 전
기록 없음 / 영상 시청 어제 한도 초과로 연속 1일 등 전부 일치),
위젯 ②③④ 미리보기 스크린샷으로 레이아웃 넘침 없음 확인,
missing: [], Debug·Store 스킴 빌드 성공.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 23:49:45 +09:00
songyc macbook
076dad26d8 feat(widget): adopt LiveActivityIntent on the widget run button too
RunActionIntent(위젯 실행 버튼)도 LiveActivityIntent를 채택 — 시스템이
앱 프로세스에서 실행해, 위젯 탭으로 시간 측정을 시작해도 시리 경로와
동일하게 다이나믹 아일랜드가 바로 뜬다.

과거 '위젯 버튼 먹통' 증상 때문에 확장 프로세스 고정을 유지했었으나,
해당 증상은 위젯 재추가·기기 재부팅(캐시)으로 해소된 것으로 확인되어
제약을 풀었다. 실기기에서 응답성 회귀가 보이면 이 인텐트의
LiveActivityIntent 채택 한 줄만 되돌리면 된다 (코드 주석에도 기록).

검증: -intentSmokeTest에 위젯 실행 토글 시나리오 추가(시작 → 토글 종료),
10개 시나리오 전부 통과. Debug·Store 스킴 빌드 성공.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 21:37:42 +09:00
songyc macbook
ec62dc83de feat(siri): background Live Activity, spoken action names, localized phrases
시리 단축어 점검에서 나온 추천 수정 일괄 적용:

- StartTimeActionIntent·StopTimeActionIntent가 LiveActivityIntent 채택 —
  시리/단축어의 백그라운드 실행에서도 Live Activity 시작이 허용되어
  앱을 열지 않아도 다이나믹 아일랜드에 측정이 표시된다.
  RunActionIntent(위젯 버튼)는 확장 프로세스 응답성 튜닝을 유지하기 위해
  의도적으로 제외.
- 행동 이름 파라미터 문구 추가: "시리야, 하루 다님에서 독서 측정 시작"처럼
  되묻지 않고 한 번에 실행. 어휘 갱신을 위해 앱 시작 시
  updateAppShortcutParameters() 호출 (새 행동은 다음 실행부터 인식).
- IOS/AppShortcuts.xcstrings 신설 — 시리 문구 ko/en/ja 지역화.
  빌드 로그의 --no-app-shortcuts-localization가 사라지고 root.ssu.yaml에
  en/ja 발화가 포함되는 것 확인.
- RunActionIntent isDiscoverable=false — 생 UUID 파라미터라 사용자가 조합할
  수 없는 위젯 전용 동작을 단축어 앱·스포트라이트에서 숨김 (위젯 버튼은
  그대로 동작).
- 결제 화면 기능 목록에 '시리 단축어' 추가. 이 과정에서 featureRow가
  String 파라미터라 기능 목록 6줄 전체가 미지역화였던 버그 발견 —
  LocalizedStringKey로 바꾸고 en/ja 12개 문자열 번역.

검증: -intentSmokeTest 9개 시나리오 전부 통과(LiveActivityIntent 전환 후
재확인), 프리미엄 화면 렌더링 확인, Debug·Store 스킴 빌드 성공.
남은 확인: 시리 음성 인식·백그라운드 Live Activity 실표시는 실기기 필요.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 21:08:48 +09:00
songyc macbook
ecfd008229 docs(siri): add Shortcuts help topic and an in-app intent smoke test
시리 단축어 기능 점검:
- 도움말(프리미엄 그룹)에 '시리·단축어로 기록하기' 항목 추가 — 그동안
  도움말에 시리 단축어 안내가 없었다. en/ja 번역 포함
- DEBUG 검증용 -intentSmokeTest 런치 인자 추가: 인텐트 6종의 perform()을
  앱 안에서 9개 시나리오(시작/중복 방지/종료/횟수 추가/타입 방어/조회
  3종/프리미엄 게이트)로 실행하고 결과를 Documents/intent-smoke-test.txt에
  남긴다. 시뮬레이터 실행 결과 9개 전부 통과
- CLAUDE.md §12·§14에 검증 방법과 현재 한계(AppShortcuts 지역화 미구성,
  '선택 안 함' 센티널의 단축어 앱 노출) 기록

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 20:51:30 +09:00
songyc macbook
1b36607ba1 feat(radial): rebuild glass bubble menu on native Liquid Glass
글래스 버블 메뉴를 시스템 리퀴드 글라스(glassEffect) 기반으로 재구축.
컨셉(FAB → 부채꼴 유리 구슬, 엄지 반경 ~150pt, 바깥 탭 닫기, 순서 설정)은
그대로 두고 유리 질감·연출·성능을 올렸다.

유리: material 흉내(ultraThinMaterial + 그라데이션 + 테두리) 대신
.glassEffect(.regular.interactive()) — 배경 굴절·빛 반사·눌림 시머까지
시스템이 그린다. 현재 탭은 초록 틴트 유리.

연출: 2단계 — 삽입 순간 FAB 유리에서 모핑으로 부풀어 나온 뒤(bloomed)
스태거 바운스 스프링으로 아치에 흩어진다. GlassEffectContainer 근접
블렌딩으로 FAB를 벗어날 때 유리가 늘어나다 물방울처럼 분리. 닫힘은
지연 없이 흡수. 그라데이션 딤 + 메뉴 뒤 초록 빛 무리 + 햅틱.

성능(버벅임): 예전엔 블러 14장(버블 7 + 라벨 알약 7) + 그림자 14개가
각각 애니메이션됐다. 라벨을 구슬 안에 넣어 유리 요소를 8개로 줄이고
GlassEffectContainer가 한 패스로 일괄 렌더링, 커스텀 그림자 제거.

주의점 기록: 컨테이너 안 유리 요소는 glassEffect 뒤 opacity/scale이
콘텐츠에 온전히 적용되지 않아(접힌 상태 내용물 비침) 숨김은 계층
제거(if expanded), 이동은 offset으로만 처리.

검증: 접힘·펼침(라이트/다크) 스크린샷으로 유리 굴절·라벨 가독성·
콘텐츠 누출 없음 확인. Debug·Store 스킴 빌드 성공.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 20:16:25 +09:00
songyc macbook
a9473be937 fix(diary): clean up empty entries created by merely viewing a day
일기 상세는 진입만 해도 DiaryEntry를 생성(loadEntry)해서, 열람만 한
날짜의 빈 엔트리가 스토어와 CloudKit에 계속 쌓였다. 달력 화면
onAppear에서 완전히 빈 엔트리만 정리한다 (상세에서 달력으로 돌아올
때마다 실행되고, 이 수정 이전에 쌓인 빈 엔트리도 함께 청소됨).

보존 조건을 엄격히 판정:
- hasContent(기분·할 일·내용 있는 페이지)는 물론
- 달력 마커에 안 잡히는 캘린더 일정(calendarEventIDs)·타임테이블
  필터(hiddenActionIDs) 선택이 있으면 보존
- 아직 내용 없는 노트 페이지를 만들어 둔 날도 보존 (페이지 0개일 때만 삭제)

검증(iPad 시뮬레이터, 스토어 직접 조회):
- 열람만 하고 나간 빈 엔트리 → 달력 재진입 시 삭제 (1건 → 0건)
- 타임테이블 필터만 설정한 엔트리 → 정리 후에도 보존, 재진입 시
  필터 배지(1)와 숨김 상태 유지 확인

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 19:40:46 +09:00
songyc macbook
0aed7a9ec5 fix(goal): evaluate ended goals at launch and foreground, not only on goal tab
종료일이 지난 목표의 자동 판정(evaluateIfEnded)이 목표 탭 진입 시에만
실행돼, 목표 탭을 열지 않으면 위젯·워치·모음 탭 카드에 '진행 중'으로
계속 남아 있었다. 앱 실행/포그라운드 복귀(scenePhase .active) 시점에
같은 판정을 추가로 실행한다.

- 목표 탭 onAppear 로직과 동일한 코드 — 진행 중 목표만 조회, 변경이
  있을 때만 DataChange.commit (위젯·워치·라이브 액티비티 갱신)
- 다짐 없는 목표는 evaluateIfEnded가 건드리지 않으므로 '확인 필요'
  직접 선택 흐름은 그대로
- 위젯 확장에서는 판정하지 않음 (프로바이더 경합·CloudKit 내보내기
  지연 위험 회피)
- 검증용 DEBUG 인자 -endGoalYesterday "제목" 추가. 시뮬레이터에서
  목표 탭을 열지 않은 콜드 스타트만으로 statusRaw가 achieved로
  전환되는 것을 스토어 조회로 확인

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 19:37:43 +09:00
songyc macbook
d023f3eca1 fix(action): commit tag order and favorite changes immediately
꼬리표 순서 변경 시트와 즐겨찾기 토글(리스트 스와이프·상세 화면)이
DataChange.commit 없이 autosave에만 의존해, 저장 확정이 지연되고
꼬리표 순서를 쓰는 워치 앱 그룹핑이 다음 커밋 시점까지 낡은 순서로
남을 수 있었다.

- TagOrderSheet: 드래그마다가 아니라 시트가 닫힐 때 1회만 커밋
  ('완료'와 스와이프 내리기 모두 onDisappear 경로) — 위젯 리로드 연발 방지
- 즐겨찾기 토글 2곳: 변경 즉시 커밋

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 19:35:29 +09:00
songyc macbook
417070bde7 chore: rewrite CLAUDE.md from actual code, plus safe hardening fixes
CLAUDE.md v2.0 — 기획서(v1.0)를 폐기하고 실제 구현 기준의 현행 명세로 전면 재작성:
프로젝트 구조·빌드/검증 루틴·도메인 모델(CloudKit 규칙)·집계/판정 규칙·데이터 계층
(LocalPrefs/DataChange)·화면별 상세·내보내기·프리미엄/StoreKit·위젯 6종·워치·시리·
DEBUG 런치 인자·작업 컨벤션까지 새 세션이 이 문서만으로 파악 가능하게 정리.

동작 보존 범위의 안전 수정 3건:
- Color.hexString: 와이드 컬러(P3) 성분을 0...1로 클램프 — 음수/1 초과 값이
  %02X를 거치며 자릿수 깨진 hex가 태그·목표 색으로 저장되던 잠재 버그 방지
- 일기 타임테이블 필터: 선택 즉시 명시적 save — 캘린더 일정 선택 경로와 동일하게
  영속을 보장 (autosave 의존 제거)
- 통계 평균 "%.1f회"가 String(format:)이라 영어·일본어에서도 '회'로 노출되던 것을
  Format.countAverage로 지역화 (en "times" / ja "回", 카탈로그 동기화 포함)

Debug·Store(Release) 스킴 빌드 검증 완료.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 18:45:53 +09:00
songyc macbook
93dd3d1d9f feat(diary): per-date action filter for the summary timetable
일기 타임테이블에서 그날 기록된 행동 중 원하는 것만 골라 볼 수 있게.
캘린더 일정 선택과 마찬가지로 날짜별로 저장되고 내보내기에도 반영된다.

- DiaryEntry.hiddenActionIDs (행동 uuid 문자열, 날짜별·동기화 안전)
- 타임테이블 카드 우상단에 필터 버튼 추가 (숨긴 개수 배지, 캘린더 버튼 옆)
- 기존 RecordFilterSheet 재사용 — 그날 기록된 행동만 꼬리표별로 나열
- 필터는 타임테이블에만 적용, 기록 목록·요약 통계는 전체 유지
  (ExportSnapshot.replacingTimetableSections로 내보내기도 동일 규칙)
- 도움말 갱신: 목표 달성 판정 기준, 일기 타임테이블 일정·필터 항목
- en/ja 번역 추가 (Live Activity의 미번역 문자열 3건도 함께 보충)
- 검증용 런치 인자 -diaryShowActionFilter, -diaryHideFirstAction 추가

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 18:24:22 +09:00
songyc macbook
85a98c1ab0 feat(goal): configurable achievement threshold per goal
목표 종료 판정이 '다짐 전체 달성'으로 고정되어 있던 것을, 목표를 만들 때
달성 판정 기준(%)을 정할 수 있게 확장. 다짐들의 평균 달성률(달성=100%,
미달성=현재 주기 진행률)이 기준 이상이면 달성 완료로 판정한다.

- Goal.achieveThresholdPercent (기본 100 = 기존 동작 유지, CloudKit 호환)
- evaluateIfEnded/manualFinish가 questAchievementRatio ≥ 기준으로 판정
- 목표 추가/수정 화면에 '달성 판정 기준' 슬라이더 (10~100%, 5% 단위)
- 수동 종료 안내 문구에 기준이 100% 미만이면 해당 기준 표기
- 검증용 런치 인자 -goalShowEditor 추가
- 그 외 진행률 표시·연산은 변경 없음

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 18:24:05 +09:00
songyc macbook
5f9593923a fix(diary): pencil-only drawing with finger panning, and truly sharp strokes
- 실기기에서 drawingPolicy .pencilOnly — 손가락은 절대 필기되지 않고,
  확대 상태에서 한 손가락으로 페이지를 상하좌우 이동(팬)한다. 이동/확대
  제스처는 allowedTouchTypes=direct로 손가락 전용이라 펜슬 획을 뺏지 않음
  (시뮬레이터는 입력 수단이 없어 anyInput 유지). 배치 모드에선 한 손가락을
  요소 드래그에 양보(팬 두 손가락)
- 선명도 재수정: SharpPencilCanvasView가 목표 래스터 배율(기기 스케일 ×
  현재 줌, 상한 ×3)을 뷰+레이어 트리에 유지하고, 획을 그릴 때마다·레이아웃
  때마다 재적용 — PencilKit이 새 획 렌더 레이어를 기본 해상도로 만들어
  흐려지던 문제와, 기존 1.5배 슈퍼샘플링의 다운샘플 소프트닝을 함께 제거
  (화면 픽셀과 1:1 매칭이 가장 선명)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 17:31:09 +09:00
songyc macbook
4c3b5a6c03 feat(diary): show selected calendar events in the timetable, per date
- DiaryEntry.calendarEventIDs: 날짜별로 어떤 캘린더(EventKit) 일정을 넣을지
  따로 저장 — 오늘은 포함, 내일은 미포함 같은 선택이 가능
- 타임테이블 카드 우상단 캘린더 버튼(+선택 개수 배지) → 일정 선택 팝업:
  그날의 일정 목록에서 전체 선택/해제 또는 개별 체크, 권한 미허용 시 설정
  이동 안내. 종일 일정은 제외, 하루 경계에 걸치면 잘라서 표시
- 일정은 행동 블록과 구분되는 외곽선+은은한 채움 스타일(캘린더 색)로 렌더,
  일기 내보내기(PDF/이미지)에도 동일하게 포함 — 내보내기 요약도 화면과
  같은 24시간 타임테이블로 통일
- NSCalendarsFullAccessUsageDescription 추가, 새 문자열 en/ja 번역
- 검증 인자: -diarySeedEvents YES, -diaryShowCalendarPicker YES

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 17:31:09 +09:00
songyc macbook
4f9fdfba11 chore(xcode): normalize Store scheme serialization (Xcode strips comments)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 17:15:37 +09:00
songyc macbook
957618fccd feat(app): add Home tab refresh button and device-specific help guide
- 모음 탭 왼쪽 위 새로고침 버튼(RefreshButton/AppRefresh): 루트 뷰 identity
  리셋으로 모든 @Query를 재조회(앱 재시작과 같은 효과) + 라이브 액티비티·
  위젯·워치 스냅숏 동기화. 다른 기기의 iCloud 변경이 화면에 늦게 보일 때
  재시작 없이 반영. iPhone·iPad 공통, Release(스토어) 빌드에도 포함
- 설정 → 지원 → 도움말(HelpView): 기본 개념/모음 탭/목표/기록·통계/동기화/
  프리미엄 공통 + iPhone은 화면 구성(탭바·버블 메뉴·다이나믹 아일랜드)과
  애플워치(기록·컴플리케이션·동기화) 섹션, iPad는 일기 섹션. 접이식 주제별
  구성, 새 문자열 59개 en/ja 번역
- 검증 인자: -helpPreview YES

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 17:09:11 +09:00
songyc macbook
040198beb4 feat(premium): add store-identical Release run scheme and real-purchase priority
- 'Haru_Danim-Store' 공유 스킴 추가: Release 구성으로 실행해 DEBUG 코드
  (프리미엄 테스트 토글·검증용 런치 인자)가 전부 빠진 '스토어에 올릴
  그대로'의 앱을 실기기에서 확인. StoreKit 로컬 구성은 유지되어 실제 결제
  시트가 뜨되 돈은 청구되지 않는다
- 실구매/복원 시 DEBUG 테스트 토글 강제 모드를 자동 해제(실권한 우선),
  개발용 섹션에 '토글 강제 해제' 버튼과 동작 설명 footer 추가
- Localizable.xcstrings는 Xcode 직렬화 포맷 정규화

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 16:14:11 +09:00
songyc macbook
14fc5cb5bd feat(premium): complete StoreKit 2 purchase experience
기존 StoreKit 2 골격(상품 3종·구매·복원·권한 주입) 위에 실사용 경험 완성:
- PremiumStore.currentPlan: 현재 이용 중인 대표 플랜(평생 > 만료 먼 구독)
  추적, 구매·복원 후 위젯 타임라인 즉시 갱신
- 프리미엄 화면: '이용 중인 플랜' 섹션(플랜 이름·다음 갱신일·평생 안내),
  구독 관리 시트(manageSubscriptionsSheet), 구독 중 평생 이용권 전환 안내,
  년 구독 절약률·평생 '한 번 결제' 배지, 자동 갱신·해지·복원 안내 문구
- 잠금 안내 개선: 행동/목표/다짐 무료 한도 알림에 '프리미엄 알아보기'
  버튼 + PremiumSheetView 모달, 아이패드 일기 잠금 화면에도 버튼 추가
- 기능 소개에 '아이패드 일기' 추가, 새 문자열 en/ja 번역

가격(월 5,000/년 50,000/일회성 80,000)은 HaruDanim.storekit(로컬 테스트)과
App Store Connect에서 각각 수정 가능. DEBUG 강제 토글은 그대로 유지.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 15:52:49 +09:00
songyc macbook
c6959950c2 feat(widget): fill quest list adaptively in goal progress widget
목표 진행률 위젯의 다짐 목록이 고정 3개(중형)/8개(대형) 제한이었던 것을
QuestBarsColumn으로 교체 — 셀의 실제 높이에 들어가는 만큼 최대한 표시
(행 14pt+간격 6pt 기준 계산)하고, 넘치는 개수는 헤더 오른쪽에 '+N' 표기.
기기·패밀리가 커지면 자동으로 더 보인다.

그 외 개수 제한 검토: 다짐 현황 위젯 그리드(4/8/16)는 스펙 고정, 통계
차트 시리즈(4/6)는 가독성 제한, 잠금화면 점(6)은 공간 제한이라 유지.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 15:14:26 +09:00
songyc macbook
5916e17b25 fix(diary): keep pencil strokes sharp at any zoom level
페이지가 논리 768×1024pt 고정 + 스케일 변환이라 PKCanvasView 래스터가
비정수 축소에선 뭉개지고 확대에선 픽셀이 보였음 → 캔버스(내부 렌더 뷰
포함)의 contentScaleFactor를 기본 1.5배 슈퍼샘플링 + 줌 배율 추종(기기
스케일 ×2.5 상한)으로 조정. 레이아웃 변경과 핀치 종료 시점에 갱신.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 15:08:08 +09:00
songyc macbook
8d4d20fc76 feat(diary): make the mood area a large square tile
'오늘 기분'을 카드의 주인공인 200pt 정사각형 타일로 재배치 — 사진은 꽉
채우고(이모지는 우하단 배지), 이모지만 있으면 크게 가운데, 비어 있으면
'탭해서 남기기' 플레이스홀더. 오른쪽에 이모지/사진/지우기 캡슐 버튼 열.
새 문자열 en/ja 번역 추가.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 15:08:08 +09:00
songyc macbook
daf4fc3157 fix(radial): add glass pill background behind bubble tab labels
글래스 버블 메뉴의 탭 이름이 맨 글자(그림자만)라 라이트 모드 밝은 배경
위에서 잘 안 보였음 → 구슬과 같은 ultraThinMaterial 캡슐 배경 + 화이트
보더 + 소프트 섀도를 붙여 라이트/다크 어디서나 읽히게 함.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 14:58:45 +09:00
songyc macbook
939406ac74 feat(brand): logo v4 — walker on a clock planet, with light/dark/tinted icon variants
콘셉트 전면 재디자인: 하루라는 행성(시계)이 화면 아래를 채우고 그 위를
사람이 걸어간다. 시계는 링+3/6/9 눈금+10:10 골드 바늘, 사람 뒤로 링을
따라 남은 발자국, 소프트 섀도로 입체감.

iOS 아이콘 외형 3종(에셋 카탈로그 luminosity 변형):
- 라이트: 웜 화이트 배경 + 초록 시계 + 검정 사람 + 골드 바늘
- 다크: 딥 그린 그라데이션 배경 + 웜 화이트 드로잉 (기존 톤 유지)
- 틴티드: 투명 배경 + 그레이스케일 (시스템이 틴트 적용)
스플래시 로고도 라이트/다크 변형 제공(테마 따라 자동 전환), 워치·워치
위젯은 다크 단일(외형 변형 미지원 플랫폼).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 14:30:01 +09:00
songyc macbook
6b0b6055eb feat(diary): customizable first-page sections — show/hide and reorder
- 일기 상세 메뉴에 '첫 화면 구성' 시트 추가: 7개 섹션(오늘 기분/요약
  지표/이 날의 목표/오늘 할 일/타임테이블/기록 상세/통계 막대)을
  드래그로 순서 변경, 스위치로 표시/숨김 (모든 날짜 공통 적용)
- DiarySummaryPage가 설정 순서대로 렌더링, 숨긴 섹션 제외. 와이드
  레이아웃은 타임테이블 표시 중일 때만 2컬럼(타임테이블 왼쪽 전담)
- 기존 '오늘 기분 표시' 토글은 새 숨김 목록으로 1회 이관
- 검증 인자: -diaryShowConfig YES, -diary.sectionOrder/-diary.hiddenSections
- 새 문자열 en/ja 번역 추가

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 05:57:11 +09:00
songyc macbook
209042575e feat(brand): logo v3 — person walking toward the clock of their day
시계와 사람을 포함해 슬로건('당신의 하루에 다녀가다')과 앱 콘셉트(시간
추적)를 직접 표현: 우상단 웜 화이트 시계 링(골드 10:10 바늘) + 그곳을
향해 걷는 웜 화이트 픽토그램 + 지나온 발자국 점 2개. 색 구성은 유지.
iOS·워치·워치 위젯 아이콘과 스플래시 로고 일괄 교체.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 05:57:11 +09:00
songyc macbook
921eb4bccf feat(brand): redesign logo around the slogan — footsteps visiting the sun of your day
'당신의 하루에 다녀가다'를 직접 표현: 골드 해(하루)를 향해 대각선으로
걸어가는 웜 화이트 발자국 캡슐 3개(멀수록 작아지는 깊이감) + 은은한 링.
기존 색 구성(딥 그린 그라데이션/웜 화이트/머스터드 골드) 유지.
iOS·워치·워치 위젯 앱 아이콘과 스플래시 로고에 일괄 적용.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 03:47:12 +09:00
songyc macbook
ecb7b43d31 feat(diary): redesign summary page as daily review and add note pinch-zoom, line spacing
- 첫 페이지를 '하루 정리' 화면으로 개편: 기록 유무와 무관한 24시간 고정
  타임테이블(trimHours 옵션), 그 날짜에 진행 중이던 목표들의 다짐별 진행
  현황 카드(하루 다짐은 그날 실적, 주간/월간/기간 다짐은 그 날짜까지 누적,
  '이하 유지'는 한도 게이지로 구분), 기록 상세·통계 막대 재배치
- 노트 페이지: UIScrollView 기반 핀치줌(두 손가락, fit~4배, 배치 모드에선 잠금)
- 줄 노트 줄 간격 설정(좁게/보통/넓게/아주 넓게, 페이지별 저장·내보내기 반영)
- 새 문자열 en/ja 번역 추가

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 03:46:58 +09:00
songyc macbook
1f77264852 fix(startup): survive store open failures instead of crashing before splash
일기 기능의 스키마 변경(모델 4종 추가) 후 기존 데이터가 있는 기기에서 첫 실행 시
마이그레이션이 필요한데, 이때 위젯 프로세스와의 스토어 경합이나 마이그레이션 실패가
발생하면 makeContainer()가 곧장 fatalError로 죽어 스플래시도 못 띄우는 문제 방어:
- 일시적 경합 대비 최대 3회 재시도(점증 대기)
- 그래도 실패하면 스토어를 타임스탬프 백업으로 보존 후 새로 생성해 앱은 반드시 켜지게
- 검증: 스토어 파일 고의 손상 → 백업 생성 + 정상 부팅 확인

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 03:15:38 +09:00
songyc macbook
8c803d4d6e feat(brand): new geometric logo — day ring + footsteps, applied to all app icons and splash
- DesignAssets/AppLogo.svg 벡터 원본 (하루=열린 링, 지금=골드 점, 다님=발자국 캡슐 2개)
- iOS·워치 앱·워치 위젯 AppIcon + 스플래시 AppLogo 전부 교체 (기존 플레이스홀더 삭제)
- CoreGraphics 렌더로 불투명(알파 없음) 1024px PNG 생성 — 앱 아이콘 알파 채널 이슈 해소

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 03:02:00 +09:00
songyc macbook
40d917d4e2 feat(diary): add iPad-only premium diary tab with calendar, pencil notes, and export
- 달력(작성일 마커: 기분 이모지/연필 점) → 날짜별 일기, 이번 달 작성 수 표시
- 첫 페이지: 날짜·오늘 기분(이모지/사진, 끄기 옵션)·할 일 체크리스트(스크리블 입력)·
  타임테이블·통계(내보내기 스냅숏 재사용으로 화면·내보내기 일치)
- 노트 페이지: PencilKit 캔버스(도구 팔레트) + 줄 노트 배경 + 사진/도형(사각형·원·화살표·선)
  배치 모드(드래그·핀치), 페이지 무한 추가 — 논리 크기 768×1024 고정으로 WYSIWYG 내보내기
- 내보내기: 구간/복수 날짜(MultiDatePicker) → PDF 1개 또는 날짜별 세로 스티치 PNG
- SwiftData 모델 4종(CloudKit 호환 패턴) 스키마 추가, PremiumFeature.diary,
  iPhone 탭 컨텍스트(탭바·더보기·라디얼)에서 일기 제외, en/ja 번역 39건
- 검증 인자: -diarySeed/-diaryOpenToday/-diaryPage N/-diaryShowExport/-diaryExportRun pdf|image

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 02:51:30 +09:00
songyc macbook
5c3017aeaa fix(l10n): complete ko/en/ja coverage — sync catalogs, translate 123 strings, localize stats titles and filter sheet
- 카탈로그 4종 xcstringstool sync + stale 키 64개 제거
- 버블 메뉴·위젯 5종·이미지 내보내기 신규 문자열 en/ja 전량 번역
- StatsTabView 카드 제목·RecordFilterSheet 제목이 String 파라미터라 미현지화되던 것을 LocalizedStringKey로 수정
- HistoryView 필터 칩 문자열 String(localized:) 누락 수정
- 위젯 익스텐션 InfoPlist.xcstrings 신설(표시 이름 현지화), iOS에 사진 권한 문구 ko/en/ja 추가, 워치 ja 앱 이름 'Haru Danim'으로 통일

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 02:24:28 +09:00
songyc macbook
cde4c4001b feat(export): add high-res image export of records and stats as report posters
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 02:05:16 +09:00
songyc macbook
b897db47db fix(widget): resolve white-on-white rendering bug in Liquid Glass and tinted themes
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 01:55:54 +09:00
songyc macbook
221dce1259 refactor(ui): redesign floating menu as one-hand glass bubble arc
The vertical capsule stack reached ~414pt up the screen, putting the top
tabs out of thumb range. Replace it with 'Glass Bubbles': liquid-glass
orbs that fan out from the FAB along a semicircular arc whose radius
(~152pt, clamped to screen width) keeps every tab inside the natural
thumb sweep from the bottom-center pivot.

- Each bubble: ultraThinMaterial circle + top white gradient (specular
  light) + white 0.4 hairline + soft shadow; label with shadow below.
  Current tab rendered as green glass with white symbol.
- Entrance: bubbles fly from the FAB to their arc slot while rotating
  -40deg -> 0 with a snappy spring (response 0.32, damping 0.72) and a
  per-item 0.03s stagger, like droplets bursting in sequence; collapse
  snaps back with no delay. All transform-only (offset/scale/opacity/
  rotation) so no per-frame blur recomputation.
- Struct renamed FloatingCapsuleMenu -> GlassBubbleMenu; storage key and
  NavStyle.radial rawValue unchanged for compatibility.
- Settings copy updated: nav style now '글래스 버블 메뉴' with a
  description of the fan-out and one-handed reach; order editor renamed
  '버블 메뉴 순서' with left-to-right arc wording.

Verified: clean rebuild (stale incremental link produced an old binary
despite BUILD SUCCEEDED; wiped DerivedData), expanded-arc screenshot
shows all 7 bubbles within thumb radius with legible labels, and the
settings screen shows the new name/description.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 01:31:45 +09:00
songyc macbook
49dd1d0ff2 feat(widgets): complete redesign of 5 widget types with modular Intents, fixed floating menu UI/Strings
Widget system rebuilt as 5 independent widgets, each with its own
WidgetConfigurationIntent registered in the WidgetBundle:

- ① ActionRun: multi-action selection, value display option (day/week/
  month/hidden), full tag-color cells; small 1 / medium 4 (2x2) / large
  4 big cells or 8 compact cells (2x4) via largeStyle. Unfilled slots
  render as dashed blank cells.
- ② GoalProgress: multi-goal selection; medium [2 goals | goal+top
  quests], large [4 goals | 2x goal+quests | 1 goal + all quests] via
  medium/largeStyle. New QuestBarRow / GoalWithQuestsCellView.
- ③ QuestRing: multi-quest selection + span; surface-card ring (tag
  color) with centered icon, name and "오늘 N%" text; interactive run
  via RunActionIntent; small 1 / medium 2 / large 4 (2x2).
- ④ QuestStatus (display-only): goal selection + span; rings with name
  only (no %), goal icon+name top-left; small 4 (2x2) / medium 8 (4x2) /
  large [16 (4x4) | 4 goals | 2 goals] via largeStyle.
- ⑤ StatsChart: multi-action selection capped per family (2/4/6) +
  3 span modes; same design scaled by family.

Common foundation:
- Theme option revived on every intent: match app / light fixed / dark
  fixed (WidgetThemeOption AppEnum) applied through widgetAppTheme(_:)
  with proper iOS 17 containerBackground; non-fullColor rendering modes
  (tinted/clear/accented) keep the Color.clear + semantic-color defense
  so content never goes white-on-white.
- Providers are family-aware (capacity by size) and slot-pad selections
  (WidgetStore.slots); defaults fill from existing data so fresh widgets
  never look empty.
- Interactive path unchanged: RunActionIntent(actionID:) +
  IntentStore.performWrite -> reloadAllTimelines.

Floating menu polish:
- All glass capsules now share a uniform width (longest label wins,
  locale-proof) for a tidy popped-up list.
- Settings strings updated: nav style renamed to '플로팅 글래스 캡슐'
  with description matching the capsule popup, order editor retitled
  '캡슐 메뉴 순서' with bottom-to-top wording.

Verified: BUILD SUCCEEDED (iPhone 17 Pro sim); widget preview harness
extended with per-variant scroll anchors and all 15 layout variants
screenshot-checked, including forced accented mode (legible translucent
cells) and blank-slot rendering; capsule menu and settings text
screenshot-checked.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-13 01:17:39 +09:00