diff options
| author | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-09-25 09:10:31 +0200 |
|---|---|---|
| committer | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-09-25 09:10:31 +0200 |
| commit | 760a61001edafb462ca9c7f5bc8013f31fb15a5c (patch) | |
| tree | 50f906de9ddaefb7362d444937f7ff4177ee2a7a /src/lib/shared/routine-metrics.ts | |
| parent | e5e1482b1f5aea4a50de44801c81c81750042201 (diff) | |
Compress comments to terse single lines within line width
Diffstat (limited to 'src/lib/shared/routine-metrics.ts')
| -rw-r--r-- | src/lib/shared/routine-metrics.ts | 30 |
1 files changed, 6 insertions, 24 deletions
diff --git a/src/lib/shared/routine-metrics.ts b/src/lib/shared/routine-metrics.ts index 7758f27..4cff240 100644 --- a/src/lib/shared/routine-metrics.ts +++ b/src/lib/shared/routine-metrics.ts @@ -1,7 +1,4 @@ -// Pure routine metrics, shared by server services and UI. No db access. -// All timestamps are ISO strings; calendar math uses Temporal in UTC: due -// dates anchor on UTC calendar days, not exact 24h intervals: a daily -// routine done yesterday is due today, whatever the time of day. +// Pure routine metrics shared by server and UI; ISO timestamps, UTC calendar. const UTC = 'UTC'; @@ -78,7 +75,7 @@ export interface RoutineState { /** Time past due, in units of the routine's own frequency (0 if not due). */ overdueRatio: number; status: RoutineStatus; - /** 100 on schedule, 50 when a full period overdue, 0 at two periods, floor at 0. */ + /** 100 on schedule, 50 one period overdue, 0 at two periods. */ health: number; } @@ -90,10 +87,7 @@ export function computeRoutineState( const lastDone = maxInstant(parseCompletions(routine.id, completions)); const reference = lastDone ?? parseInstant(routine.createdAt, now); const period = periodMs(routine.frequencyDays); - // Calendar-day anchor: the period starts at midnight of the reference day, - // so any new calendar day past the frequency flips the routine to due. - // A never-done routine has no completed period: its creation day is its - // due date, so it ages exactly like a done one whose anchor is creation. + // Calendar-day anchor: the period starts at the reference day's midnight. const due = reference .toZonedDateTimeISO(UTC) .startOfDay() @@ -138,7 +132,7 @@ export interface HealthPoint { health: number; } -/** Health at instant t given the reference anchor (creation or last completion). */ +/** Health at t given the reference anchor (creation or last completion). */ function healthAtPoint( reference: Temporal.Instant, frequencyDays: number, @@ -155,14 +149,7 @@ function healthAtPoint( return Math.max(0, Math.round(100 - Math.max(0, rawRatio) * 50)); } -/** - * Daily health samples from the routine's creation to now: 100 right after a - * completion, then a linear decay to 0 once two full periods are overdue - * (sawtooth). - * Each sample anchors on the latest completion at or before it (or creation, - * which is then itself the due date for a never-done routine). - * Uses the routine's current frequency across the whole history. - */ +/** Daily health samples: 100 at completion, decaying while overdue. */ export function computeHealthSeries( routine: RoutineInput, completions: CompletionInput[], @@ -210,12 +197,7 @@ export function computeHealthSeries( return points; } -/** - * Project health series: daily mean of per-routine health across the routines - * alive that day (createdAt <= t). Same sawtooth as the per-routine series, - * so the project curve ends at the current health score. Empty when no - * routines. - */ +/** Project health: daily mean of alive routines' health, same sawtooth. */ export function computeProjectHealthSeries( routines: RoutineInput[], completions: CompletionInput[], |
