From b24d291cc8def98312cd40f80abe95f809baa2fc Mon Sep 17 00:00:00 2001 From: Albrecht Degering Date: Sat, 22 Aug 2026 06:50:34 +0200 Subject: [PATCH] docs(postbox): complete German reference coverage --- pyproject.toml | 2 +- src/govoplan_postbox/__init__.py | 2 +- src/govoplan_postbox/backend/manifest.py | 50 ++++++++++++++++++- .../test_interface_documentation_contract.py | 11 ++++ webui/package.json | 2 +- .../test-interface-pattern-language.mjs | 2 +- webui/src/module.ts | 2 +- 7 files changed, 65 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a447f6f..065dec7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "govoplan-postbox" -version = "0.1.18" +version = "0.1.19" description = "Function-bound institutional postboxes for GovOPlaN." readme = "README.md" requires-python = ">=3.12" diff --git a/src/govoplan_postbox/__init__.py b/src/govoplan_postbox/__init__.py index de177f4..6b6c84b 100644 --- a/src/govoplan_postbox/__init__.py +++ b/src/govoplan_postbox/__init__.py @@ -1,3 +1,3 @@ """GovOPlaN Postbox module.""" -__version__ = "0.1.18" +__version__ = "0.1.19" diff --git a/src/govoplan_postbox/backend/manifest.py b/src/govoplan_postbox/backend/manifest.py index 8d47afa..ad223e4 100644 --- a/src/govoplan_postbox/backend/manifest.py +++ b/src/govoplan_postbox/backend/manifest.py @@ -72,7 +72,7 @@ from govoplan_postbox.backend.permissions import ( MODULE_ID = "postbox" MODULE_NAME = "Postbox" -MODULE_VERSION = "0.1.18" +MODULE_VERSION = "0.1.19" def _permission(scope: str, label: str, description: str) -> PermissionDefinition: @@ -665,6 +665,19 @@ manifest = ModuleManifest( documentation_types=("admin", "user"), audience=("administrator", "user", "campaign_manager"), related_modules=("search", "idm", "encryption"), + translations={ + "de": { + "title": "Berechtigte Postfachnachrichten durchsuchen", + "summary": "Betreffzeilen und zulässige Klartextinhalte aus Postbox für die berechtigungsgeprüfte Plattform-Suche bereitstellen.", + "body": ( + "Ist Search installiert, stellt Postbox ausschließlich Betreffzeilen, Absenderbezeichnungen und Klartextinhalte " + "von Nachrichten bereit. Chiffrat und Schlüsselmaterial werden niemals indiziert. Jedes Ergebnis ist auf den " + "Mandanten begrenzt und prüft aktuelle Funktionszuweisung, Postfachbindung, Klassifikation, Handlungskontext " + "und allgemeine Leseberechtigung erneut, ohne die Nachricht als gelesen zu markieren. Abgeschlossene Zustellungen " + "und Nachrichtenänderungen aktualisieren den abgeleiteten Index über den dauerhaften Plattform-Ereignispfad." + ), + } + }, order=34, ), DocumentationTopic( @@ -876,6 +889,22 @@ manifest = ModuleManifest( kind="api", ), ), + translations={ + "de": { + "title": "Funktionsgebundene Postfächer", + "summary": "Dauerhafte institutionelle Nachrichtencontainer, deren Zugriff den wirksamen Zuweisungen zu Organisationsfunktionen folgt.", + "body": ( + "Postfächer gehören zu Verantwortlichkeiten und nicht zu einzelnen Konten. Ein stabiles Postfach bleibt während " + "einer Vakanz und Neubesetzung adressierbar. Der aktuelle Zugriff verbindet eine allgemeine Postfachberechtigung " + "mit dem wirksamen IDM-Zuweisungskontext. Vorlagen können einheitsspezifische Adressen bei Bedarf erzeugen; exakte " + "Postfächer bilden besondere Verantwortlichkeiten ab. Die Administration wählt Klartext, die empfohlene institutionell " + "verwaltete Encryption-Umschlagverschlüsselung oder einen strikten, extern erzeugten E2EE-Vertrag. Verwaltete Umschläge " + "bleiben für berechtigte institutionelle Schlüsselverantwortliche entschlüsselbar; E2EE weist Klartext zurück und " + "GovOPlaN besitzt keinen privaten Entschlüsselungsschlüssel. Ist Tasks aktiviert, erscheinen aktuell lesbare ungelesene " + "Nachrichten auch im gemeinsamen Arbeitsvorrat und verschwinden dort, sobald der persönliche Lesestatus gespeichert ist." + ), + } + }, metadata={ "kind": "guide", "help_contexts": [ @@ -940,6 +969,25 @@ manifest = ModuleManifest( kind="source", ), ), + translations={ + "de": { + "title": "Postfachfelder und ihre Auswirkungen", + "summary": "Referenz für Adresse, Vorlage, Routing, Nachricht, Gruppierung, Klassifikation, Aufbewahrung und Lebenszyklus.", + "body": ( + "Eine Postfachadresse ist dauerhaft und an eine Organisationsfunktion gebunden. Vorlagenrevisionen sind nach der " + "Veröffentlichung unveränderlich; die Stilllegung einer Vorlage entfernt keine bereits erzeugten Adressen. Die " + "Archivierung einer Adresse stoppt neue Zustellungen und bewahrt Nachrichten und Nachweise. Zusammengefasste " + "Posteingänge sind ausschließlich persönliche Projektionen und verschieben oder löschen niemals Quellnachrichten. " + "Die Klassifikation begrenzt zulässige Zustellungs- und Hierarchiekopieziele. Hierarchiekopien sind eigenständige " + "Zustellungen mit eigenen Nachweisen; die Vakanzeskalation erfolgt verzögert und getrennt prüfbar. Ablauf oder Rücknahme " + "einer Nachricht sperrt den künftigen Inhaltszugriff, kann aber bereits kopierten, exportierten oder gedruckten Klartext " + "nicht zurückrufen. Teilbaumvorlagen wählen genau eine Organisationsstruktur und optional Beziehungstypen. Ihre " + "schreibgeschützte Auswirkungsvorschau meldet erzeugte Adressen, aktuelle Stelleninhaber, Vakanzen, Kollisionen, Zyklen, " + "Tiefengrenzen und mehrdeutige Pfade, ohne Vorlagen oder Postfächer anzulegen. Gruppierungssummen umfassen nur Quellpostfächer, " + "die für das aktuelle Konto sichtbar sind." + ), + } + }, metadata={ "kind": "reference", "help_contexts": [ diff --git a/tests/test_interface_documentation_contract.py b/tests/test_interface_documentation_contract.py index 7e46e43..8d213e8 100644 --- a/tests/test_interface_documentation_contract.py +++ b/tests/test_interface_documentation_contract.py @@ -10,6 +10,17 @@ REPOSITORY_ROOT = Path(__file__).resolve().parents[1] class PostboxInterfaceDocumentationContractTests(unittest.TestCase): + def test_public_topics_have_complete_german_coverage(self) -> None: + topics = manifest.documentation + + self.assertEqual(9, len(topics)) + for topic in topics: + translation = topic.translations["de"] + self.assertEqual({"title", "summary", "body"}, set(translation)) + self.assertTrue( + all(str(translation[field]).strip() for field in translation) + ) + def test_route_and_contributed_surfaces_remain_declared(self) -> None: frontend = manifest.frontend self.assertIsNotNone(frontend) diff --git a/webui/package.json b/webui/package.json index 05d788a..82f3bf6 100644 --- a/webui/package.json +++ b/webui/package.json @@ -1,6 +1,6 @@ { "name": "@govoplan/postbox-webui", - "version": "0.1.18", + "version": "0.1.19", "private": true, "type": "module", "main": "src/index.ts", diff --git a/webui/scripts/test-interface-pattern-language.mjs b/webui/scripts/test-interface-pattern-language.mjs index 159b6ab..86e4279 100644 --- a/webui/scripts/test-interface-pattern-language.mjs +++ b/webui/scripts/test-interface-pattern-language.mjs @@ -22,7 +22,7 @@ assert(page.includes("useUnsavedDraftGuard") && admin.includes("useUnsavedDraftG assert(page.includes("delete_grouping_confirmation") && page.includes("ConfirmDialog"), "Deleting a unified view confirms that source records remain unchanged"); assert(admin.includes("archive_confirmation") && admin.includes("retire_template_confirmation"), "Address and template lifecycle actions use shared destructive confirmation"); assert(patterns.includes('topicId: "postbox.function-bound-containers"') && patterns.includes('topicId: "postbox.reference.fields-and-consequences"'), "Postbox uses manifest-backed help references"); -assert(moduleSource.includes('version: "0.1.18"') && moduleSource.includes("generatedTranslations"), "WebUI metadata matches the module release and registers translations"); +assert(moduleSource.includes('version: "0.1.19"') && moduleSource.includes("generatedTranslations"), "WebUI metadata matches the module release and registers translations"); assert(translations.includes('"i18n:govoplan-postbox.unavailable_message_reason"'), "Access-sensitive unavailable states are localized"); assert(widget.includes("usePlatformLanguage") && widget.includes("i18nMessage"), "Widget dates and dynamic accessible labels follow the platform locale"); assert(!page.includes("window.confirm") && !admin.includes("window.confirm"), "Postbox does not use browser-native consequential confirmation"); diff --git a/webui/src/module.ts b/webui/src/module.ts index 468ca01..5ebf01a 100644 --- a/webui/src/module.ts +++ b/webui/src/module.ts @@ -97,7 +97,7 @@ const postboxAdminSections: AdminSectionsUiCapability = { export const postboxModule: PlatformWebModule = { id: "postbox", label: "i18n:govoplan-postbox.postbox", - version: "0.1.18", + version: "0.1.19", dependencies: ["identity", "organizations", "idm"], optionalDependencies: [ "access",