From 9bb68ade8a452c77bf44b7952b0e8192a29090da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Mon, 8 Jun 2026 18:29:05 +0200 Subject: [PATCH] feat(medications): persist a per-dose configurable intake window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add `doseWindows` (Json?) to MedicationSchedule: a nullable array of `{ timeOfDay, start, end }` HH:mm triples naming an explicit on-time range for a dose time (e.g. 07:00–09:00). A time with no entry keeps the symmetric ±1h default; a NULL column leaves every slot on the default derivation, so the migration is additive and changes no existing behaviour. Migration 0137 adds the column with no backfill. --- .../0137_v11518_dose_windows/migration.sql | 18 ++++++++++++++++++ prisma/schema.prisma | 10 ++++++++++ 2 files changed, 28 insertions(+) create mode 100644 prisma/migrations/0137_v11518_dose_windows/migration.sql diff --git a/prisma/migrations/0137_v11518_dose_windows/migration.sql b/prisma/migrations/0137_v11518_dose_windows/migration.sql new file mode 100644 index 000000000..17c551b20 --- /dev/null +++ b/prisma/migrations/0137_v11518_dose_windows/migration.sql @@ -0,0 +1,18 @@ +-- v1.15.18 — per-dose configurable intake WINDOW. +-- +-- Marc's "07:00–09:00" lever: a dose time can carry an explicit on-time RANGE +-- instead of the symmetric ±1h default the band minter derives. The column is +-- a nullable JSON array of `{ timeOfDay, start, end }` HH:mm triples, one per +-- dose time the user gave an explicit window for, e.g. +-- [{ "timeOfDay": "07:00", "start": "07:00", "end": "09:00" }] +-- +-- The band minter reads it to build the on-time band from `[start, end]` for +-- the matching `timeOfDay`; a time with no entry keeps the default ±1h +-- derivation, and a NULL column leaves every slot on the default (unchanged +-- behaviour). The late tail stays cadence-derived. +-- +-- Additive + non-destructive: a new nullable column with no backfill. Existing +-- rows read NULL and behave exactly as before; the iOS contract gains an +-- optional field. +ALTER TABLE "medication_schedules" + ADD COLUMN "dose_windows" JSONB; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 5c97ed5da..4ced5f92e 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1388,6 +1388,16 @@ model MedicationSchedule { /// v1.7.0 — cyclic "off" weeks. Only meaningful when /// `scheduleType = CYCLIC`. cyclicOffWeeks Int? @map("cyclic_off_weeks") + /// v1.15.18 — per-dose on-time intake WINDOW (the configurable lever). + /// A JSON array of `{ timeOfDay, start, end }` HH:mm triples, one per + /// dose time the user wants an explicit range for (e.g. + /// `[{ "timeOfDay": "07:00", "start": "07:00", "end": "09:00" }]`). + /// The band minter reads this to build the on-time band from the + /// explicit `[start, end]` range for the matching `timeOfDay`; a + /// `timeOfDay` with no entry falls back to the symmetric ±1h default. + /// The late tail stays cadence-derived. NULL = every slot uses the + /// default derivation (unchanged behaviour). Additive + iOS-safe. + doseWindows Json? @map("dose_windows") medication Medication @relation(fields: [medicationId], references: [id], onDelete: Cascade) telegramMessages TelegramReminderMessage[]