Lorixen.
EN

One Email, Five Events: A Ledger That Keeps Each Acknowledgement Separate

Digests reduce noise, but they can blur responsibility. If a digest is marked done, does that mean every event inside was handled? This article proposes a ledger that keeps the digest as a delivery container and each event as its own thing to acknowledge. It is a conditional design for your own system.

Primary artifact: the digest membership and acknowledgement ledger

Two tables, described in plain terms.

Digest records: digest id, recipient, composed_at, delivery state (composed, sent, send_unknown, failed), and the count of members fixed at composition.

Membership rows: digest id, event id, position in the digest, acknowledgement state (open, acknowledged), who acknowledged, and when.

Rules:

  1. Membership is frozen when the digest is composed. Events arriving later go to the next digest, never silently added to one already sent.
  2. An event belongs to at most one digest per recipient. A uniqueness constraint on recipient plus event is one proposed layer; it supports the rule but does not replace testing.
  3. Acknowledging happens per event. The digest has no acknowledged state of its own; display it as 'acknowledged 2 of 5' derived from membership rows.
  4. A digest counts as fully handled only when every member is acknowledged.

Decision branches: delivery

Branch A: the send call clearly succeeded. Mark the digest sent.

Branch B: the send clearly failed before leaving your system. Mark failed. A retry may be allowed, as nothing was sent.

Branch C: the outcome is unclear, such as a timeout after the request left. Mark send_unknown. Do not automatically resend, since a duplicate digest could carry events already acted on. A person checks, or the provider is asked for status if that is available to you, and then decides. A local claim that you tried to send cannot prove the message was delivered once, so the design makes no exactly-once promise. Duplicate delivery is possible and the per-event acknowledgement is what keeps duplicates harmless: acknowledging an already acknowledged event changes nothing.

Worked hypothetical

Digest D1 for one recipient is composed with events e1, e2, e3, e4, e5. Count fixed at 5. Delivery succeeds, so D1 is sent.

The recipient acknowledges e2 and e4 from the app. The ledger now shows 2 acknowledged, 3 open, displayed as 'acknowledged 2 of 5'. While this happens, event e6 arrives. D1 is frozen, so e6 waits for D2, which is composed later with e6 and e7. D2 has a count of 2.

Now suppose the D2 send times out. It becomes send_unknown, and nothing is retried automatically. A staff member confirms it was not received and records that decision; only then is a resend created, as a new delivery attempt for the same D2 membership, not a new digest. Totals across both digests: 7 events, 7 membership rows, 2 acknowledged, 5 open.

Stop conditions

  • Stop composing digests for a recipient if the previous one is send_unknown.
  • Stop if a membership row would put one event in two digests for the same recipient.
  • Never mark events acknowledged because the digest was opened or clicked.
  • Never delete membership rows after sending; they are the evidence.

Proposed acceptance tests (not yet performed)

  1. Compose D1 from five events and expect five membership rows and count 5.
  2. Acknowledge two events and expect 'acknowledged 2 of 5', with three still open.
  3. Add a sixth event after composition and expect it absent from D1.
  4. Simulate a timeout and expect send_unknown with no automatic resend.
  5. Acknowledge the same event twice and expect no change the second time.
  6. Attempt to place e1 in a second digest and expect refusal.
  7. Open the digest and expect no acknowledgement to be recorded.

These are checks to run later, and passing them would show the ledger rules hold for those cases only.

Sources

    WhatsAppLet’s talk