feat(campaign): govern attachment reuse

This commit is contained in:
2026-08-20 05:20:07 +02:00
parent f4fe534ee1
commit 112ef9dc31
16 changed files with 705 additions and 2 deletions
@@ -19,6 +19,7 @@ from govoplan_campaign.backend.attachments.resolver import (
effective_send_without_attachments_behavior,
resolve_entry_attachments,
)
from govoplan_campaign.backend.attachments.reuse import evaluate_attachment_reuse
from govoplan_campaign.backend.campaign.addressing import effective_address_lists, formatted_recipient
from govoplan_campaign.backend.campaign.entries import load_campaign_entries
from govoplan_campaign.backend.campaign.field_values import ignored_entry_field_overrides
@@ -1149,6 +1150,28 @@ def _apply_campaign_level_issues(built_messages: list[BuiltMessage], issues: lis
status = _apply_behavior(status, issue.behavior)
built.draft.validation_status = status
def _apply_attachment_reuse_policy(
config: CampaignConfig,
built_messages: list[BuiltMessage],
) -> dict[str, object]:
evaluation = evaluate_attachment_reuse(
[built.draft for built in built_messages],
policy=config.attachments.reuse_policy,
)
for built in built_messages:
issues = evaluation.issues_by_entry_index.get(built.draft.entry_index, [])
if not issues:
continue
built.draft.issues.extend(issues)
for issue in issues:
if issue.behavior:
built.draft.validation_status = _apply_behavior(
built.draft.validation_status,
issue.behavior,
)
return evaluation.report
def build_campaign_messages(
config: CampaignConfig,
*,
@@ -1203,6 +1226,10 @@ def build_campaign_messages(
)
if residual_message is not None:
built_messages.append(residual_message)
attachment_reuse = _apply_attachment_reuse_policy(
config,
built_messages,
)
rules_resolved = sum(len(built.draft.attachments) for built in built_messages)
report = CampaignBuildReport(
@@ -1216,6 +1243,7 @@ def build_campaign_messages(
duration_ms=(time.perf_counter() - started) * 1000,
rules_resolved=rules_resolved,
),
attachment_reuse=attachment_reuse,
residual_file_disposition=_residual_file_disposition_evidence(
config=config,
residual_groups=residual_groups,