13 Commits

Author SHA1 Message Date
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
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
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
fbd4810628 fix: resolve widget sync crashes via local AppGroup container and improve goal widget to show all sub-goals
위젯 동기화 크래시 수정:
- DataStore: CloudKit 미러링을 메인 앱 프로세스 전담으로 분리.
  위젯 등 앱 확장(.appex)은 CloudKit 엔타이틀먼트가 없고 메모리·수명
  제약으로 미러링 설정이 크래시/행을 유발하므로, 확장 프로세스는 항상
  같은 App Group 스토어 파일을 로컬 전용(cloudKitDatabase: .none)으로
  연다. 확장이 쓴 변경은 메인 앱이 히스토리로 집어 CloudKit에 내보냄
- CloudSyncMonitor 신설: 메인 앱이 NSPersistentStoreRemoteChange
  (다른 기기의 CloudKit 가져오기·위젯 인텐트의 쓰기)를 디바운스로 받아
  라이브 액티비티 → 위젯 타임라인 → 워치 스냅숏 순으로 즉시 갱신
- 인터랙티브 위젯(AppIntent)의 컨테이너 매핑 점검: IntentStore.commit이
  저장 직후 reloadAllTimelines를 이미 보장함을 확인·문서화

모음 탭 목표 진행 현황 카드 개선:
- '다짐별로 보기'의 상위 3개 제한 제거 — 모든 다짐 확인 가능
- 화면 균형을 위해 접힘/펼침 UX 적용: iPhone은 3개, iPad는 6개까지
  접힌 상태로 보여주고 '다짐 N개 더 보기' 버튼으로 카드 안에서 펼침
  (카드 탭 이동과 충돌하지 않는 독립 버튼, 스냅 애니메이션)
- DebugSeed: 접힘/펼침 검증용 4번째 다짐 추가, -expandGoalCard 인자 추가

검증: iPhone 17 Pro·iPad Pro 11 시뮬레이터에서 접힘/펼침 렌더링과
사이드바 레이아웃 확인, 전체 타깃(iOS·워치·위젯) 빌드 성공

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-11 21:35:20 +09:00
songyc macbook
3dd53c4fc6 refactor: decouple all UI preferences and layout settings from CloudKit sync to local device storage
- Add Shared/LocalPrefs.swift: device-local UI preferences stored in App Group
  UserDefaults (never synced by iCloud), read identically by app, widgets,
  watch snapshot, and App Intents on the same device
- Move to local storage: main-tab action button order (UUID array), pinned
  goal-progress cards on the main tab, goal quest-list collapse state, and
  per-action memo-prompt popup — reordering or repinning on iPhone no longer
  touches the iPad and vice versa
- Defense logic: actions not in the local order list (e.g. newly received via
  CloudKit from another device) are automatically appended to the end, sorted
  by legacy sortOrder then creation date
- One-time migration adopts existing @Model values (sortOrder, showsOnMain,
  isCollapsed, promptsForNote) into local prefs at launch; model properties
  stay in place so the CloudKit schema is untouched and records keep syncing
- Data remains fully synced: actions, goals, quests, sessions, count entries,
  statistics, and goal/tag/quest list order are untouched by this change
- Verified in simulator: legacy data migrates losslessly, grid renders from
  local order, unknown action lands at the end; iOS+watch+widgets build clean

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-11 20:58:34 +09:00
songyc macbook
9e81cd3d03 feat: auto-adapt layout for iPadOS/macOS with NavigationSplitView and hide irrelevant settings
- Add SidebarRootView: iPad/Mac (Designed for iPad) uses a NavigationSplitView
  sidebar listing all 7 tabs, sharing every existing screen (rootView) untouched
- Branch by device idiom (DeviceLayout.isPad) so iPhone keeps its tab bar UI,
  logic, and Live Activity behavior pixel-for-pixel, including landscape
- AppRouter gains sidebar mode: cross-tab routing (기록 확인/통계 보기) selects
  the target tab directly instead of detouring through the More tab
- Hide iPhone-only settings on iPad/Mac: 탭바 구성 section and the main grid's
  per-row column picker are meaningless with a sidebar/adaptive grid
- Main tab wide-screen layout: pinned goal cards flow in an adaptive grid
  (340-520pt cards) instead of full-width paging; action buttons auto-fill
  columns at 150-220pt so nothing stretches on large displays
- Verified on iPad Pro 11" simulator (sidebar, settings, stats routing,
  timetable) and iPhone 17 Pro (unchanged tab bar); both build clean

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-11 09:28:06 +09:00
songyc macbook
2567b53b71 fix: correct daily goal progress calculation and optimize widget refresh logic
- 목표 하루 진행률은 오늘이 수행일인 다짐만 모수로 계산 (요일·날짜 지정으로
  오늘 쉬는 다짐은 분모에서 제외, QuestProgress.isScheduled 신설)
- 오늘 수행할 다짐이 하나도 없는 날은 0% 대신 100%(완료 상태)로 표기
- 주간/월간 진행률은 기존대로 전체 다짐 기준 유지
- 이벤트 기반 위젯 새로 고침: 앱 내 모든 핵심 Mutation(측정 시작/종료,
  횟수 추가, 기록 추가·수정·삭제, 행동·꼬리표·목표·다짐 CRUD, 순서 변경,
  목표 상태 변경)의 끝단에서 DataChange.commit() 호출 — 저장 즉시 확정 후
  Live Activity·위젯 타임라인·워치 스냅숏을 한 번에 동기화
- 주기적 백그라운드 새로 고침 없이 변경 시점에만 갱신해 WidgetKit
  업데이트 예산 절약 (타이머 표시는 기존 Text(style: .timer)로 시스템이
  자체 렌더링하므로 타임라인 소모 없음)
- 하루 시작 시간·주 시작 요일 설정 변경 시에도 위젯 집계 갱신
- 시뮬레이터 검증: 월·수·금 다짐이 있는 목표의 토요일 하루 진행률이
  33%가 아닌 50%(오늘 수행 다짐 2개 평균)로 표시됨 확인

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-11 08:30:12 +09:00
songyc macbook
a6c040cd6a feat(i18n): 전체 UI 다국어 지원 (한국어·영어·일본어)
- 언어 설정 실적용: 변경 시 AppleLanguages 오버라이드 저장, 재시작 안내 footer
- 자동 추출되지 않던 일반 문자열(탭 이름, 픽커 라벨, 상태 뱃지, 포매터,
  삼항 문구, 심볼 카테고리 등)을 String(localized:)로 전환
- 위젯·워치 앱·컴플리케이션 타깃에 Localizable.xcstrings 신설
  (중복 리소스 방지 pbxproj 예외 추가), xcstringstool sync로 키 추출
- 4개 카탈로그 전체 키(고유 430개)에 en/ja 번역 주입
- 영어의 긴 횟수 단위("times")가 잘리지 않도록 모음 탭 셀 축소 허용
- 검증: -AppleLanguages "(en)"/"(ja)"로 모음 탭·설정 화면 확인

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-10 15:03:24 +09:00
songyc macbook
f468fdf296 feat(data): SwiftData 저장소를 App Group으로 이관하고 CloudKit 동기화 지원
- DataStore: App Group 컨테이너의 HaruDanim.store 사용, 기존 default.store 1회 자동 이관
- 프리미엄 + 동기화 토글 시 CloudKit(.private) 구성으로 컨테이너 생성, 실패하면 로컬 폴백
- CloudKit 요건(모든 관계 optional)에 맞춰 to-many 관계를 optional 저장 + 기존 이름
  접근자로 리팩터링 (originalName 매핑으로 기존 데이터 유지)
- Tag/Action/Goal/Quest에 uuid 추가 (시리 단축어·위젯·워치 식별자) + 중복 보정
- 모델 레이어(Models/Settings/DayMath/QuestProgress/Formatters/Theme)를 Shared/로 이동
  — 위젯 확장과 공유
- 집계 설정(주 시작 요일·하루 시작 시간·대표 시간·짧은 기록 무시)을 App Group defaults로
  이관해 위젯·워치와 공유, 설정의 '기기 간 동기화' 토글 활성화
- Goal.combinedSpanRatio 공용화 (모음 탭 카드·위젯·시리가 동일 산식 사용)
- DEBUG 검증 인자: -cloudSync YES, -settingsScrollPremium YES

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
2026-07-10 08:59:15 +09:00
songyc macbook
0509285a04 feat(goals): add drag-and-drop reordering and hide completed goals
- Implement drag-and-drop functionality for users to reorder the active goals list
- Ensure the custom order of goals is persistently saved and loaded
- Filter out completed goals from the main active list to reduce visual clutter
- Add a 'View Completed Goals' button to navigate to a dedicated screen for finished items
2026-07-10 04:41:11 +09:00
songyc macbook
ecc4c016f7 feat(main): implement snap-scrolling carousel for goal widgets with unified display options
- Remove the maximum limit for selected goal widgets on the main tab
- Unify the display format (aggregate vs. individual) to apply globally across all selected goals
- Redesign the horizontal scrolling into a full-width snap carousel (pagination style)
- Ensure only one widget is fully visible at a time with no adjacent cards partially showing
- Apply snap scrolling so light swipes firmly transition to the next or previous widget
2026-07-10 04:11:14 +09:00
songyc macbook
352be3e29b feat(main): allow displaying up to 3 goals on the top progress widget
- Update the goal progress widget in the main tab to support up to 3 selected goals
- Add multi-selection capabilities to the widget settings menu
- Implement a horizontal or scrollable layout for multiple goals to optimize screen space
- Maintain existing routing to specific goal detail screens upon tap
2026-07-10 03:52:51 +09:00
songyc macbook
520e625377 change folder Haru_Danim -> HaruDanim 2026-07-10 03:02:15 +09:00