mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 22:32:04 +00:00
fix(medications): restore the containers the in-use clock wrongly wrote off
Migration 0276 reverses the rows that reached EXPIRED only through the post-opening clock on a container that never had one. It moves a row back to IN_USE when an opening date is recorded and ACTIVE when none is, and sets `expires_at` from the printed expiry — which for these rows is usually nothing at all, because they recorded none. The predicate is exact rather than approximate: nothing but the printed expiry and the in-use clock can write EXPIRED, so a clock-less container whose printed expiry is absent or still ahead can only have got there through the clock. Pens and ampoules keep their EXPIRED, so does anything whose printed date genuinely lapsed, and so does a drained container. No date is invented and no printed expiry is fabricated. The integration test seeds the before-state, applies the migration SQL from disk, and asserts both what moves and what stays — the testcontainer starts empty, so the migration running at boot proves nothing on its own.
This commit is contained in:
1 parent
a1dbd9c831
commit
bb1e01e456
2 files changed
+305
No files matched your search
@@ -0,0 +1,44 @@
|
||||
-- Restore supply containers that the in-use clock wrote off although they
|
||||
-- never carried one.
|
||||
--
|
||||
-- Until this release the state machine started a 30-day post-opening clock
|
||||
-- for every container as soon as `first_use_at` was set, including the
|
||||
-- containers whose units stay individually sealed. Pressing the first tablet
|
||||
-- out of a blister therefore condemned the rest of the pack a month later:
|
||||
-- the row went EXPIRED, its units dropped out of the available pool, and the
|
||||
-- supply card read "0 of 0 doses" beside a count of expired units.
|
||||
--
|
||||
-- The rows to restore are the ones that can ONLY have reached EXPIRED through
|
||||
-- that clock:
|
||||
-- * `container_type` is one of the kinds that has no post-opening clock
|
||||
-- (everything except PEN and AMPOULE — see IN_USE_CLOCK_CONTAINER_TYPES
|
||||
-- in src/lib/medications/inventory/state-machine.ts),
|
||||
-- * the printed expiry is absent or still ahead of now, so the printed
|
||||
-- label cannot be what expired the row,
|
||||
-- * units are left, so USED_UP is not the answer either.
|
||||
--
|
||||
-- Nothing else can have set EXPIRED: the API cannot write that state
|
||||
-- directly, the daily cron only flips rows whose `expires_at` has lapsed,
|
||||
-- and the consumption hook derives the state from the same two clocks.
|
||||
--
|
||||
-- Deliberately untouched:
|
||||
-- * PEN and AMPOULE rows — their clock is real and their EXPIRED is earned;
|
||||
-- * any row whose printed expiry has genuinely lapsed, whatever its kind;
|
||||
-- * rows with no units left (their state is a USED_UP question, not this
|
||||
-- one);
|
||||
-- * every other column. No date is invented and no printed expiry is
|
||||
-- fabricated: a row that recorded no expiry keeps recording none, which
|
||||
-- is why `expires_at` is set from `printed_expiry` rather than computed.
|
||||
UPDATE "medication_inventory_items"
|
||||
SET
|
||||
"state" = CASE
|
||||
WHEN "first_use_at" IS NOT NULL THEN 'IN_USE'::"medication_inventory_state"
|
||||
ELSE 'ACTIVE'::"medication_inventory_state"
|
||||
END,
|
||||
-- The only deadline a clock-less container can carry is its printed one.
|
||||
"expires_at" = "printed_expiry",
|
||||
"updated_at" = NOW()
|
||||
WHERE "state" = 'EXPIRED'
|
||||
AND "container_type" NOT IN ('PEN', 'AMPOULE')
|
||||
AND ("printed_expiry" IS NULL OR "printed_expiry" > NOW())
|
||||
AND "doses_remaining" > 0;
|
||||
Reference in new issue
Block a user