aboutsummaryrefslogtreecommitdiff
path: root/src/lib/shared
diff options
context:
space:
mode:
authorMartin Kagamino Lehoux <martin@lehoux.net>2026-09-25 09:10:31 +0200
committerMartin Kagamino Lehoux <martin@lehoux.net>2026-09-25 09:10:31 +0200
commit760a61001edafb462ca9c7f5bc8013f31fb15a5c (patch)
tree50f906de9ddaefb7362d444937f7ff4177ee2a7a /src/lib/shared
parente5e1482b1f5aea4a50de44801c81c81750042201 (diff)
Compress comments to terse single lines within line width
Diffstat (limited to 'src/lib/shared')
-rw-r--r--src/lib/shared/routine-metrics.test.ts2
-rw-r--r--src/lib/shared/routine-metrics.ts30
-rw-r--r--src/lib/shared/temporal.ts3
3 files changed, 8 insertions, 27 deletions
diff --git a/src/lib/shared/routine-metrics.test.ts b/src/lib/shared/routine-metrics.test.ts
index 64b5da9..5bc0a78 100644
--- a/src/lib/shared/routine-metrics.test.ts
+++ b/src/lib/shared/routine-metrics.test.ts
@@ -49,7 +49,7 @@ describe('computeRoutineState', () => {
it('is due the calendar day after completion for a daily routine', () => {
const daily = { ...routine, frequencyDays: 1 };
const doneAt = '2026-09-07T20:00:00.000Z'; // yesterday evening
- const now = Temporal.Instant.from('2026-09-08T08:00:00.000Z'); // this morning, <24h later
+ const now = Temporal.Instant.from('2026-09-08T08:00:00.000Z'); // <24h later
const state = computeRoutineState(daily, [{ routineId: 1, doneAt }], now);
expect(state.status).toBe('due');
});
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[],
diff --git a/src/lib/shared/temporal.ts b/src/lib/shared/temporal.ts
index 7097ba3..103f209 100644
--- a/src/lib/shared/temporal.ts
+++ b/src/lib/shared/temporal.ts
@@ -1,5 +1,4 @@
-// Shared Temporal display helpers. Storage and logic stay in ISO instants;
-// these format one for the viewer in their own timezone.
+// Temporal display helpers: format ISO instants for the viewer's timezone.
/** Format an ISO instant in the viewer's timezone. */
export function formatInstant(