mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
fix(insights): exclude soft-deleted measurements in remaining measurement.findMany sites
W-DELETED closed the dashboard, analytics, summaries and rollup tiers but the Insights cluster (tile-strip, AI Coach snapshot, GLP-1 plateau detector, pulse-status helper) still walked `prisma.measurement.findMany` without filtering tombstoned rows. Once iOS sync starts emitting deletions any soft-deleted reading would still contribute to: - /api/insights/targets 30-day average + 1-year latest-ever tile values (recentMeasurements, latestEverByType, glucoseRows) - /api/insights/cards 90-day weight/BP/pulse window the iOS-adapter card stream consumes - /api/insights/generate per-type aggregate payload feeding the AI prompt - Coach prompt feature aggregator (lib/insights/features.ts) - GLP-1 plateau detection window (lib/insights/glp1-plateau.ts) - Pulse-status snapshot input (lib/insights/pulse-status.ts) Add `deletedAt: null` to every remaining production `where` clause. `comprehensive-aggregator.ts` already filtered; `ai/coach/snapshot.ts` already filtered. Closes senior H1 from the v1.4.40 QA round.
This commit is contained in:
1 parent
99b4fde002
commit
926ac36dea
6 files changed
+12
-4
No files matched your search
@@ -77,6 +77,7 @@ export const GET = apiHandler(async () => {
|
||||
in: ["WEIGHT", "BLOOD_PRESSURE_SYS", "BLOOD_PRESSURE_DIA", "PULSE"],
|
||||
},
|
||||
measuredAt: { gte: ninetyDaysAgo },
|
||||
deletedAt: null,
|
||||
},
|
||||
orderBy: { measuredAt: "asc" },
|
||||
select: { type: true, value: true, measuredAt: true },
|
||||
|
||||
@@ -134,7 +134,7 @@ async function buildComparisonSnapshotForUser(
|
||||
const rows = await Promise.all(
|
||||
types.map(async (type) => {
|
||||
const measurements = await prisma.measurement.findMany({
|
||||
where: { userId, type },
|
||||
where: { userId, type, deletedAt: null },
|
||||
orderBy: { measuredAt: "asc" },
|
||||
select: { measuredAt: true, value: true },
|
||||
});
|
||||
|
||||
@@ -178,11 +178,15 @@ async function buildTargetsResponse(user: AuthedUser) {
|
||||
const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
|
||||
|
||||
// Fetch all measurements in the last 30 days + the latest for each type
|
||||
// Soft-delete filter mirrors the W-DELETED pattern: tombstoned rows
|
||||
// must not contribute to tile averages / latest values once iOS sync
|
||||
// starts emitting deletions.
|
||||
const recentMeasurements = await prisma.measurement.findMany({
|
||||
where: {
|
||||
userId,
|
||||
type: { in: types },
|
||||
measuredAt: { gte: thirtyDaysAgo },
|
||||
deletedAt: null,
|
||||
},
|
||||
orderBy: { measuredAt: "desc" },
|
||||
select: { type: true, value: true, measuredAt: true },
|
||||
@@ -207,6 +211,7 @@ async function buildTargetsResponse(user: AuthedUser) {
|
||||
userId,
|
||||
type: { in: types },
|
||||
measuredAt: { gte: oneYearAgo },
|
||||
deletedAt: null,
|
||||
},
|
||||
orderBy: { measuredAt: "desc" },
|
||||
distinct: ["type"],
|
||||
@@ -1193,7 +1198,7 @@ async function buildTargetsResponse(user: AuthedUser) {
|
||||
};
|
||||
const thirtyDaysAgoGlucose = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
|
||||
const glucoseRows = await prisma.measurement.findMany({
|
||||
where: { userId, type: "BLOOD_GLUCOSE" },
|
||||
where: { userId, type: "BLOOD_GLUCOSE", deletedAt: null },
|
||||
orderBy: { measuredAt: "desc" },
|
||||
select: { value: true, measuredAt: true, glucoseContext: true },
|
||||
});
|
||||
|
||||
@@ -377,8 +377,8 @@ export async function extractFeatures(
|
||||
: null;
|
||||
const measurements = await prisma.measurement.findMany({
|
||||
where: sinceCutoff
|
||||
? { userId, measuredAt: { gte: sinceCutoff } }
|
||||
: { userId },
|
||||
? { userId, measuredAt: { gte: sinceCutoff }, deletedAt: null }
|
||||
: { userId, deletedAt: null },
|
||||
orderBy: { measuredAt: "asc" },
|
||||
});
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ export async function detectGlp1Plateau(
|
||||
userId,
|
||||
type: "WEIGHT",
|
||||
measuredAt: { gte: windowStart },
|
||||
deletedAt: null,
|
||||
},
|
||||
orderBy: { measuredAt: "asc" },
|
||||
select: { value: true, measuredAt: true },
|
||||
|
||||
@@ -158,6 +158,7 @@ export async function generatePulseStatusForUser(
|
||||
where: {
|
||||
userId,
|
||||
type: "PULSE",
|
||||
deletedAt: null,
|
||||
},
|
||||
orderBy: { measuredAt: "desc" },
|
||||
take: 365,
|
||||
|
||||
Reference in new issue
Block a user