3 Commits
Author SHA1 Message Date
zemion 00bec0ed94 fix(packaging): expose immutable WebUI Git package for v0.1.23
Module Package Release / publish-packages (push) Successful in 11s
2026-09-08 02:06:09 +02:00
zemion cfcd723496 docs: complete German structured documentation
Module Package Release / publish-packages (push) Successful in 11s
2026-08-24 01:15:34 +02:00
zemion 06afa79795 docs(forms): complete German reference coverage
Module Package Release / publish-packages (push) Successful in 12s
2026-08-23 20:27:25 +02:00
9 changed files with 220 additions and 7 deletions
+18
View File
@@ -39,3 +39,21 @@ PYTHONPATH=src:/mnt/DATA/git/govoplan-core/src \
``` ```
See [docs/FORMS_BOUNDARY.md](docs/FORMS_BOUNDARY.md) for the boundary decision. See [docs/FORMS_BOUNDARY.md](docs/FORMS_BOUNDARY.md) for the boundary decision.
## Git-source WebUI package
The repository root exposes `@govoplan/forms-webui` for Git-tagged release
dependencies. It mirrors the owning `webui/package.json` version, public
TypeScript/CSS exports and peer requirements, with entry paths under
`webui/src`. Consumers provide the shared Core/React peers; the facade runs no
development or install scripts. The source archive contains `webui/src`, this
README and any repository license file. Run module development checks from `webui/`; Python
installation remains governed by `pyproject.toml`.
Das Repository stellt `@govoplan/forms-webui` am Wurzelpfad für versionierte
Git-Abhängigkeiten bereit. Version, öffentliche TypeScript-/CSS-Exporte und
Peer-Anforderungen entsprechen `webui/package.json`; die Einstiegspfade liegen
unter `webui/src`. Gemeinsame Core-/React-Peers stellt die einbindende Anwendung
bereit. Die Fassade führt keine Entwicklungs- oder Installationsskripte aus.
Entwicklungsprüfungen bleiben in `webui/`, die Python-Installation weiterhin in
`pyproject.toml` definiert.
+33
View File
@@ -0,0 +1,33 @@
{
"name": "@govoplan/forms-webui",
"version": "0.1.23",
"private": true,
"type": "module",
"main": "webui/src/index.ts",
"module": "webui/src/index.ts",
"types": "webui/src/index.ts",
"exports": {
".": {
"types": "./webui/src/index.ts",
"import": "./webui/src/index.ts"
},
"./styles/forms.css": "./webui/src/styles/forms.css"
},
"peerDependencies": {
"@govoplan/core-webui": "^0.1.18",
"lucide-react": "^1.23.0",
"react": ">=19.2.7 <20",
"react-dom": ">=19.2.7 <20",
"react-router": ">=8.3.0 <9"
},
"peerDependenciesMeta": {
"@govoplan/core-webui": {
"optional": true
}
},
"files": [
"webui/src",
"README.md",
"LICENSE"
]
}
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "govoplan-forms" name = "govoplan-forms"
version = "0.1.20" version = "0.1.23"
description = "Immutable reusable form definitions for GovOPlaN." description = "Immutable reusable form definitions for GovOPlaN."
readme = "README.md" readme = "README.md"
requires-python = ">=3.12" requires-python = ">=3.12"
+1 -1
View File
@@ -1,3 +1,3 @@
"""GovOPlaN Forms module.""" """GovOPlaN Forms module."""
__version__ = "0.1.20" __version__ = "0.1.23"
@@ -0,0 +1,84 @@
"""German translations for public structured documentation metadata."""
from __future__ import annotations
from typing import Any
GERMAN_STRUCTURED_TRANSLATIONS: dict[str, dict[str, Any]] = {'forms.data-subject-requests': {'consequence_classes': {'exclude_form_semantics': 'Gibt keinen '
'Schema-, Feld- '
'oder '
'Submission-Value-Inhalt '
'zurück.',
'export_definition_attribution': 'Returns '
'minimierten '
'die '
'unveränderliche '
'Revisionsaktivität.'}},
'forms.definitions': {'privacy_notes': ['Definitionskataloge enthalten Schemata und '
'Richtlinienreferenzen, keine eingereichten '
'Formularwerte.',
'Die Paketbewertung gewährt keinen Zugriff auf '
'referenzierte Laufzeiteinreichungen oder externe '
'Anbieter.',
'Veröffentlichte Zugänglichkeits- und '
'Lokalisierungsinhalte sind überall dort sichtbar, wo die '
'genaue Definition autorisiert ist.']},
'forms.reference.fields-and-consequences': {'consequence_classes': {'import_package': 'Erstellt '
'einen '
'lokalen '
'Entwurf '
'und behält '
'die '
'Herkunft '
'des Pakets '
'ohne '
'automatische '
'Veröffentlichung.',
'publish': 'Macht die genaue '
'Revision für '
'zukünftige '
'autorisierte '
'Instanzen '
'verfügbar.',
'retire': 'Stoppt die '
'zukünftige '
'Nutzung, während '
'Definitionen und '
'genaue '
'Laufzeitreferenzen '
'beibehalten '
'werden.',
'save_revision': 'Erstellt '
'eine '
'unveränderliche '
'Definitionsrevision '
'mit einem '
'Änderungsgrund.'},
'limitations': ['Der Paketimport veröffentlicht '
'niemals automatisch eine '
'Formularrevision.',
'Laufzeiteingaben und eingereichte '
'Werte werden niemals als '
'Definitionskonfiguration exportiert.',
'Generische Paket-Rollback erfordert '
'die Voranwendung Datenbank Snapshot '
'beibehalten.'],
'operational_consequences': ['Preserve blockiert eine '
'widersprüchliche lokale '
'Definition; new '
'revision muss explizit '
'überprüft werden.',
'Das erneute Anwenden '
'eines identischen '
'Quell-Digests ist '
'idempotent und erzeugt '
'keine Revision.',
'Importierte '
'Definitionen erfordern '
'eine normale '
'Überprüfung und '
'Veröffentlichung von '
'Formularen vor der '
'Verwendung zur '
'Laufzeit.']}}
+69 -2
View File
@@ -1,5 +1,8 @@
from __future__ import annotations from __future__ import annotations
from govoplan_core.core.modules import with_documentation_structured_translations
from govoplan_forms.backend.german_structured_documentation import GERMAN_STRUCTURED_TRANSLATIONS
from pathlib import Path from pathlib import Path
from govoplan_core.core.access import ( from govoplan_core.core.access import (
@@ -13,6 +16,7 @@ from govoplan_core.core.module_guards import (
) )
from govoplan_core.core.modules import ( from govoplan_core.core.modules import (
CapabilityDocumentation, CapabilityDocumentation,
DocumentationCondition,
DocumentationLink, DocumentationLink,
DocumentationTopic, DocumentationTopic,
FrontendModule, FrontendModule,
@@ -47,7 +51,7 @@ from govoplan_forms.backend.semantic_subjects import (
MODULE_ID = "forms" MODULE_ID = "forms"
MODULE_NAME = "Forms" MODULE_NAME = "Forms"
MODULE_VERSION = "0.1.20" MODULE_VERSION = "0.1.23"
READ_SCOPE = "forms:definition:read" READ_SCOPE = "forms:definition:read"
WRITE_SCOPE = "forms:definition:write" WRITE_SCOPE = "forms:definition:write"
ADMIN_SCOPE = "forms:definition:admin" ADMIN_SCOPE = "forms:definition:admin"
@@ -97,7 +101,9 @@ def _semantic_subjects(
def _configuration_provider(_context: ModuleContext): def _configuration_provider(_context: ModuleContext):
from govoplan_forms.backend.configuration_provider import SqlFormsConfigurationProvider from govoplan_forms.backend.configuration_provider import (
SqlFormsConfigurationProvider,
)
return SqlFormsConfigurationProvider() return SqlFormsConfigurationProvider()
@@ -292,6 +298,27 @@ manifest = ModuleManifest(
kind="repository", kind="repository",
), ),
), ),
translations={
"de": {
"title": "Konfigurierte Bedeutung von Formularen und Feldern dokumentieren",
"summary": (
"Mandanteneigene semantische Erläuterungen an ein berechtigtes Formular, Feld oder einen Abschnitt anfügen, ohne das "
"Schema zu verändern."
),
"body": (
"Ist Docs installiert, liefert Forms dokumentationssichere Subjekte für jede zugängliche aktuelle Definition sowie ihre "
"stabilen Felder und Abschnitte. Die Subjektidentität übersteht Änderungen an Bezeichnung und Reihenfolge. Ein gelöschter "
"und später neu angelegter Schlüssel erhält eine neue Abstammungsidentität; ältere Dokumentation bleibt ausdrücklich "
"verwaist, statt stillschweigend neu angefügt zu werden. Fingerabdrücke ändern sich nur, wenn sich relevante Formular-, "
"Feld-, Lokalisierungs-, Hierarchie-, Validierungs- oder Sichtbarkeitssemantik ändert, und fordern dann eine redaktionelle "
"Prüfung an; Docs-Inhalte werden niemals automatisch veröffentlicht oder entwertet. Semantischer Text darf Bedeutung, "
"Erhebungszweck, Interpretation, beabsichtigte und nicht beabsichtigte Verwendung sowie Beispiele erläutern, aber weder "
"Feldtyp, Pflichtstatus, Einschränkungen, Validierung, Optionen, Richtlinie noch übermittelte Werte überstimmen. Forms prüft "
"Mandant und Leseberechtigung für Ermittlung, direkte Auflösung, Kontexthilfe, Suche und Docs-Projektion erneut. Fehlt Docs, "
"funktionieren Formularerstellung und statische Hilfe unverändert weiter."
),
}
},
metadata={ metadata={
"kind": "reference", "kind": "reference",
"help_contexts": ["forms.semantic-documentation"], "help_contexts": ["forms.semantic-documentation"],
@@ -317,6 +344,20 @@ manifest = ModuleManifest(
documentation_types=("admin", "user"), documentation_types=("admin", "user"),
audience=("user", "operator", "module_admin", "auditor"), audience=("user", "operator", "module_admin", "auditor"),
related_modules=("core", "forms_runtime", "docs", "audit"), related_modules=("core", "forms_runtime", "docs", "audit"),
translations={
"de": {
"title": "Betroffenenanfragen für Formulardefinitionen",
"summary": "Aktivität der Definitionsautoren exportieren, ohne Schemata als übermittelte Werte zu behandeln.",
"body": (
"Forms gleicht nur eine exakte mandantenbezogene Kontokennung ab und kann eine bereits verifizierte Suche auf ein "
"Formular oder eine Definitionsrevision begrenzen. Ausgegeben werden unveränderliche Revisionskennung, "
"Lebenszykluszustand und Zeitpunkte der Definitionsarbeit der betroffenen Person. Titel, Suchtext, Schemanutzdaten, "
"Feldsemantik, Richtlinienverweise und Inhalte von Änderungsgründen sind nicht enthalten. Forms speichert keine "
"übermittelten Werte; Forms Runtime und der zuständige Service exportieren diese Datensätze getrennt. Die Zuordnung der "
"Definitionsarbeit bleibt mit der unveränderlichen Schemahistorie erhalten."
),
}
},
metadata={ metadata={
"help_contexts": ["forms.catalogue", "privacy.data-subject-requests"], "help_contexts": ["forms.catalogue", "privacy.data-subject-requests"],
"consequence_classes": { "consequence_classes": {
@@ -338,6 +379,11 @@ manifest = ModuleManifest(
layer="configured", layer="configured",
documentation_types=("admin", "user"), documentation_types=("admin", "user"),
audience=("user", "operator", "module_admin", "product_owner"), audience=("user", "operator", "module_admin", "product_owner"),
conditions=(
DocumentationCondition(
any_scopes=(READ_SCOPE, WRITE_SCOPE, ADMIN_SCOPE)
),
),
links=( links=(
DocumentationLink( DocumentationLink(
label="Forms boundary and recovery", label="Forms boundary and recovery",
@@ -345,7 +391,23 @@ manifest = ModuleManifest(
kind="repository", kind="repository",
), ),
), ),
translations={
"de": {
"title": "Wiederverwendbare Formulardefinitionen erstellen",
"summary": (
"Unveränderliche versionierte Schemata erstellen, die Forms Runtime und institutionelle Services verwenden."
),
"body": (
"Jede Revision legt Feldtypen, Optionen, Einschränkungen sowie Anforderungen an Entwurf, Anlagen, Signaturen, "
"Richtlinien und Übergaben fest. Die Veröffentlichung erfolgt ausdrücklich; vorhandene Einreichungen behalten ihre "
"exakte Revision. Katalog, Filter, Leerzustände, Abschnittsüberschriften und Feldgruppen der Definition verwenden die "
"gemeinsame responsive Layoutsprache und ordnen sich bei geringer Breite neu an, ohne Filterumfang, Berechtigungen oder "
"Lebenszykluswirkungen zu verändern."
),
}
},
metadata={ metadata={
"kind": "workflow",
"seed": True, "seed": True,
"help_contexts": [ "help_contexts": [
"forms.navigation", "forms.navigation",
@@ -464,5 +526,10 @@ manifest = ModuleManifest(
) )
manifest = with_documentation_structured_translations(
manifest, locale="de", translations=GERMAN_STRUCTURED_TRANSLATIONS
)
def get_manifest() -> ModuleManifest: def get_manifest() -> ModuleManifest:
return manifest return manifest
+12 -1
View File
@@ -11,6 +11,14 @@ from govoplan_core.core.semantic_documentation import (
class FormsInterfaceDocumentationContractTests(unittest.TestCase): class FormsInterfaceDocumentationContractTests(unittest.TestCase):
def test_all_static_topics_have_complete_german_content(self) -> None:
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
)
def test_route_and_surfaces_remain_declared(self) -> None: def test_route_and_surfaces_remain_declared(self) -> None:
frontend = manifest.frontend frontend = manifest.frontend
self.assertIsNotNone(frontend) self.assertIsNotNone(frontend)
@@ -26,7 +34,10 @@ class FormsInterfaceDocumentationContractTests(unittest.TestCase):
reference = topics["forms.reference.fields-and-consequences"] reference = topics["forms.reference.fields-and-consequences"]
self.assertIn("forms.catalogue", guide.metadata["help_contexts"]) self.assertIn("forms.catalogue", guide.metadata["help_contexts"])
self.assertGreaterEqual(len(guide.metadata["privacy_notes"]), 3) self.assertGreaterEqual(len(guide.metadata["privacy_notes"]), 3)
self.assertIn("forms.field.publication-state", reference.metadata["help_contexts"]) self.assertEqual("workflow", guide.metadata["kind"])
self.assertIn(
"forms.field.publication-state", reference.metadata["help_contexts"]
)
self.assertIn("publish", reference.metadata["consequence_classes"]) self.assertIn("publish", reference.metadata["consequence_classes"])
self.assertIn("import_package", reference.metadata["consequence_classes"]) self.assertIn("import_package", reference.metadata["consequence_classes"])
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@govoplan/forms-webui", "name": "@govoplan/forms-webui",
"version": "0.1.20", "version": "0.1.23",
"private": true, "private": true,
"type": "module", "type": "module",
"main": "src/index.ts", "main": "src/index.ts",
+1 -1
View File
@@ -9,7 +9,7 @@ const FormsPage = lazy(() => import("./features/forms/FormsPage"));
export const formsModule: PlatformWebModule = { export const formsModule: PlatformWebModule = {
id: "forms", id: "forms",
label: "i18n:govoplan-forms.form_definitions", label: "i18n:govoplan-forms.form_definitions",
version: "0.1.20", version: "0.1.21",
dependencies: ["access"], dependencies: ["access"],
optionalDependencies: ["forms_runtime", "portal", "workflow_engine", "cases", "policy", "docs"], optionalDependencies: ["forms_runtime", "portal", "workflow_engine", "cases", "policy", "docs"],
translations: generatedTranslations, translations: generatedTranslations,