From 891c85a82b5bd5f180f9dd65ab245458b340f174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Fri, 9 Oct 2026 15:25:37 +0200 Subject: [PATCH] chore(demo): seed readiness and health-score history and a start for magnesium The day view reads readiness from the nightly COMPUTED recovery row and the health score from the record of each local day; neither job reaches back, so a fresh seed showed both for today at most. Mint the rows the jobs would have written over the window, and give magnesium the start date its running line needs. --- scripts/seed-demo.ts | 112 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 3 deletions(-) diff --git a/scripts/seed-demo.ts b/scripts/seed-demo.ts index 70eb90461..7c606cb91 100644 --- a/scripts/seed-demo.ts +++ b/scripts/seed-demo.ts @@ -1045,6 +1045,112 @@ async function seed() { } } + // ── Readiness and health-score history ──── + // The day view reads readiness from the COMPUTED `RECOVERY_SCORE` row the + // nightly job files for the night that ended (noon UTC of the day before + // the wake morning, `recovery:`), and the health score from the + // `health_score_records` row of each local day. Neither job reaches back, + // so a fresh seed carried both for today at most; mint the history the + // jobs would have written over the window. + console.log("Creating readiness and health-score history..."); + const shiftKey = (key: string, by: number) => + new Date(Date.parse(`${key}T12:00:00Z`) + by * 86_400_000) + .toISOString() + .slice(0, 10); + const readinessRows: unknown[][] = []; + for (let i = 1; i < span; i++) { + const wakeKey = berlinDayKey(daysAgoAt(days - i, 7, 0)); + const endedKey = shiftKey(wakeKey, -1); + const at = new Date(`${endedKey}T12:00:00.000Z`); + const value = Math.round( + Math.min(100, Math.max(0, recovery[i] * 0.7 + 20 + jitter(4))), + ); + readinessRows.push([ + cuid(), + userId, + "RECOVERY_SCORE", + value, + "score", + "COMPUTED", + `recovery:${endedKey}`, + at, + at, + at, + ]); + } + await bulkInsert( + client, + "measurements", + [ + "id", + "user_id", + "type", + "value", + "unit", + "source", + "external_id", + "measured_at", + "created_at", + "updated_at", + ], + readinessRows, + ); + const PILLAR_BASE: Record = { + BLOOD_PRESSURE: 86, + GLYCAEMIA: 98, + ACTIVITY: 95, + SLEEP: 76, + ADIPOSITY: 97, + WELLBEING: 76, + LIPIDS: 100, + }; + const composites = randomWalk(87, 90, 60, 3, { min: 80, max: 96 }); + const scoreRows: unknown[][] = []; + for (let n = 60; n >= 1; n--) { + const pillars = Object.fromEntries( + Object.entries(PILLAR_BASE).map(([k, v]) => [ + k, + Math.round(Math.min(100, Math.max(40, v + jitter(5)))), + ]), + ); + const at = daysAgoAt(n, 4, 50); + scoreRows.push([ + cuid(), + userId, + berlinDayKey(at), + "Europe/Berlin", + Math.round(composites[60 - n]), + "green", + 4, + Object.keys(PILLAR_BASE), + JSON.stringify(pillars), + createHash("sha256").update(`demo-health-score:${n}`).digest("hex"), + 0, + at, + at, + ]); + } + await bulkInsert( + client, + "health_score_records", + [ + "id", + "user_id", + "day_key", + "timezone", + "composite", + "band", + "score_version", + "composition", + "pillar_scores", + "input_fingerprint", + "config_version", + "computed_at", + "created_at", + ], + scoreRows, + ); + // ── Workouts ────────────────────────────── // ~3–4 sessions/week across the window: a mix of running, strength, and // cycling, with the fields the workout tiles render — duration, energy, @@ -1195,9 +1301,9 @@ async function seed() { // Medication 3: Magnesium (evening) const med3Id = cuid(); await client.query( - `INSERT INTO medications (id, user_id, name, dose, active, notifications_enabled, created_at, updated_at) - VALUES ($1, $2, 'Magnesium', '400mg', true, true, $3, $3)`, - [med3Id, userId, daysAgo(60)], + `INSERT INTO medications (id, user_id, name, dose, active, notifications_enabled, starts_on, created_at, updated_at) + VALUES ($1, $2, 'Magnesium', '400mg', true, true, $3, $4, $4)`, + [med3Id, userId, formatDate(daysAgo(60)), daysAgo(60)], ); const sched3Id = cuid(); await client.query(