From 8e29c3ab54921039271fa9df29b6f9d6746f9626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Mon, 18 May 2026 12:30:49 +0200 Subject: [PATCH] feat(medication-compliance-rollups): boot-time backfill queue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Registers `medication-compliance-full-backfill` on pg-boss alongside the existing `rollup-full-backfill` and `mood-rollup-full-backfill` queues. The worker boot fires a discovery query that enqueues one full-fold per user with intake events but no rollup coverage — idempotent across reboots and singleton-keyed so a fast restart while a backfill is queued doesn't double up. The reminder worker's RED-phase mint path also wires the per-write rollup hook so freshly minted `takenAt:null` rows bump the per-day `scheduled` count before any read sees the user's compliance tile. Legacy accounts pre-dating the v1.4.39 deploy auto-converge on the persistent tier without operator action. --- src/lib/jobs/reminder-worker.ts | 80 +++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/lib/jobs/reminder-worker.ts b/src/lib/jobs/reminder-worker.ts index 7ab32511e..6c9b6540b 100644 --- a/src/lib/jobs/reminder-worker.ts +++ b/src/lib/jobs/reminder-worker.ts @@ -77,6 +77,14 @@ import { type MoodRollupFullBackfillPayload, type MoodRollupRecomputePayload, } from "@/lib/mood/rollups"; +import { + MEDICATION_COMPLIANCE_BACKFILL_QUEUE, + MEDICATION_COMPLIANCE_BACKFILL_CONCURRENCY, + recomputeMedicationComplianceForEvent, + recomputeUserMedicationCompliance, + enqueueBootTimeMedicationComplianceBackfill, + type MedicationComplianceBackfillPayload, +} from "@/lib/medications/compliance-rollups"; import { drainPerSampleCumulative, DRAIN_CUMULATIVE_CUTOFF_HOURS, @@ -577,6 +585,17 @@ async function handleReminderCheck(jobs: Job[]) { "missed_dose", `${med.name}:${schedule.windowStart}-${schedule.windowEnd}`, ); + + // v1.4.39 W-MED — the worker just minted a fresh + // `scheduledFor` row with `takenAt: null`; refresh the + // compliance rollup so the per-day `scheduled` count + // increments before any read sees the user's tile. + await recomputeMedicationComplianceForEvent({ + userId: med.user.id, + medicationId: med.id, + scheduledFor, + tz: med.user.timezone, + }); } } @@ -1676,6 +1695,10 @@ export async function startReminderWorker() { // entries but no rollup rows; the user drops off the list once // the fold completes. MOOD_ROLLUP_FULL_BACKFILL_QUEUE, + // v1.4.39 W-MED — boot-time fold for the medication-compliance + // rollup tier. Discovery enqueues one job per user with intake + // events but no rollup coverage; idempotent across reboots. + MEDICATION_COMPLIANCE_BACKFILL_QUEUE, // v1.4.37 W7c — explicit createQueue is required before the // nightly schedule below registers (pg-boss v12 contract). Without // this entry the drain schedule silently no-ops and the @@ -1989,6 +2012,37 @@ export async function startReminderWorker() { }, ); + // v1.4.39 W-MED — medication-compliance boot-backfill worker. The + // discovery helper below sends one job per user with intake events + // but zero rollup coverage; this handler folds the trailing 90-day + // window per account. Concurrency-1 so the populator never crowds + // the request pool. + await boss.work( + MEDICATION_COMPLIANCE_BACKFILL_QUEUE, + { localConcurrency: MEDICATION_COMPLIANCE_BACKFILL_CONCURRENCY }, + async (jobs) => { + for (const job of jobs) { + const { userId } = job.data; + try { + const { rowsUpserted, durationMs } = + await recomputeUserMedicationCompliance(userId); + workerLog( + "info", + `[medication-compliance-backfill] user=${userId} rows=${rowsUpserted} duration=${durationMs}ms`, + ); + } catch (err) { + recordError(); + workerLog( + "error", + `[medication-compliance-backfill] user=${userId} failed`, + err, + ); + throw err; + } + } + }, + ); + // v1.4.37 W7c — nightly drain worker. Walks every user × cumulative // type and folds per-sample APPLE_HEALTH rows older than the cutoff // into one `stats:…` row per calendar day. Idempotent — a second run @@ -2080,6 +2134,32 @@ export async function startReminderWorker() { ); } + // v1.4.39 W-MED — fire-and-forget boot discovery for the medication + // compliance rollup tier. Mirrors the v1.4.35.1 pattern: one job per + // user with intake events but no rollup coverage. Idempotent across + // reboots and singleton-keyed inside pg-boss. + try { + const { enqueued, skipped, error } = + await enqueueBootTimeMedicationComplianceBackfill(); + if (error) { + workerLog( + "error", + `[medication-compliance-backfill] boot discovery failed: ${error}`, + ); + } else { + workerLog( + "info", + `[medication-compliance-backfill] boot discovery: enqueued=${enqueued} skipped=${skipped}`, + ); + } + } catch (err) { + workerLog( + "error", + "[medication-compliance-backfill] boot discovery threw an unexpected error", + err, + ); + } + return boss; }