From d338403dbdfa917bcff16603cbde023dcae60a9e Mon Sep 17 00:00:00 2001 From: Albrecht Degering Date: Sun, 23 Aug 2026 20:27:27 +0200 Subject: [PATCH] docs(workflow-engine): complete German reference coverage --- pyproject.toml | 2 +- src/govoplan_workflow_engine/__init__.py | 2 +- .../backend/manifest.py | 123 +++++++++++++++++- tests/test_manifest.py | 17 +++ 4 files changed, 140 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8a04d27..476041e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "govoplan-workflow-engine" -version = "0.1.19" +version = "0.1.20" description = "Headless, versioned workflow definition and execution engine for GovOPlaN." readme = "README.md" requires-python = ">=3.12" diff --git a/src/govoplan_workflow_engine/__init__.py b/src/govoplan_workflow_engine/__init__.py index 3448139..821aa50 100644 --- a/src/govoplan_workflow_engine/__init__.py +++ b/src/govoplan_workflow_engine/__init__.py @@ -1,3 +1,3 @@ """Headless GovOPlaN Workflow Engine module.""" -__version__ = "0.1.18" +__version__ = "0.1.20" diff --git a/src/govoplan_workflow_engine/backend/manifest.py b/src/govoplan_workflow_engine/backend/manifest.py index 95216bf..c28c222 100644 --- a/src/govoplan_workflow_engine/backend/manifest.py +++ b/src/govoplan_workflow_engine/backend/manifest.py @@ -60,7 +60,7 @@ from govoplan_workflow_engine.backend.service_launcher import ( MODULE_ID = "workflow_engine" MODULE_NAME = "Workflow Engine" -MODULE_VERSION = "0.1.19" +MODULE_VERSION = "0.1.20" DEFINITION_READ_SCOPE = "workflow:definition:read" DEFINITION_WRITE_SCOPE = "workflow:definition:write" @@ -410,7 +410,12 @@ manifest = ModuleManifest( ), layer="available", documentation_types=("admin", "user"), - audience=("operator", "workflow_designer", "campaign_manager", "module_admin"), + audience=( + "operator", + "workflow_designer", + "campaign_manager", + "module_admin", + ), related_modules=("campaigns", "views", "tasks", "notifications", "audit"), conditions=( DocumentationCondition( @@ -418,6 +423,26 @@ manifest = ModuleManifest( ), ), order=75, + translations={ + "de": { + "title": "Workflow aus verantwortlicher Campaign-Arbeit fortsetzen", + "summary": ( + "Revisionsgebundene Campaign-Arbeit öffnen, die relevante Oberfläche fokussieren und ohne Polling aus deklarierten " + "Lebenszyklusereignissen fortfahren." + ), + "body": ( + "Der externe Übergabebaustein folgt einer Modulaktion, die eine Campaign anlegt oder referenziert und genau eine " + "verantwortliche Arbeitszuweisung öffnet. Workflow speichert exakte Campaign-Version und Zuweisungsrevision, einen " + "sicheren Aktionslink, Korrelations- und Idempotenzherkunft sowie ein dauerhaftes Ereignisabonnement. Zugewiesen-, " + "angenommen-, begonnen- und neu-zugewiesen-Ereignisse aktualisieren den Wartezustand; abgeschlossene, abgelehnte, " + "abgebrochene und abgelaufene Ergebnisse nehmen getrennte Graphpfade. Doppelte Ereignisse werden ignoriert. Vor der " + "Fortsetzung durch ein Abschlussereignis löst Workflow seine Befugnis erneut auf und Campaign prüft Zugriff und " + "Ereignisrevision. Eine Zuweisung gewährt niemals Campaign-Zugriff. Fehlende Campaign- oder Views-Fähigkeiten halten die " + "Instanz prüfbar, aber blockiert. Fehlende Tasks- oder Notifications-Integration wird als eingeschränkt gemeldet und " + "ändert das Campaign-Ergebnis nicht." + ), + } + }, metadata={ "kind": "workflow", "help_contexts": [ @@ -443,6 +468,27 @@ manifest = ModuleManifest( audience=("user", "operator", "module_admin", "auditor"), related_modules=("core", "cases", "forms_runtime", "services", "tasks"), order=75, + translations={ + "de": { + "title": "Betroffenenanfragen für Workflows", + "summary": ( + "Strukturierte Betroffenenverknüpfungen prüfen, ohne beliebige Prozessnutzdaten offenzulegen oder zu erraten." + ), + "body": ( + "Workflow Engine gleicht exakte mandantenbezogene Kennungen für Definition, Revision, Instanz, Schritt, Ereignis, " + "Auslöser, Lieferung und Wartezustand ab. Zusätzlich werden strukturierte Instanzautorisierung, Arbeitszuweisung, " + "Automatisierungsbefugnis und minimierte Personalzuordnung für Konto-, Identitäts- und Mitgliedschaftsselektoren " + "abgeglichen. DSAR-Ergebnisse kopieren niemals Graphen oder BPMN, Eingaben, Kontext, Ausgaben, Übergaben, Ereignis-/" + "Konfigurationsnutzdaten, Autorisierungs-Snapshots, Fehler, Wiederholungsschlüssel, externe Verweise, Hashes oder " + "Zugangsdaten. Beliebige Laufzeitnutzdaten werden nicht nach Kennungen durchsucht, weil der zuständige Service, Vorgang, " + "das Formular oder ein anderes Quellmodul maßgeblich bleibt. Betroffenenbezogene Automatisierung kann deaktiviert und " + "widerrufen werden; ausdrücklich ausgewählte Details abgeschlossener Auslöserlieferungen können idempotent minimiert " + "werden, während ihr Wiederholungsschlüssel erhalten bleibt. Definitionen, Instanzen, laufende Arbeit, Zuweisungen, " + "unveränderliche Übergangs-/Entscheidungsereignisse, Wartezustände und Betriebszuordnung erfordern die Prüfung durch " + "Workflow-Owner sowie Zuständige für Aufbewahrung, Dritte und Quellhoheit." + ), + } + }, metadata={ "help_contexts": [ "workflow.data-subject-requests", @@ -478,6 +524,21 @@ manifest = ModuleManifest( "audit", ), order=76, + translations={ + "de": { + "title": "Workflow-Definitionsgraphen", + "summary": "Gesteuerte Prozessgraphen unabhängig von einem Editor bereitstellen.", + "body": ( + "Workflow Engine stellt eine Bibliothek aus Auslöser-, Aktivitäts-, Entscheidungs-, Warte-, Integrations- und " + "Ergebnisknoten auf Cores domänenneutralem Graphvertrag bereit. Anders als Dataflow erlaubt Workflow Zyklen für " + "Korrektur- und Wiederholungspfade. Modulaktionen werden über versionierte Fähigkeiten statt Implementierungsimporte " + "adressiert. Definitionen werden als unveränderliche Graphrevisionen gespeichert; die Aktivierung legt die exakte " + "Revision für zukünftige Instanzen fest. Die optionale Service-Startfähigkeit startet eine berechtigte aktive Revision " + "aus einer exakten Portal-Servicebindung und zeichnet diese Herkunft auf. Ist Tasks aktiviert, werden aktuelle menschliche " + "Übergaben mit typisierter Verantwortung, Fälligkeit und fortsetzbarem Quelllink in den gemeinsamen Arbeitskorb projiziert." + ), + } + }, ), DocumentationTopic( id="workflow.bpmn-interchange", @@ -505,6 +566,21 @@ manifest = ModuleManifest( audience=("operator", "module_admin", "power_user", "product_owner"), related_modules=("audit", "policy", "views"), order=77, + translations={ + "de": { + "title": "BPMN-Modellierungs- und Ausführungsprofile", + "summary": "Verlustfreie BPMN-2.0-Revisionen mit ausdrücklicher, sicher schließender Ausführungskonformität.", + "body": ( + "BPMN 2.0 ist die kanonische native Graphsprache von Workflow. Der gemeinsame Grapheditor modelliert BPMN-Knoten, " + "Flüsse, Verschachtelung und Diagrammgeometrie direkt, ohne getrennten browserseitigen Modeler. Importiertes XML wird in " + "den Graphen normalisiert und jede unveränderliche Revision legt ein deterministisches XML-Artefakt fest. Die Aktivierung " + "verlangt einen festgelegten Ausführungsadapter und eine Version, deren erklärtes Profil jede modellierte " + "Laufzeitsemantik akzeptiert. Nicht unterstützte Laufzeitkonstrukte bleiben bearbeitbar und exportierbar. Adapterpakete " + "integrieren über die Entry-Point-Gruppe govoplan.workflow.bpmn_adapters und müssen kanonischen Workflow-Laufzeitzustand " + "materialisieren; Workflow Engine importiert niemals ein konkretes Engine-Modul." + ), + } + }, ), DocumentationTopic( id="workflow.runtime-recovery", @@ -529,6 +605,49 @@ manifest = ModuleManifest( audience=("operator", "module_admin", "power_user"), related_modules=("core", "dataflow", "audit"), order=78, + translations={ + "de": { + "title": "Workflow-Laufzeit wiederherstellen", + "summary": ( + "Abgesicherte Modulaktionen, Zeitgeber und nachweisbasierte Wiederherstellung bei unbekannten Provider-Ergebnissen." + ), + "body": ( + "Workflow Engine zeichnet vor jeder folgenreichen Modulaktion einen Core-Wiederherstellungsvorgang auf und schreibt ein " + "abschließendes Provider-Ergebnis gemeinsam mit der lokalen Workflow-Projektion fest. Ein Timeout oder verlorene " + "Bestätigung nach nicht atomarer Auslieferung wird zu einem unbekannten Ergebnis und deaktiviert Wiederholen. " + "Betriebspersonen prüfen den Provider, halten Nachweise fest und wählen Wirkung bestätigt, um ohne Wiederholung fortzufahren, " + "oder Wirkung ausgeblieben, um eine bewusste Wiederholung zu erlauben. Instanz-Worker, Auslöserlieferungen und Zeitgeber " + "verwenden verteilte Sperren und werden vor der Zustandsübernahme nach Mandanten-Modulberechtigung partitioniert. Das " + "Deaktivieren von Workflow Engine bewahrt angenommene Instanzen, Wartezustände und Auslöserlieferungen für die betriebliche " + "Klärung. Verknüpfte Dataflow-Wiederherstellung bleibt blockiert, bis ihr Ergebnis eindeutig ist." + ), + } + }, + metadata={ + "kind": "reference", + "help_contexts": ["workflow.instances", "workflow.runtime-recovery"], + "consequence_classes": { + "effect_confirmed": "Continues from retained evidence without replaying the provider effect.", + "effect_absent": "Enables one deliberate retry after evidence confirms that the provider effect did not occur.", + "disable_module": "Preserves accepted instances, waits, and trigger deliveries for operator resolution.", + }, + }, + structured_translation_version="1", + structured_translations={ + "de": { + "consequence_classes": { + "effect_confirmed": ( + "Setzt den Ablauf anhand aufbewahrter Nachweise fort, ohne die Provider-Wirkung zu wiederholen." + ), + "effect_absent": ( + "Erlaubt genau eine bewusste Wiederholung, nachdem Nachweise bestätigen, dass die Provider-Wirkung ausblieb." + ), + "disable_module": ( + "Bewahrt angenommene Instanzen, Wartezustände und Auslöserlieferungen für die betriebliche Klärung." + ), + } + } + }, ), ), architecture=declared_module_architecture( diff --git a/tests/test_manifest.py b/tests/test_manifest.py index 3ad547e..0a5a814 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -17,6 +17,23 @@ from govoplan_core.core.workflows import ( class WorkflowManifestTests(unittest.TestCase): + def test_all_static_topics_have_complete_german_content(self) -> None: + manifest = get_manifest() + for topic in manifest.documentation: + german = (topic.translations or {}).get("de", {}) + self.assertEqual({"title", "summary", "body"}, set(german), topic.id) + self.assertTrue( + all(str(value).strip() for value in german.values()), topic.id + ) + + recovery = next( + topic + for topic in manifest.documentation + if topic.id == "workflow.runtime-recovery" + ) + self.assertEqual("reference", recovery.metadata["kind"]) + self.assertTrue(recovery.metadata["consequence_classes"]) + def test_manifest_exposes_definition_contracts(self) -> None: manifest = get_manifest()