Issue #3621119: Preserve event identity and make retries atomic (#3621120)

A delivery currently prevents a later complaint or another recipient event with the same MessageID from being recorded. This change uses a versioned event identity and a unique database constraint so distinct events survive and concurrent retries produce one row. It addresses #3621119 and #3621120.

Provider IDs are qualified by record type, normalized recipient, server and stream; the fallback includes message, bounce type and provider timestamp. The alpha upgrade preserves all legacy rows with NULL keys because missing provider identifiers cannot be reconstructed. The README documents legacy replay, missing-identifier and retention limits.

Validation: Drupal 10.3/PHP 8.3 and Drupal 11/PHP 8.4 on PostgreSQL: 26 tests, 77 assertions on each. Includes two independently bootstrapped concurrent receivers, unrelated constraint failures, distinct events/recipients, missing MessageID, and legacy duplicates. Drupal/DrupalPractice PHPCS and git diff --check pass.

Manual findings review checked duplicate conflict handling, PostgreSQL rollback, migration data preservation, raw-payload exclusion and documentation consistency. No remaining findings within this slice. Payload validation (#3621122), durable suppression (#3621121), and provider-time policy (#3621124) remain separate queue work. Automated review is not configured on this GitLab project.

Merge request reports

Loading