mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-15 06:52:04 +00:00
feat(insights): widen per-card window from 30 days to 360+24 buckets
Every per-card KI insight generator was clipping each metric to the
last 30 daily means before sending the prompt. The model therefore
saw a one-month window per metric — far too narrow to detect drift
that plays out over a year, and the cause of repeated complaints that
a "Stable" trend assessment ignored an obvious 9-month decline.
New shared helper `applyPayloadBudget()` builds a `{ daily, monthly }`
view: the most recent 360 days as daily means (`dayOffset 0..359`)
plus 24 thirty-day windows for the older history (`monthOffset
12..35`). Empty buckets are dropped. If the canonical payload would
serialise above 50 KB the helper transparently re-buckets at 180
daily days so the prompt token budget stays bounded; a per-generator
`annotate({ payload_size_bytes })` makes the chosen window
observable in Wide Events.
All seven generators now consume the bucketed view as the metric
`series` field (general-status, blood-pressure-status, pulse-status,
weight-status, bmi-status, mood-status, medication-compliance-
status) — including their cross-metric joins (BP-pair, weight ↔ mean
BP correlation, medication-compliance per day) which are rebuilt on
top of the shared `dayOffset` instead of date strings. Mood and
medication queries widened to ~3 years so the older monthly window
can actually be filled.
One focused vitest per generator captures the prompt that goes to the
provider, JSON-parses the embedded snapshot, and asserts every
metric series carries both `daily` and `monthly` arrays with the
expected shape. The bucketing helper also has its own unit tests
covering offsets, leap-year-safe Berlin-day boundaries, and the
50 KB → 180-day fallback.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
c3ca8614a6
commit
1adda80944
17 files changed
+1379
-481
No files matched your search
@@ -53,12 +53,11 @@ describe("POST /api/feedback bug-report toggle gate", () => {
|
||||
category: "BUG",
|
||||
subject: "test",
|
||||
description: "Anything at least ten characters long.",
|
||||
}),
|
||||
}) as never,
|
||||
);
|
||||
expect(res.status).toBe(503);
|
||||
const body = (await res.json()) as { error: string };
|
||||
expect(body.error).toMatch(/disabled/i);
|
||||
// Must not even attempt to create the row when the toggle is off.
|
||||
expect(prisma.feedback.create).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -78,7 +77,7 @@ describe("POST /api/feedback bug-report toggle gate", () => {
|
||||
category: "BUG",
|
||||
subject: "test",
|
||||
description: "Anything at least ten characters long.",
|
||||
}),
|
||||
}) as never,
|
||||
);
|
||||
expect(res.status).toBe(201);
|
||||
expect(prisma.feedback.create).toHaveBeenCalledTimes(1);
|
||||
@@ -98,7 +97,7 @@ describe("POST /api/feedback bug-report toggle gate", () => {
|
||||
category: "BUG",
|
||||
subject: "test",
|
||||
description: "Anything at least ten characters long.",
|
||||
}),
|
||||
}) as never,
|
||||
);
|
||||
expect(res.status).toBe(201);
|
||||
expect(prisma.feedback.create).toHaveBeenCalledTimes(1);
|
||||
|
||||
Reference in new issue
Block a user