Close Campaign interface audit gaps

This commit is contained in:
2026-08-04 01:04:39 +02:00
parent 3f3545f080
commit df5a93d6a3
10 changed files with 153 additions and 15 deletions
+2 -6
View File
@@ -527,7 +527,6 @@ manifest = ModuleManifest(
order=22,
surface_id=REPORTS_SURFACE_ID,
),
FrontendRoute(path="/templates", component="TemplatesPage", order=90),
),
nav_items=(
NavItem(
@@ -537,9 +536,6 @@ manifest = ModuleManifest(
required_any=CAMPAIGN_MODULE_REQUIRED_ANY,
order=20,
),
NavItem(
path="/templates", label="Templates", icon="layout-template", order=90
),
),
view_surfaces=(
ViewSurface(
@@ -808,7 +804,7 @@ manifest = ModuleManifest(
id="campaigns.workflow.prepare-validate-and-build",
title="Prepare, validate, and build a campaign",
summary="Turn governed recipient, template, attachment, and Mail-profile inputs into exact built messages for review.",
body="Prepare each input in its owning surface, resolve every blocking validation issue, and build exact recipient messages before review. Campaign freezes recipient and attachment evidence for the selected version; later source changes do not silently alter that build.",
body="Prepare each input in its owning surface, resolve every blocking validation issue, and build exact recipient messages before review. Campaign freezes recipient and attachment evidence for the selected version; later source changes do not silently alter that build. When the Templates module is installed, its single Templates navigation entry owns the reusable library while campaign-specific composition remains in the campaign workspace.",
layer="configured",
documentation_types=("user",),
audience=("campaign_manager", "campaign_author"),
@@ -836,7 +832,7 @@ manifest = ModuleManifest(
kind="repository",
),
),
related_modules=("addresses", "files", "mail"),
related_modules=("addresses", "files", "mail", "templates"),
unlocks=(
"A reviewable build whose exact recipient-specific effects can be inspected before delivery.",
),
@@ -23,6 +23,9 @@ from govoplan_campaign.backend.path_security import (
assert_server_safe_campaign_paths,
)
from govoplan_campaign.backend.campaign.loader import load_campaign_json
from govoplan_campaign.backend.campaign.mail_profile_boundary import (
CampaignMailProfileBoundaryError,
)
from govoplan_campaign.backend.attachments.resolver import resolve_campaign_attachments
from govoplan_campaign.backend.persistence.versions import (
is_version_final_locked,
@@ -324,7 +327,7 @@ def preview_campaign_attachments(
include_unmatched=payload.include_unmatched,
include_unlinked_candidates=payload.include_unlinked_candidates,
)
except CampaignPathSecurityError as exc:
except (CampaignPathSecurityError, CampaignMailProfileBoundaryError) as exc:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=str(exc)
) from exc