feat(templates): persist reusable content requirements

This commit is contained in:
2026-08-19 21:54:54 +02:00
parent 1c12359750
commit 5de54ccd2e
3 changed files with 30 additions and 3 deletions
+15 -1
View File
@@ -146,7 +146,16 @@ class SqlTemplateContentLibrary(TemplateContentLibraryProvider):
template_type=request.template_type,
usages=list(request.usages),
locale=request.locale,
required_fields=[],
required_fields=[
{
"path": field.path,
"value_type": field.value_type,
"label": field.label,
"required": field.required,
"description": field.description,
}
for field in request.required_fields
],
output_profiles=[],
content_text=request.content_text,
content_html=request.content_html,
@@ -168,6 +177,11 @@ class SqlTemplateContentLibrary(TemplateContentLibraryProvider):
"definition_hash": revision.definition_hash,
"template_type": revision.template_type,
"usages": list(revision.usages or []),
"required_fields": [
str(field.get("path") or "")
for field in revision.required_fields or []
if field.get("path")
],
"source": "content_library_capability",
},
commit=False,
+4 -2
View File
@@ -104,7 +104,8 @@ DOCUMENTATION = (
body=(
"Content fragments retain text and HTML variants, usage constraints, locale, scope, revision, and publication state in Templates. "
"Campaign can load a fragment or complete email part through the optional content-library capability. Saving from Campaign creates "
"a draft and never publishes it automatically. Inserting content changes only the current Campaign draft; existing Campaign versions "
"a draft with its declared required-field contract and never publishes it automatically. Consumers show missing required fields before "
"applying content. Inserting content changes only the current Campaign draft; existing Campaign versions "
"and Template revisions remain unchanged."
),
layer="available",
@@ -118,7 +119,8 @@ DOCUMENTATION = (
"body": (
"Inhaltsbausteine speichern Text- und HTML-Fassungen, Verwendungszwecke, Sprache, Geltungsbereich, Revision und "
"Veröffentlichungsstatus in Templates. Campaign kann Bausteine oder vollständige E-Mail-Teile über die optionale "
"Inhaltsbibliothek laden. Das Speichern aus Campaign legt einen Entwurf an und veröffentlicht ihn niemals automatisch. "
"Inhaltsbibliothek laden. Das Speichern aus Campaign legt einen Entwurf mit dem deklarierten Pflichtfeldvertrag an und "
"veröffentlicht ihn niemals automatisch. Fehlende Pflichtfelder werden vor dem Anwenden angezeigt. "
"Das Einfügen ändert nur den aktuellen Kampagnenentwurf; bestehende Kampagnenversionen und Template-Revisionen bleiben unverändert."
),
}
+11
View File
@@ -13,6 +13,7 @@ from govoplan_core.core.templates import (
CAPABILITY_TEMPLATE_RENDERER,
TemplateCompatibilityError,
TemplateContentDraftRequest,
TemplateFieldRequirement,
TemplateRenderError,
TemplateRenderRequest,
)
@@ -182,6 +183,12 @@ class TemplateServiceTests(unittest.TestCase):
usages=("campaign.content",),
locale="de",
content_text="Mit freundlichen Grüßen",
required_fields=(
TemplateFieldRequirement(
path="local.display_name",
label="Display name",
),
),
metadata={"campaign_targets": ["text"]},
),
)
@@ -190,6 +197,10 @@ class TemplateServiceTests(unittest.TestCase):
self.assertEqual("draft", result.status)
self.assertEqual("content_fragment", result.template_type)
self.assertEqual("Mit freundlichen Grüßen", result.revision.content_text)
self.assertEqual(
"local.display_name",
result.revision.required_fields[0].path,
)
self.assertEqual(["text"], result.revision.metadata["campaign_targets"])
self.assertEqual(
"templates.content_library",