fix(sync): bind sync engine to its user DB, scope instructions/templates per account, harden navigation

This commit is contained in:
Yun Chan 2026-09-28 00:53:42 +09:00
parent 1b8fe445f3
commit 9aa7302944
30 changed files with 2614 additions and 386 deletions

View file

@ -0,0 +1,31 @@
// src/main/services/history-stats.ts
// 대시보드 통계 정책(순수 함수). 누적 값은 저장된 카운터가 아니라 history 테이블에서 계산한다 —
// 동기화·로컬 모드 가져오기·삭제로 들어오고 나간 행도 그대로 반영되도록.
/** 로컬 날짜 키(YYYY-MM-DD). SQLite date(created_at/1000,'unixepoch','localtime') 와 같은 형식. */
export function localDayKey(date: Date): string {
const y = date.getFullYear()
const m = String(date.getMonth() + 1).padStart(2, '0')
const d = String(date.getDate()).padStart(2, '0')
return `${y}-${m}-${d}`
}
/**
* 연속 사용일. 오늘(또는 오늘 아직 기록이 없으면 어제)부터 거꾸로 하루도 빠짐없이 기록이 있는 날 수.
* @param dayKeys 기록이 있는 로컬 날짜 키들(중복·순서 무관)
*/
export function computeStreakDays(dayKeys: Iterable<string>, today: Date = new Date()): number {
const days = new Set(dayKeys)
if (days.size === 0) return 0
const cursor = new Date(today.getFullYear(), today.getMonth(), today.getDate())
if (!days.has(localDayKey(cursor))) {
cursor.setDate(cursor.getDate() - 1)
if (!days.has(localDayKey(cursor))) return 0
}
let streak = 0
while (days.has(localDayKey(cursor))) {
streak++
cursor.setDate(cursor.getDate() - 1)
}
return streak
}