From 1f49041025eca10c1ae0e8e047703af9ceae78cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Thu, 21 May 2026 11:41:05 +0200 Subject: [PATCH] fix(summaries-slice): exclude soft-deleted measurements The four `$queryRaw` blocks in `computeFromRollups` and `computeFromLiveAggregate` (narrow aggregate + DISTINCT ON latest, both fast and cold paths) folded every row regardless of `deleted_at`. The DAY-bucket rollup aggregate is unaffected because its source table is already filtered by the writer. Add `AND m."deleted_at" IS NULL` to every `FROM measurements m` WHERE clause so the slim slice's avg7/avg30/slope/r2 plus the per-type latest never reflect a row the user soft-deleted. --- src/lib/analytics/summaries-slice.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lib/analytics/summaries-slice.ts b/src/lib/analytics/summaries-slice.ts index dee43ceee..33dd0dd4a 100644 --- a/src/lib/analytics/summaries-slice.ts +++ b/src/lib/analytics/summaries-slice.ts @@ -301,6 +301,7 @@ async function computeFromRollups(userId: string): Promise { )::double precision AS r2_90 FROM measurements m WHERE m."user_id" = ${userId} + AND m."deleted_at" IS NULL GROUP BY m."type" `, prisma.$queryRaw` @@ -310,6 +311,7 @@ async function computeFromRollups(userId: string): Promise { m."measured_at" AS measured_at FROM measurements m WHERE m."user_id" = ${userId} + AND m."deleted_at" IS NULL ORDER BY m."type", m."measured_at" DESC `, // v1.4.37.2 hotfix — the v1.4.35 implementation read EVERY DAY @@ -487,6 +489,7 @@ async function computeFromLiveAggregate( )::double precision AS r2_90 FROM measurements m WHERE m."user_id" = ${userId} + AND m."deleted_at" IS NULL GROUP BY m."type" `, prisma.$queryRaw` @@ -496,6 +499,7 @@ async function computeFromLiveAggregate( m."measured_at" AS measured_at FROM measurements m WHERE m."user_id" = ${userId} + AND m."deleted_at" IS NULL ORDER BY m."type", m."measured_at" DESC `, ]);