Commit Graph
7 Commits
Author SHA1 Message Date
Marc-André Bombeck 23a67f61e6 feat(medications): let a course end at an instant
A course's end date is a calendar day and counts in full: the doses of that
day stay due, reminded and expected until local midnight. That is right for
an end date set in the editor and wrong for "End course", whose dialog
promises that nothing more is due.

A course now carries `endedAt` (migration 0482, additive, nullable), the
instant it was ended on its `endsOn` day, projected onto the medication next
to `startsOn` / `endsOn` by the one course writer. From that instant:

- the schedule engine emits no slot, so a dose later that day is not due,
  not reminded, not projected onto the today list and never expected by
  compliance, while a dose earlier that day stays inside the course;
- the course reads ENDED (`courseStatusAt` / `courseStatusOn`), so the dose
  actions, `remindersActive` and the reminder gate stop at once, follow-ups
  of an earlier dose included;
- every engine context builder, compliance context, dose history, Coach
  snapshot, doctor report and the adherence storyline read it, through one
  select and one picker for the medication window.

Any write that moves a course's `endsOn` clears the instant, so an end date
chosen in the editor keeps meaning the whole day. Backups carry it in both
purposes and a restore projects it again. `courseStatusAt` moves next to the
other course rules.

Refs #1280
2026-10-24 22:20:06 +02:00
Marc-André Bombeck 24f06884b3 fix(reminders): an ended course reads as not reminding
The worker expands no slot past endsOn, so it never reminds for a
course that has ended, but remindersActive still read true for it. The
reminder gate now includes the course end on the person's clock, so the
published value, the worker and the admin check make the same decision.
2026-10-11 15:16:54 +02:00
Marc-André Bombeck 38900656a3 fix(audit): name automatic dose recording in medication audit rows
Switching autoMarkTaken on or off now appears in the medication.update
row with its previous value, and medication.create records whether the
medication starts with doses recorded automatically.
2026-10-11 15:11:27 +02:00
Marc-André Bombeck 0ff1340ff4 fix(medications): never backfill days an edit reopens under auto-take
A start moved earlier, an end moved later or removed, or a medication
made active again reopened past slots, and the auto-take pass filled up
to a week of them as taken. The course window writer and the
re-activation paths now move the auto-take floor to the moment of the
edit.
2026-10-11 15:07:06 +02:00
Marc-André Bombeck a4cccc11ba fix(medications): keep an auto-taken rolling cadence moving
A rolling cadence yields only lastIntakeAt + N, so a slot the auto-take
pass never records (before the switch-on floor, past the catch-up
window, inside a pause, skipped or removed by the person) held it still
for good. Step the cadence forward by N past every such slot, keeping
its rhythm, and feed the stepped anchor to the card, dashboard and
schedule-tool next due so they show the slot the pass will record.
2026-10-11 15:00:37 +02:00
Marc-André Bombeck 195fa28cc5 feat(medications): publish the resolved reminder decision as remindersActive 2026-10-11 14:09:22 +02:00
Marc-André Bombeck 7417d8f423 test(medications): prove the auto-take pass against Postgres 2026-10-11 13:53:35 +02:00