fix(compliance): carry endedAt into the streak and per-window timelines

calculateCompliance and buildTimelineForWindow built the cadence
engine's context field by field and left out endedAt, so a dose slot
after End course counted as missed in the streak and the timeline while
the rate left it out.

Both now take the context from one builder, endedAt is required on
ComplianceMedicationContext and CadenceEngineContext, and the course
anchor guard holds every builder of either type to naming it.

Refs #1280
This commit is contained in:
Marc-André Bombeck committed 2026-10-25 00:26:55 +02:00
1 parent 8fd1d543a6
commit 8b66f647cb
9 files changed
+217 -35

No files matched your search

@@ -1,7 +1,7 @@
{
"$comment": "Production functions over 200 lines, keyed \"file :: name\", and their length. Maintained by src/__tests__/source-size-ratchet.test.ts.",
"count": 351,
"total": 113619,
"count": 350,
"total": 113407,
"entries": {
"app/achievements/page.tsx :: AchievementsPage": 206,
"app/api/admin/backups/upload/route.ts :: apiHandler(arg)": 314,
@@ -257,7 +257,6 @@
"lib/ai/local-client.ts :: generateCompletionStream": 294,
"lib/ai/openai-client.ts :: generateCompletion": 335,
"lib/analytics/bp-in-target-fast-path.ts :: computeFromRollups": 203,
"lib/analytics/compliance/display.ts :: calculateCompliance": 212,
"lib/analytics/correlations-fast-path.ts :: computeCorrelationHypothesesFastPath": 256,
"lib/analytics/intraday-pulse-io.ts :: loadIntradayPulse": 206,
"lib/analytics/score/reader.ts :: computeUserHealthScore": 324,