You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## Summary
- re-dispatch stored `queued` and `scheduled` emails when an identical
idempotent request is replayed
- preserve the original email ID and stored schedule during recovery
- rely on the existing atomic send lease and final-state checks to
collapse duplicate SQS deliveries
- document the ambiguous-acceptance recovery procedure and at-least-once
boundary
## Root cause
Email persistence and SQS/EventBridge dispatch are separate operations.
If persistence succeeded and dispatch then failed, the API returned an
error but retained the email and idempotency claim. An identical retry
returned that stored record without restoring an immediate or
short-delay job, so the email could remain queued forever.
## Impact
Clients can safely retry the identical payload with the same idempotency
key after an ambiguous API failure. HayaSend returns the same ID and
restores dispatch for eligible non-final records. Replays never
re-dispatch `sending`, canceled, suppressed, or terminal records.
This remains an immediate risk-reduction bridge. The accepted #81/#84
direction replaces client-triggered repair with durable outbox
reconciliation in the provider-neutral semantics series.
## Validation
- `npm ci`
- `npm run check`
- `npm test` — 22 files, 170 tests
- `npm run build`
- `npm run lint:openapi`
- `npm audit --omit=dev --audit-level=high` — 0 vulnerabilities
- `npm outdated --json` — no direct dependency updates available
- `git diff --check`
Closes#50
Signed-off-by: Yusuke Hayashi <yusuke8h@gmail.com>
0 commit comments