Planet4.Me docs
Open the app

#Auto-add and dormancy

A client-side sweep, because there is no server in this design. It runs on the first settled snapshot after the app opens and on every return to the foreground — never on a timer.

Idempotency is three stacked guards, because two phones opening the app at the same moment both decide to add the same milk:

  1. The item id is derived — auto_{stapleId}_{local day of the due date} — so two devices computing the same cadence write the same document, even if both were offline when they decided.
  2. computeAutoAdds skips any staple the household already has in hand: one with an unchecked item, and one this trip has checked off. The second half is the same tripChecked chain the list renders its "Checked off" section from, so the sweep and the screen agree on what is still being handled — see below.
  3. The same batch stamps lastAutoAddedForDueAt, and a candidate is only offered when it differs. That also gives deletion the right meaning: removing an auto-added item does not bring it back until a new purchase moves the due date.

Guard 2 covers the trip because guard 3 cannot. A check-off writes a purchase, the purchase moves nextDueAt to a new cycle, and a new cycle is exactly what releases guard 3 — by design, since that is what lets a staple be offered again next time round. So for any staple due again inside its own lead window — milk on a two-day rhythm against the two-day fallback lead, or anything whose store is visited about as often as the item runs out — nothing else stood between the check-off and a fresh offer for the cycle it had just started. The sweep runs on every return to the foreground, and the first check-off of a trip raises the location permission prompt, so the item reappeared before the undo bar had expired and could never be cleared. Widening guard 2 to the trip is the fix; the lead window itself is left alone, because a long lead is right when trips are rare and an item due in four days with the next trip in five belongs on the list now.

The sweep shares the cadence map with the screens rather than recomputing it, so what it decides and what the user is looking at cannot disagree about the time.

Dormancy is written by the same sweep and never deletes anything: the staple stays, with one quiet question attached. Low-confidence staples are never auto-added at all — they collect on a collapsed "might be running low" shelf, because a wrong guess on the list costs more trust than a missing one costs convenience.