feat(backup): carry per-schedule units-per-dose through backup and restore

The schedule exporter enumerates columns, so the new per-schedule
units-per-dose needs adding by hand: export it as a Decimal string in
the disaster-recovery payload, accept it in the wire schema, and write
it back on restore (NULL stays NULL to inherit). Extend the round-trip
test to prove a half-tablet slot survives export and re-import.
This commit is contained in:
Marc-André Bombeck committed 2026-08-10 07:58:48 +02:00
1 parent 80958ab307
commit 08a1dbccac
4 files changed
+14

No files matched your search

@@ -581,6 +581,9 @@ const handler = apiHandler(
windowEnd: s.windowEnd,
label: s.label ?? null,
dose: s.dose ?? null,
// #219 — per-schedule units per dose. Prisma coerces the
// Decimal string; NULL / absent stays NULL (inherit).
unitsPerDose: s.unitsPerDose ?? null,
daysOfWeek: s.daysOfWeek ?? null,
timesOfDay: s.timesOfDay ?? [],
reminderGraceMinutes: s.reminderGraceMinutes ?? null,
@@ -131,6 +131,8 @@ function makePrisma() {
scheduleType: "CYCLIC",
cyclicOnWeeks: 3,
cyclicOffWeeks: 1,
// #219 — per-schedule units per dose (a half tablet at this slot).
unitsPerDose: { toString: () => "0.5000" },
doseWindows: [
{ timeOfDay: "08:00", start: "07:30", end: "09:00" },
],
@@ -502,6 +504,8 @@ describe("buildFullBackupPayload disaster-recovery mode", () => {
scheduleType: "CYCLIC",
cyclicOnWeeks: 3,
cyclicOffWeeks: 1,
// #219 — Decimal → string, round-tripped through the DR payload.
unitsPerDose: "0.5000",
}),
],
}),
+4
View File
@@ -507,6 +507,10 @@ export async function buildFullBackupPayload(
cyclicOnWeeks: s.cyclicOnWeeks,
cyclicOffWeeks: s.cyclicOffWeeks,
doseWindows: s.doseWindows,
// #219 — per-schedule units per dose. Decimal → string like the
// medication-level column; NULL (inherit) stays NULL.
unitsPerDose:
s.unitsPerDose == null ? null : s.unitsPerDose.toString(),
}
: {}),
windowStart: s.windowStart,
+3
View File
@@ -127,6 +127,9 @@ const medicationScheduleSchema = z
windowEnd: z.string().min(1),
label: z.string().nullable().optional(),
dose: z.string().nullable().optional(),
// #219 — per-schedule units per dose. Serialised as a Decimal string in a
// DR file (or a number in a hand-authored one); NULL means inherit.
unitsPerDose: z.union([z.string(), z.number()]).nullable().optional(),
daysOfWeek: z.string().nullable().optional(),
timesOfDay: z.array(z.string()).optional(),
reminderGraceMinutes: z.number().int().nullable().optional(),