From 9d2901aaf98032ab4098d2285cc1317be425b3b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Thu, 21 May 2026 17:35:10 +0200 Subject: [PATCH] refactor(rollups): retire v1.4.39 W-SUM legacy-NULL UNION discovery arm The `sum_value IS NULL` UNION arm in `enqueueBootTimeRollupBackfill` was added in v1.4.39 W-SUM to converge DAY rollup rows that pre-dated the writer change. Production data has since converged, so the arm is a permanent no-op seq scan over `measurement_rollups`. Per-day missing coverage remains the sole discovery anchor. Drops the legacy text-anchor unit test. The read-side `mean * count` fallback in `/api/dashboard/summary` retains legacy-row readability and stays covered by its dedicated route test. --- .../__tests__/measurement-rollups.test.ts | 24 ---------- src/lib/rollups/measurement-rollups.ts | 47 ++++++++----------- 2 files changed, 19 insertions(+), 52 deletions(-) diff --git a/src/lib/rollups/__tests__/measurement-rollups.test.ts b/src/lib/rollups/__tests__/measurement-rollups.test.ts index f5d056e85..7a5891898 100644 --- a/src/lib/rollups/__tests__/measurement-rollups.test.ts +++ b/src/lib/rollups/__tests__/measurement-rollups.test.ts @@ -543,30 +543,6 @@ describe("enqueueBootTimeRollupBackfill", () => { expect(bossSend).not.toHaveBeenCalled(); }); - // v1.4.39 W-SUM — the discovery query now unions in users whose - // existing DAY rollup rows carry `sum_value IS NULL`. Re-folding - // converges those rows because `persistRollupRows` always writes the - // new column on upsert; the union keeps the per-day missing-coverage - // gap (v1.4.39.1) and the legacy-NULL backfill on the same indexed - // pass. - it("includes the sum_value IS NULL branch in the discovery query", async () => { - getGlobalBossMock.mockReturnValue({ send: bossSend }); - queryRaw.mockResolvedValueOnce([{ id: "user-with-legacy-rollups" }]); - bossSend.mockResolvedValueOnce("job-id"); - - const result = await enqueueBootTimeRollupBackfill(); - - expect(result).toEqual({ enqueued: 1, skipped: 0, error: null }); - // The discovery SQL surfaces both per-day missing coverage AND - // legacy NULL sum_value rows under one UNION. The text-anchor is - // the only durable assertion at the unit level — the integration - // suite covers the planner shape on real Postgres. - const sqlParts = queryRaw.mock.calls[0][0] as TemplateStringsArray; - const sqlText = Array.isArray(sqlParts) ? sqlParts.join("?") : ""; - expect(sqlText).toContain("sum_value"); - expect(sqlText).toContain("UNION"); - }); - // v1.4.39.1 — the discovery anchor moved from per-type to per-day so // accounts whose Withings sync / `/api/import` / admin restore wrote // measurements without firing the rollup write hook get re-enqueued diff --git a/src/lib/rollups/measurement-rollups.ts b/src/lib/rollups/measurement-rollups.ts index 897789a30..a6de1b45f 100644 --- a/src/lib/rollups/measurement-rollups.ts +++ b/src/lib/rollups/measurement-rollups.ts @@ -752,35 +752,26 @@ export async function enqueueBootTimeRollupBackfill(): Promise<{ // index path. The LEFT JOIN walks `measurement_rollups` against // its composite primary key. // - // v1.4.39 W-SUM — the discovery also surfaces users whose existing - // DAY rollup rows carry `sum_value IS NULL`. Those rows pre-date - // the v1.4.39 writer change; re-folding the user converges them - // because `persistRollupRows` always writes the new column on - // upsert. The union runs in one query so the per-day coverage gap - // and the legacy-NULL backfill share a single planner pass. + // v1.4.41 — the v1.4.39 W-SUM legacy-NULL `sum_value` UNION arm + // has been retired. Marc's tenant converged at v1.4.40, so the + // arm was a permanent no-op seq scan over `measurement_rollups`. + // Per-day missing coverage remains the sole discovery anchor. const users = await prisma.$queryRaw>` - SELECT DISTINCT id FROM ( - SELECT DISTINCT mt."user_id" AS id - FROM ( - SELECT DISTINCT - m."user_id", - m."type", - date_trunc('day', m."measured_at") AS bucket_start - FROM measurements m - WHERE m."deleted_at" IS NULL - ) mt - LEFT JOIN measurement_rollups r - ON r."user_id" = mt."user_id" - AND r."type" = mt."type" - AND r."granularity" = 'DAY' - AND r."bucket_start" = mt."bucket_start" - WHERE r."bucket_start" IS NULL - UNION - SELECT DISTINCT r2."user_id" AS id - FROM measurement_rollups r2 - WHERE r2."granularity" = 'DAY' - AND r2."sum_value" IS NULL - ) discovery + SELECT DISTINCT mt."user_id" AS id + FROM ( + SELECT DISTINCT + m."user_id", + m."type", + date_trunc('day', m."measured_at") AS bucket_start + FROM measurements m + WHERE m."deleted_at" IS NULL + ) mt + LEFT JOIN measurement_rollups r + ON r."user_id" = mt."user_id" + AND r."type" = mt."type" + AND r."granularity" = 'DAY' + AND r."bucket_start" = mt."bucket_start" + WHERE r."bucket_start" IS NULL `; if (users.length === 0) {