mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 20:42:43 +00:00
The per-phase "already sent today" guard read the Telegram message ledger, and that table is written only when a Telegram send succeeds. A user on email, APNs or ntfy never had a row, so the 15-minute tick re-derived the same overdue slot and sent it again on every pass — around fifty mails for a single missed dose. Anchor the guard in `push_attempts` instead, the ledger the daily briefing and the illness escalation already use. Two properties are deliberate: the anchor is stamped for every dispatched slot regardless of what any channel returned, because keying it on a delivered push would re-open the flood the moment a channel starts failing; and it is stamped before the dispatch, so a crash costs one phase's notice rather than a repeat every quarter hour. The key carries the schedule id and the slot's real HH:mm alongside the phase and the local date. Both are load-bearing: two legacy single-window schedules on one medication share the empty first-class time-of-day, so a coarser key would collapse the evening dose into the morning one. The tests assert the other direction too — the next phase still escalates, and the next local day starts clean. The Telegram ledger keeps its message-tracking duties; it is no longer the dedup key. Anchor rows carry a sentinel channel and stay out of the operator's notification health and diagnostic reads, which count deliveries, not decisions.