mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 13:22:14 +00:00
The MEDICATION_INTAKE_SYNC fan-out used to fire one silent APNs per distinct dose slot, so a bulk intake marking five doses woke every other device five times. Replace the per-slot dispatch with a per-user coalescer: the first mutation in a burst dispatches immediately, every further mutation inside the 2 s window folds into one trailing fan-out. A bulk request now costs exactly one queue call, and a rapid burst of N single-dose mutations costs at most two fan-outs. The window state is in-process; multiple app instances throttle independently, which is accepted because the iOS reconcile is idempotent and the deployment model is a single container. The silent payload shrinks to a pure sync trigger — eventType + syncedAt. The per-slot medicationId / scheduledFor fields are gone: the iOS handler runs a full reconcile regardless, a coalesced burst has no single slot to name, and a push payload travels through Apple's infrastructure, so it now carries no health data by construction. The Live Activity end push likewise sends only the ActivityKit envelope. The trailing flush keeps the origin skip only when every coalesced mutation came from the same device; a mixed-origin burst wakes everyone. Each flush still records one push_attempts ledger row, reaps hard-rejected device tokens, and annotates the wide event with the recipient count and coalesced-mutation count.