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

798 lines
17 KiB
Plaintext

{
"sourceLanguage": "ko",
"strings": {
"%@": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "%@"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "%@"
}
}
}
},
"%@ %@": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "%@ %@"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "%@ %@"
}
},
"ko": {
"stringUnit": {
"state": "new",
"value": "%1$@ %2$@"
}
}
}
},
"%@ %lld%%": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "%@ %lld%%"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "%@ %lld%%"
}
},
"ko": {
"stringUnit": {
"state": "new",
"value": "%1$@ %2$lld%%"
}
}
}
},
"%@ +%lld": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "%@ +%lld"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "%@ +%lld"
}
},
"ko": {
"stringUnit": {
"state": "new",
"value": "%1$@ +%2$lld"
}
}
}
},
"%lld": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "%lld"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "%lld"
}
}
}
},
"%lld%%": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "%lld%%"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "%lld%%"
}
}
}
},
"%lld분": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "%lldm"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "%lld分"
}
}
}
},
"%lld시간": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "%lldh"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "%lld時間"
}
}
}
},
"%lld시간 %lld분": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "%lldh %lldm"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "%lld時間%lld分"
}
},
"ko": {
"stringUnit": {
"state": "new",
"value": "%1$lld시간 %2$lld분"
}
}
}
},
"%lld초": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "%llds"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "%lld秒"
}
}
}
},
"+%lld": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "+%lld"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "+%lld"
}
}
}
},
"iPhone 앱의 설정 → 프리미엄에서 잠금 해제해 주세요": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Unlock in the iPhone app: Settings → Premium"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "iPhoneアプリの設定→プレミアムでロックを解除してください"
}
}
}
},
"iPhone과 연결 중...": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Connecting to iPhone..."
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "iPhoneに接続中..."
}
}
}
},
"iPhone에 연결할 수 없어요. 근처에 있는지 확인해 주세요.": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Can't reach your iPhone. Make sure it's nearby."
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "iPhoneに接続できません。近くにあるか確認してください。"
}
}
}
},
"기간": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Period"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "期間"
}
}
}
},
"꼬리표 없음": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "No tag"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "タグなし"
}
}
}
},
"다짐": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Quest"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "クエスト"
}
}
}
},
"다짐 달성률": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Quest Progress"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "クエスト達成率"
}
}
}
},
"다짐 없음": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "No quest"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "クエストなし"
}
}
}
},
"목표": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Goals"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "目標"
}
}
}
},
"목표 달성률": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Goal Progress"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "目標達成率"
}
}
}
},
"목표 없음": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "No goal"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "目標なし"
}
}
}
},
"새로고침": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Refresh"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "更新"
}
}
}
},
"선택한 다짐의 달성률을 표시해요. 한도형 다짐은 상태로 표시돼요. (프리미엄)": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Shows the selected quest's progress. Limit quests show their status. (Premium)"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "選択したクエストの達成率を表示します。上限型はステータス表示になります。(プレミアム)"
}
}
}
},
"선택한 목표의 하루/주간/월간 달성률을 표시해요. (프리미엄)": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Shows the selected goal's daily/weekly/monthly progress. (Premium)"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "選択した目標の日/週/月の達成率を表示します。(プレミアム)"
}
}
}
},
"실행 중 아님": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Not running"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "実行中なし"
}
}
}
},
"앱을 열면 새로고침돼요": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Open the app to refresh"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "アプリを開くと更新されます"
}
}
}
},
"없음": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "None"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "なし"
}
}
}
},
"오늘 %@": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Today %@"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "今日 %@"
}
}
}
},
"오늘 %lld회": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Today %lld times"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "今日%lld回"
}
}
}
},
"월간": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Monthly"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "月間"
}
}
}
},
"주간": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Weekly"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "週間"
}
}
}
},
"즐겨찾기": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Favorites"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "お気に入り"
}
}
}
},
"초과": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Over"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "超過"
}
}
}
},
"측정 중": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Tracking"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "計測中"
}
}
}
},
"측정 중인 행동과 경과 시간을 표시해요. (프리미엄)": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Shows the running action and elapsed time. (Premium)"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "計測中のアクションと経過時間を表示します。(プレミアム)"
}
}
}
},
"측정 표시 새로고침 필요": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Timer display needs a refresh"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "計測表示の更新が必要"
}
}
}
},
"측정 표시가 오래됐어요": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Timer display is out of date"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "計測表示が古くなっています"
}
}
}
},
"표시할 다짐과 기간을 선택하세요.": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Choose a quest and period to display."
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "表示するクエストと期間を選んでください。"
}
}
}
},
"표시할 목표와 기간을 선택하세요.": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Choose a goal and period to display."
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "表示する目標と期間を選んでください。"
}
}
}
},
"프리미엄": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Premium"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "プレミアム"
}
}
}
},
"프리미엄 기능": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Premium Features"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "プレミアム機能"
}
}
}
},
"하루": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Daily"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "1日"
}
}
}
},
"하루 다님": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Haru Danim"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "ハルダニム"
}
}
}
},
"한도": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Limit"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "上限"
}
}
}
},
"한도 안": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Within"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "上限内"
}
}
}
},
"한도 초과": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Over limit"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "上限超過"
}
}
}
},
"현재 현황": {
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Current Status"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "現在の状況"
}
}
}
}
},
"version": "1.0"
}