Files
HealthLog/src/lib/medications/dose-day-refresh.ts
T
Marc-André Bombeck 41de0ca126 refactor(medications): drop the compliance rollup table that nothing reads
medication_compliance_rollups lost its last reader when compliance moved
to the schedule-anchored computation, yet every dose write still upserted
it, a boot backfill refolded it, and the wipe and backup plans carried it.

The per-dose hook keeps the one derived row that still hangs off a dose
day, the supplement nutrients, under dose-day-refresh. The pending-row
mints (today projection, reminder) no longer call it, since an untaken
dose adds no nutrients. The import job finishes without its per-day
recompute phase; its progress keeps touchedDays and rollupProcessed on
the wire, inert and documented as deprecated. The backfill queue is
retired on boot and migration 0414 drops the table under a bounded lock
wait.
2026-10-20 13:01:45 +02:00

63 lines
2.1 KiB
TypeScript

/**
* The write-path hook every dose mutation funnels through: after a dose of a
* medication was taken, skipped, corrected, deleted, undone or recorded
* automatically, the rows derived from that dose's local day are recomputed.
*
* Today that is one derived row family, the micronutrients a taken
* supplement dose adds (`refreshSupplementNutrientsForDose`). The hook used to
* upsert a per-day compliance rollup as well; that table had no reader left
* and was dropped, so this is what remains of it, under a name that says what
* it does.
*
* Best-effort, like every derived row: a failure is reported by the refresh
* itself and never fails the dose write.
*/
import { refreshSupplementNutrientsForDose } from "@/lib/medications/ingredients/recompute";
import { DEFAULT_TIMEZONE, isValidTimezone, userDayKey } from "@/lib/tz/format";
function safeTimezone(tz: string | null | undefined): string {
return tz && isValidTimezone(tz) ? tz : DEFAULT_TIMEZONE;
}
/**
* The account-local day (`YYYY-MM-DD`) a dose slot belongs to: the local day
* of its `scheduledFor` in the account's timezone, falling back to the server
* default for a missing or unknown zone.
*/
export function dayKeyForScheduledFor(
scheduledFor: Date,
tz: string | null | undefined,
): string {
return userDayKey(scheduledFor, safeTimezone(tz));
}
/** Refresh the derived rows of one medication's local day. */
export async function refreshDoseDay(input: {
userId: string;
medicationId: string;
dayKey: string;
tz: string | null | undefined;
}): Promise<void> {
await refreshSupplementNutrientsForDose({
userId: input.userId,
medicationId: input.medicationId,
dayKey: input.dayKey,
timezone: safeTimezone(input.tz),
});
}
/** Refresh the derived rows of the local day a dose slot sits on. */
export async function refreshDoseSlot(input: {
userId: string;
medicationId: string;
scheduledFor: Date;
tz: string | null | undefined;
}): Promise<void> {
await refreshDoseDay({
userId: input.userId,
medicationId: input.medicationId,
dayKey: dayKeyForScheduledFor(input.scheduledFor, input.tz),
tz: input.tz,
});
}