[Feature] Detect duplicate campaign recipients and configure handling during build #106

Open
opened 2026-10-13 13:15:39 +02:00 by zemion · 0 comments
Owner

Problem

When building a campaign, multiple entries or generated messages can target the same recipient or the same recipient group. Campaign authors need a scan that exposes this before sending and prevents unintended repeated mail according to a configurable policy.

An address appearing in several messages is not sufficient to declare those messages duplicates. For example, messages to A+B+C and A+D may deliberately have different content; A's overlap must not silently cause either message to be dropped or the groups to be merged.

Proposed Capability

Add a duplicate-recipient scan to campaign validation/build, after resolving the actual delivery addresses and message inputs. Show findings in build/review and apply a configurable duplicate-handling policy before jobs become sendable.

Matching and review

  • Detect repeated normalized mailbox addresses across campaign entries/messages and repeated recipient groups. Compare resolved delivery recipients rather than display names, import row IDs, or a recipient's position in a list.
  • Make the matching scope explicit: same recipient versus same complete recipient group. Identify partial group overlaps separately.
  • Group comparison should account for To/Cc/Bcc roles, including Bcc delivery recipients without exposing them in visible headers. Ignore address order for matching while preserving the saved order in retained messages.
  • Show the affected source entries/jobs, matching addresses/groups, and differences in subject, rendered content, personalization, and attachments so an author can distinguish accidental repeats from intentional messages.
  • Do not assume provider-specific aliases are the same mailbox. Document normalization and grouping rules.

Configurable policy

Policy Required behavior
Ask Require an explicit review decision for each duplicate group; prevent queueing/sending unresolved groups. Ask in the authoring/review UI rather than an unattended delivery worker.
Stop Block the build from becoming sendable when duplicate candidates within the configured scope remain. Explain which entries must be corrected.
Consolidate Create one reviewed message for a duplicate group using defined content/data/attachment merge rules. If conflicting personalization, attachments, addressing roles, or group membership cannot be merged safely, require a decision instead of silently discarding information.
First only Keep the first matching message according to a documented, stable campaign/source order and mark later matches as excluded with a reason. Rebuilding the same inputs must retain the same message.

Allow authors to explicitly preserve intentional separate messages where policy permits it. Make the effective policy and matching scope visible; define defaults and any campaign override within existing policy constraints. Selecting consolidation must not silently expand a recipient group or disclose content/attachments to additional recipients.

Ownership

  • Owning repository: govoplan-campaign.
  • Own the scan, configuration, build/review decisions, job eligibility, and evidence in Campaign.
  • Addresses/Dist-lists remain responsible for reusable source data; consume their resolved snapshots without modifying their master records.
  • Preserve Mail delivery idempotency and existing review/approval gates. This scan addresses separate generated messages, in addition to existing retry protection.
  • Related context: Campaign #96 preserves address order within a message; Campaign #47 defines the Addresses boundary.

Acceptance Criteria

  • A scan during build identifies duplicate recipients and exact recipient groups across active generated mail jobs, and clearly distinguishes partial overlaps.
  • Ask, stop, consolidate, and first-only policies are configurable, persisted, and explained in the UI.
  • Two entries targeting A alone, and two messages targeting the same complete A+B+C group, follow the chosen matching scope and handling policy.
  • A+B+C and A+D can remain separate messages with different content; overlap at A never silently suppresses or merges either message.
  • Consolidation preserves intended content and attachment provenance, or blocks for explicit review when conflicts cannot be resolved safely.
  • First-only is deterministic and excluded jobs cannot be sent through bulk, individual, API, or worker paths.
  • Unresolved ask/stop findings block sending on the backend, not only in the UI.
  • Findings, effective policy, explicit decisions, retained/consolidated/excluded job relationships, and resulting counts are recorded in the frozen build and report/audit evidence.
  • Changing recipients, message inputs, matching scope, or policy invalidates affected decisions and requires a fresh scan/build.
  • User and administrator documentation describe matching, overlapping groups, all policy modes, and exclusions.

Verification Target

Backend and WebUI tests with repeated imports/entries, normalized address variants, address-order permutations, To/Cc/Bcc role differences, excluded entries, conflicting personalized content/attachments, and unchanged rebuilds.

Exercise each policy with repeated A recipients, repeated A+B+C groups, and overlapping A+B+C / A+D groups. Verify effective delivery-job counts and that suppressed or unresolved jobs cannot reach Mail. Verify review, reports, and policy changes against the exact frozen build.

## Problem When building a campaign, multiple entries or generated messages can target the same recipient or the same recipient group. Campaign authors need a scan that exposes this before sending and prevents unintended repeated mail according to a configurable policy. An address appearing in several messages is not sufficient to declare those messages duplicates. For example, messages to **A+B+C** and **A+D** may deliberately have different content; A's overlap must not silently cause either message to be dropped or the groups to be merged. ## Proposed Capability Add a duplicate-recipient scan to campaign validation/build, after resolving the actual delivery addresses and message inputs. Show findings in build/review and apply a configurable duplicate-handling policy before jobs become sendable. ### Matching and review - Detect repeated normalized mailbox addresses across campaign entries/messages and repeated recipient groups. Compare resolved delivery recipients rather than display names, import row IDs, or a recipient's position in a list. - Make the matching scope explicit: **same recipient** versus **same complete recipient group**. Identify partial group overlaps separately. - Group comparison should account for To/Cc/Bcc roles, including Bcc delivery recipients without exposing them in visible headers. Ignore address order for matching while preserving the saved order in retained messages. - Show the affected source entries/jobs, matching addresses/groups, and differences in subject, rendered content, personalization, and attachments so an author can distinguish accidental repeats from intentional messages. - Do not assume provider-specific aliases are the same mailbox. Document normalization and grouping rules. ### Configurable policy | Policy | Required behavior | | --- | --- | | **Ask** | Require an explicit review decision for each duplicate group; prevent queueing/sending unresolved groups. Ask in the authoring/review UI rather than an unattended delivery worker. | | **Stop** | Block the build from becoming sendable when duplicate candidates within the configured scope remain. Explain which entries must be corrected. | | **Consolidate** | Create one reviewed message for a duplicate group using defined content/data/attachment merge rules. If conflicting personalization, attachments, addressing roles, or group membership cannot be merged safely, require a decision instead of silently discarding information. | | **First only** | Keep the first matching message according to a documented, stable campaign/source order and mark later matches as excluded with a reason. Rebuilding the same inputs must retain the same message. | Allow authors to explicitly preserve intentional separate messages where policy permits it. Make the effective policy and matching scope visible; define defaults and any campaign override within existing policy constraints. Selecting consolidation must not silently expand a recipient group or disclose content/attachments to additional recipients. ## Ownership - Owning repository: **govoplan-campaign**. - Own the scan, configuration, build/review decisions, job eligibility, and evidence in Campaign. - Addresses/Dist-lists remain responsible for reusable source data; consume their resolved snapshots without modifying their master records. - Preserve Mail delivery idempotency and existing review/approval gates. This scan addresses separate generated messages, in addition to existing retry protection. - Related context: [Campaign #96](https://git.add-ideas.de/GovOPlaN/govoplan-campaign/issues/96) preserves address order within a message; [Campaign #47](https://git.add-ideas.de/GovOPlaN/govoplan-campaign/issues/47) defines the Addresses boundary. ## Acceptance Criteria - [ ] A scan during build identifies duplicate recipients and exact recipient groups across active generated mail jobs, and clearly distinguishes partial overlaps. - [ ] Ask, stop, consolidate, and first-only policies are configurable, persisted, and explained in the UI. - [ ] Two entries targeting A alone, and two messages targeting the same complete A+B+C group, follow the chosen matching scope and handling policy. - [ ] A+B+C and A+D can remain separate messages with different content; overlap at A never silently suppresses or merges either message. - [ ] Consolidation preserves intended content and attachment provenance, or blocks for explicit review when conflicts cannot be resolved safely. - [ ] First-only is deterministic and excluded jobs cannot be sent through bulk, individual, API, or worker paths. - [ ] Unresolved ask/stop findings block sending on the backend, not only in the UI. - [ ] Findings, effective policy, explicit decisions, retained/consolidated/excluded job relationships, and resulting counts are recorded in the frozen build and report/audit evidence. - [ ] Changing recipients, message inputs, matching scope, or policy invalidates affected decisions and requires a fresh scan/build. - [ ] User and administrator documentation describe matching, overlapping groups, all policy modes, and exclusions. ## Verification Target Backend and WebUI tests with repeated imports/entries, normalized address variants, address-order permutations, To/Cc/Bcc role differences, excluded entries, conflicting personalized content/attachments, and unchanged rebuilds. Exercise each policy with repeated A recipients, repeated A+B+C groups, and overlapping A+B+C / A+D groups. Verify effective delivery-job counts and that suppressed or unresolved jobs cannot reach Mail. Verify review, reports, and policy changes against the exact frozen build.
zemion added the
status
triage
module/campaign
type
feature
labels 2026-10-13 13:15:39 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: GovOPlaN/govoplan-campaign#106