docs(idm): complete German reference coverage
Module Package Release / publish-packages (push) Successful in 11s

This commit is contained in:
2026-08-23 20:19:15 +02:00
parent 3dd7766b08
commit e9f8e0a1f8
5 changed files with 213 additions and 26 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@govoplan/idm-webui",
"version": "0.1.18",
"version": "0.1.22",
"private": true,
"type": "module",
"main": "webui/src/index.ts",
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "govoplan-idm"
version = "0.1.21"
version = "0.1.22"
description = "GovOPlaN identity management bridge module."
readme = "README.md"
requires-python = ">=3.12"
+195 -21
View File
@@ -66,7 +66,7 @@ from govoplan_idm.backend.search_source import create_idm_search_source
from govoplan_idm.backend.scim import SCIM_EXTERNAL_PROVIDER_ID
MODULE_VERSION = "0.1.21"
MODULE_VERSION = "0.1.22"
IDM_READ_SCOPES = (
"idm:organization_assignment:read",
@@ -204,7 +204,9 @@ def _idm_directory(context: ModuleContext) -> object:
from govoplan_idm.backend.directory import SqlIdmDirectory
identities = context.registry.require_capability(CAPABILITY_IDENTITY_DIRECTORY)
organizations = context.registry.require_capability(CAPABILITY_ORGANIZATION_DIRECTORY)
organizations = context.registry.require_capability(
CAPABILITY_ORGANIZATION_DIRECTORY
)
if not isinstance(identities, IdentityDirectory):
raise RuntimeError(f"Invalid capability: {CAPABILITY_IDENTITY_DIRECTORY}")
if not isinstance(organizations, OrganizationDirectory):
@@ -376,12 +378,32 @@ manifest = ModuleManifest(
factory=create_idm_search_source,
),
),
nav_items=(NavItem(path="/idm", label="IDM", icon="users", required_any=IDM_READ_SCOPES, order=72),),
nav_items=(
NavItem(
path="/idm",
label="IDM",
icon="users",
required_any=IDM_READ_SCOPES,
order=72,
),
),
frontend=FrontendModule(
module_id="idm",
package_name="@govoplan/idm-webui",
routes=(FrontendRoute(path="/idm", component="IdmPage", required_any=IDM_READ_SCOPES, order=72),),
nav_items=(NavItem(path="/idm", label="IDM", icon="users", required_any=IDM_READ_SCOPES, order=72),),
routes=(
FrontendRoute(
path="/idm", component="IdmPage", required_any=IDM_READ_SCOPES, order=72
),
),
nav_items=(
NavItem(
path="/idm",
label="IDM",
icon="users",
required_any=IDM_READ_SCOPES,
order=72,
),
),
product_areas=(
ProductAreaContribution(
id="people-responsibility",
@@ -548,9 +570,7 @@ manifest = ModuleManifest(
"organizations",
"records",
),
conditions=(
DocumentationCondition(required_modules=("idm", "access")),
),
conditions=(DocumentationCondition(required_modules=("idm", "access")),),
links=(
DocumentationLink(
label="Data-subject requests",
@@ -563,6 +583,28 @@ manifest = ModuleManifest(
kind="runtime",
),
),
translations={
"de": {
"title": "IDM-Daten in einer Betroffenenanfrage prüfen",
"summary": (
"Mandantenbezogene institutionelle Funktions- und Beziehungsmerkmale erfassen und dabei gesteuerte "
"Entscheidungsnachweise bewahren."
),
"body": (
"IDM durchsucht bestätigte Konto- und Identitätsselektoren sowie namensraumgebundene Zuweisungs-, Beziehungs- und "
"Zuweisungsänderungsverweise. Ergebnisse umfassen zeitlich wirksame Organisationsfunktionszuweisungen, typisierte "
"Identitätsbeziehungen mit minimiertem Gruppenkontext, gesteuerte Zuweisungsanträge oder -erteilungen und zugehörige "
"Lebenszyklusereignisse. Betrifft ein Datensatz eine andere kandidierende oder handelnde Person, werden deren Identitäts- "
"und Kontokennungen aus dem automatischen Export entfernt. Einstellungen, Gruppeneigenschaften, externe Quellverweise, "
"Herkunft, Begründungen, Nachweislisten, Richtlinienentscheidungen, Workflow-Interna, Idempotenzschlüssel, Anfrage-Digests, "
"undurchsichtige Metadaten, Ereigniskommentare und -details, unbeteiligte Datensätze und andere Mandanten sind ausgeschlossen. "
"Zuweisungen und Beziehungen sind wirksame institutionelle Tatsachen; Korrektur, Widerruf, Deaktivierung oder Ablauf "
"erfordern daher eine berechtigte IDM-Lebenszyklusprüfung. Gesteuerte Änderungs- und Ereignisdatensätze bewahren "
"ausdrückliche Gründe für Entscheidungsnachweise. Identity besitzt den Personendatensatz, Organizations Funktionen und "
"Einheiten und Access die aus bestätigten IDM-Tatsachen abgeleitete Befugnis."
),
}
},
metadata={
"kind": "guide",
"help_contexts": [
@@ -587,6 +629,21 @@ manifest = ModuleManifest(
documentation_types=("admin", "user"),
audience=("tenant_admin", "access_admin", "operator"),
related_modules=("search", "identity", "organizations"),
translations={
"de": {
"title": "Berechtigte IDM-Datensätze durchsuchen",
"summary": (
"Typisierte Gruppen, zeitlich wirksame Beziehungen und Organisationsfunktionszuweisungen für die "
"berechtigungsbewusste Plattform-Suche bereitstellen."
),
"body": (
"Ist Search installiert, liefert IDM begrenzte Verzeichnis- und Zuweisungsmetadaten, ohne uneingeschränkte "
"Herkunftsdaten zu kopieren. Jedes Ergebnis bleibt mandantengebunden und prüft die aktuelle Leseberechtigung für "
"Zuweisung oder Beziehung erneut. Festgeschriebene IDM-Lebenszyklusereignisse aktualisieren den abgeleiteten Index; ein "
"betrieblicher Neuaufbau gleicht Datensätze ab, die vor der Aktivierung von Search angelegt wurden."
),
}
},
order=25,
),
DocumentationTopic(
@@ -602,6 +659,20 @@ manifest = ModuleManifest(
documentation_types=("admin", "user"),
audience=("tenant_admin", "access_admin", "operator"),
related_modules=("identity", "organizations", "access"),
translations={
"de": {
"title": "Brücke zwischen Identität und Organisation",
"summary": (
"IDM löst auf, welche Identitäten und Konten Organisationsfunktionszuweisungen zugeordnet werden können."
),
"body": (
"Identity besitzt normalisierte Identitäten und Kontoverknüpfungen. Organizations besitzt Einheiten und Funktionen. "
"IDM besitzt die Zuweisungsverknüpfungen zwischen Identitäten und Organisationsfunktionen, einschließlich Identitätssuche "
"für Organisationszuweisungen und zukünftiger Synchronisations-/Zuordnungsabläufe. Access darf diese Verknüpfungen nutzen, "
"wenn IDM installiert ist; IDM benötigt Access jedoch nicht, um Rechte auszuwerten."
),
}
},
order=26,
),
DocumentationTopic(
@@ -631,6 +702,26 @@ manifest = ModuleManifest(
kind="api",
),
),
translations={
"de": {
"title": "Governance von IDM-Zuweisungen",
"summary": (
"Mandantenbezogene IDM-Einstellungen können freigegebene Änderungsanträge verlangen, bevor "
"Identitäts-Funktionszuweisungen angewendet werden."
),
"body": (
"Zuweisungsverknüpfungen haben hohe Auswirkung, weil sie später Zugriffsentscheidungen speisen können. Mandanten können "
"aufgezeichnete Änderungsanträge für Anlage und Aktualisierung von Zuweisungen verlangen. Zusätzlich lassen sich "
"Obergrenzen für Tiefe und Gültigkeit von Delegationsketten sowie ausdrückliche Eskalationsziele und Fristen für Prüfungen "
"durch Inhabende, verantwortliche Stelle oder Empfangende konfigurieren. IDM prüft vollständige Wege bei jeder "
"Entscheidung und der endgültigen Anwendung gegen die aktuelle Policy. Abgelaufene Fristen werden als sichtbarer "
"eskalierter Zustand mit Notifications- und Auditnachweis erfasst; eine Freigabe wird nicht unterstellt. Ein periodischer "
"Worker sendet genau ein Ablaufereignis, wenn eine zukünftige Zuweisung endet. Kennzeichnung und Ereignis werden gemeinsam "
"festgeschrieben, damit Wiederholungen idempotent bleiben. Der alte Bereich organizations:function:assign bleibt während "
"des Übergangs gültig; neue Rollenvorlagen sollten idm:organization_assignment:write gewähren."
),
}
},
metadata={
"kind": "reference",
"help_contexts": [
@@ -672,10 +763,24 @@ manifest = ModuleManifest(
),
),
links=(
DocumentationLink(label="IDM relationship administration", href="/idm", kind="runtime"),
DocumentationLink(label="Typed groups API", href="/api/v1/idm/typed-groups", kind="api"),
DocumentationLink(label="Identity relationships API", href="/api/v1/idm/relationships", kind="api"),
DocumentationLink(label="Typed relationship contract", href="docs/TYPED_RELATIONSHIPS.md", kind="repository"),
DocumentationLink(
label="IDM relationship administration", href="/idm", kind="runtime"
),
DocumentationLink(
label="Typed groups API",
href="/api/v1/idm/typed-groups",
kind="api",
),
DocumentationLink(
label="Identity relationships API",
href="/api/v1/idm/relationships",
kind="api",
),
DocumentationLink(
label="Typed relationship contract",
href="docs/TYPED_RELATIONSHIPS.md",
kind="repository",
),
),
translations={
"de": {
@@ -779,9 +884,7 @@ manifest = ModuleManifest(
documentation_types=("admin", "user"),
audience=("tenant_admin", "access_admin", "operator", "user"),
related_modules=("identity", "organizations", "access"),
conditions=(
DocumentationCondition(any_scopes=IDM_READ_SCOPES),
),
conditions=(DocumentationCondition(any_scopes=IDM_READ_SCOPES),),
links=(
DocumentationLink(
label="IDM assignments",
@@ -794,6 +897,24 @@ manifest = ModuleManifest(
kind="api",
),
),
translations={
"de": {
"title": "Einer Identität eine Organisationsfunktion zuweisen",
"summary": (
"IDM verknüpft Identitäten oder Konten mit Organisationsfunktionen; Access kann bestätigte Verknüpfungen bei "
"vorhandener Funktions-Rollenzuordnung verwenden."
),
"body": (
"Legen Sie zuerst Einheit und Funktion in Organizations an und stellen Sie sicher, dass Person und Konto in Identity "
"bestehen. Erstellen Sie anschließend die Zuweisung in IDM. Direkte Zuweisungen halten fest, wer die Funktion innehat. "
"Delegierte Zuweisungen benötigen eine Quellzuweisung und eine delegierbare Funktion. Stellvertretungszuweisungen benötigen "
"Quellzuweisung, handelndes Konto und eine Funktion, die Handeln an Stelle zulässt. Access bildet bestätigte "
"Funktionsmerkmale auf Rollen und Rechte ab; ohne eine solche Zuordnung wird die Zuweisung gespeichert, gewährt aber keine "
"Anwendungsberechtigungen. Der Zuweisungsarbeitsbereich nutzt die verfügbare Anwendungsbreite, sodass Governance-Steuerungen "
"und Zuweisungsdaten gemeinsam sichtbar bleiben."
),
}
},
metadata={
"kind": "workflow",
"help_contexts": [
@@ -835,7 +956,14 @@ manifest = ModuleManifest(
layer="configured",
documentation_types=("admin", "user"),
audience=("tenant_admin", "access_admin", "operator", "user"),
related_modules=("identity", "organizations", "access", "policy", "audit", "workflow_engine"),
related_modules=(
"identity",
"organizations",
"access",
"policy",
"audit",
"workflow_engine",
),
links=(
DocumentationLink(
label="Function assignment workflows",
@@ -843,6 +971,30 @@ manifest = ModuleManifest(
kind="repository",
),
),
translations={
"de": {
"title": "Felder und Folgen von IDM-Zuweisungen",
"summary": (
"Referenz für direkte Zuweisungen, Delegation, Stellvertretung, Wirksamkeitsdaten, gesteuerte Änderungen, Nachweise und "
"Aufbewahrung."
),
"body": (
"Identität und Konto wählen, wer die institutionelle Tatsache erhält; Funktion und Einheit gehören Organizations. Die "
"Quelle unterscheidet direkte, delegierte, stellvertretende, Verzeichnis-, Governance- und Systemtatsachen. Delegation und "
"Stellvertretung verlangen eine gültige Quellzuweisung und die entsprechende Organizations-Funktionsberechtigung. Eine "
"delegierte Person handelt als sie selbst; bei Stellvertretung muss Access zusätzlich den exakten Repräsentationskontext "
"auswählen, bevor daraus Befugnis entsteht. Quell- und abgeleitete Zuweisungen müssen aktuell, aktiv, mandantenlokal und "
"funktionskompatibel bleiben. Der Untereinheitenbereich erweitert die organisatorische Reichweite. Deaktivierung und Ablauf "
"bewahren die Herkunft, entfernen die Zuweisung aber aus der wirksamen Auflösung. Entscheidungen zu gesteuerten Anträgen "
"und Erteilungen bewahren handelnde Person, Richtlinie, Workflow-Revision, Kommentare und Nachweise. Delegierte Befugnis "
"wird über die vollständige Quellkette gegen aktuelle Tiefen- und Gültigkeitsgrenzen geprüft. Eine konfigurierte Frist pro "
"Schritt erzeugt einen sichtbaren eskalierten Zustand und eine exakte Zielfunktionsroute; sie ersetzt oder protokolliert "
"niemals automatisch eine freigebende Person. Eine Notfallüberschreibung ist nicht der Normalweg und benötigt einen "
"ausdrücklichen Grund. Eine IDM-Zuweisung allein gewährt niemals Anwendungsberechtigungen; Access verlangt eine "
"ausdrückliche Zuordnung."
),
}
},
metadata={
"kind": "reference",
"help_contexts": [
@@ -878,12 +1030,34 @@ manifest = ModuleManifest(
maturity="vertical_slice",
documentation_ref="docs/FUNCTION_ASSIGNMENT_WORKFLOWS.md",
test_ref="tests/test_assignment_workflow.py",
known_limits=("SCIM provisioning is a deterministic preview; governed plan execution is not implemented yet.",),
known_limits=(
"SCIM provisioning is a deterministic preview; governed plan execution is not implemented yet.",
),
supported_authority_modes=("external_authoritative", "external_mirror"),
owned_concepts=("function assignment", "assignment delegation", "acting-for assignment", "assignment request", "typed group", "identity relationship"),
non_owned_concepts=("identity", "organization function", "application role", "workflow runtime"),
recovery_docs=("docs/FUNCTION_ASSIGNMENT_WORKFLOWS.md", "docs/TYPED_RELATIONSHIPS.md", "docs/SCIM_PROVISIONING.md"),
security_docs=("docs/FUNCTION_ASSIGNMENT_WORKFLOWS.md", "docs/TYPED_RELATIONSHIPS.md", "docs/SCIM_PROVISIONING.md"),
owned_concepts=(
"function assignment",
"assignment delegation",
"acting-for assignment",
"assignment request",
"typed group",
"identity relationship",
),
non_owned_concepts=(
"identity",
"organization function",
"application role",
"workflow runtime",
),
recovery_docs=(
"docs/FUNCTION_ASSIGNMENT_WORKFLOWS.md",
"docs/TYPED_RELATIONSHIPS.md",
"docs/SCIM_PROVISIONING.md",
),
security_docs=(
"docs/FUNCTION_ASSIGNMENT_WORKFLOWS.md",
"docs/TYPED_RELATIONSHIPS.md",
"docs/SCIM_PROVISIONING.md",
),
operations_docs=("README.md", "docs/SCIM_PROVISIONING.md"),
),
)
+15 -2
View File
@@ -7,6 +7,14 @@ from govoplan_idm.backend.api.v1.routes import ORGANIZATION_IDENTITY_READ_SCOPES
class IdmInterfaceDocumentationContractTests(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_contributed_action_remain_declared(self) -> None:
frontend = manifest.frontend
self.assertIsNotNone(frontend)
@@ -54,8 +62,13 @@ class IdmInterfaceDocumentationContractTests(unittest.TestCase):
"idm.typed-groups.action.resolve-memberships",
relationships.metadata["help_contexts"],
)
self.assertIn("Revocation immediately", relationships.metadata["consequences"][2])
self.assertIn("Access permissions remain unchanged", relationships.metadata["verification"])
self.assertIn(
"Revocation immediately", relationships.metadata["consequences"][2]
)
self.assertIn(
"Access permissions remain unchanged",
relationships.metadata["verification"],
)
def test_relationship_writers_may_use_identity_search_selectors(self) -> None:
self.assertIn("idm:relationship:write", ORGANIZATION_IDENTITY_READ_SCOPES)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@govoplan/idm-webui",
"version": "0.1.21",
"version": "0.1.22",
"private": true,
"type": "module",
"main": "src/index.ts",