From aa3049a14c8cc668b51aac1c4a9806d2e2ea3241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Thu, 8 Oct 2026 18:45:01 +0200 Subject: [PATCH] Emit the strain device block on every wellness read The published WellnessScoreValue lists every field the engine sends, and the contract test holds the two sets equal. The computed path now sends device: null like anchor and components, and the device path has its own contract case. --- .../derived-wellness-value-contract.test.ts | 25 +++++++++++++++++++ src/lib/insights/derived/wellness-scores.ts | 1 + 2 files changed, 26 insertions(+) diff --git a/src/__tests__/derived-wellness-value-contract.test.ts b/src/__tests__/derived-wellness-value-contract.test.ts index 9034c98da..d58de8d62 100644 --- a/src/__tests__/derived-wellness-value-contract.test.ts +++ b/src/__tests__/derived-wellness-value-contract.test.ts @@ -112,4 +112,29 @@ describe("published WellnessScoreValue", () => { Object.keys(derived.value as unknown as Record).sort(), ); }); + + it("accepts the strain value served from the device's day strain", async () => { + findMany.mockImplementation(async (args: { where: { type: string } }) => + args.where.type === "DAY_STRAIN" + ? [ + { + value: 12.6, + measuredAt: new Date("2026-06-01T04:00:00Z"), + source: "WHOOP", + }, + ] + : [], + ); + const derived = await computeWellnessScore("STRAIN_SCORE", "u1", PROFILE, { + now: NOW, + }); + expect(derived.status).toBe("ok"); + if (derived.status !== "ok") return; + const parsed = wellnessScoreValue.safeParse(derived.value); + expect(parsed.error?.issues ?? []).toEqual([]); + expect(Object.keys(wellnessScoreValue.shape).sort()).toEqual( + Object.keys(derived.value as unknown as Record).sort(), + ); + findMany.mockReset(); + }); }); diff --git a/src/lib/insights/derived/wellness-scores.ts b/src/lib/insights/derived/wellness-scores.ts index c60148976..e41f66f0e 100644 --- a/src/lib/insights/derived/wellness-scores.ts +++ b/src/lib/insights/derived/wellness-scores.ts @@ -287,6 +287,7 @@ export async function computeWellnessScore( .reverse(), anchor, components, + device: null, }, coverage: { requiredInputs: 1,