Problem/Motivation

Deduplication uses MessageID alone. An authenticated Delivery followed by SpamComplaint for the same MessageID returns 200 twice, stores only Delivery, and leaves the address unsuppressed. The same problem affects different recipients of one message.

Evidence and scope

Reviewed 1.0.0-alpha1, source commit 02fd9d36af5237e712cecb7155d79725f7824880. Location: src/Controller/PostmarkWebhookController.php:77.

Kernel reproduction passed: two events acknowledged, one row stored, suppression reason NULL. Sequential loss is confirmed; this is separate from the concurrent insertion race.

Proposed resolution

Define event identity using provider event identifiers where available and a documented fallback including event kind, recipient and source scope. Preserve distinct events of the same message; retain retry idempotency. Do not simply add RecordType if multiple same-kind events can legitimately exist.

Acceptance criteria

Test delivery then complaint, separate recipients, repeated identical events and missing provider IDs. Document migration limitations: discarded history cannot be reconstructed locally.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jmcerda created an issue. See original summary.

jmcerda’s picture

Assigned: Unassigned » jmcerda

Working on event identity together with atomic retry handling in #3621120. The implementation uses a database-enforced event key and preserves legacy rows whose provider identity was not retained. Verification covers distinct events and recipients, repeated events with and without MessageID, independent concurrent receiver processes, upgrade preservation, and unrelated database failures.

jmcerda’s picture

Status: Active » Needs review

Ready for review in https://git.drupalcode.org/project/postmark_webhooks/-/merge_requests/1 . Drupal 10.3/PHP 8.3 and Drupal 11/PHP 8.4 each pass 26 kernel tests and 77 assertions on PostgreSQL, including simultaneous independent receiver processes and legacy upgrade preservation. Drupal/DrupalPractice coding standards pass. Manual findings review is recorded in the merge request; no automated review or GitLab pipeline is configured yet.

  • jmcerda committed 67b13526 on 1.x
    Issue #3621119: Freeze upgrade schema and support resumed updates
    

  • jmcerda committed 0f576611 on 1.x
    Issue #3621119: Preserve event identity and make retries atomic (#...
jmcerda’s picture

Status: Needs review » Fixed

The event-identity fix was integrated into the 1.x development branch in commit 69e045b and is included in the current d3c5d94 head. The development branch has been mirrored to Drupalcode; both repositories were verified at the same commit. Marking Fixed to record integration. This is unreleased development code: no release tag or deployment is recorded by this update.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.