Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b8c6c548e | ||
|
|
930302b535 | ||
|
|
ad8235028f | ||
|
|
62970d6374 | ||
|
|
6b1c0ca786 |
@@ -70,3 +70,21 @@ Published or referenced state, immutable materializations, lifecycle evidence,
|
|||||||
governance evidence,
|
governance evidence,
|
||||||
holds, and operator attribution require data-steward review. Dataflow and
|
holds, and operator attribution require data-steward review. Dataflow and
|
||||||
Reporting derivatives must be refreshed after the source correction.
|
Reporting derivatives must be refreshed after the source correction.
|
||||||
|
|
||||||
|
## Git-source WebUI package
|
||||||
|
|
||||||
|
The repository root exposes `@govoplan/datasources-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/datasources-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.
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "@govoplan/datasources-webui",
|
||||||
|
"version": "0.1.25",
|
||||||
|
"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/datasources.css": "./webui/src/styles/datasources.css"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@govoplan/core-webui": "^0.1.45",
|
||||||
|
"lucide-react": "^1.23.0",
|
||||||
|
"react": ">=19.2.7 <20",
|
||||||
|
"react-dom": ">=19.2.7 <20",
|
||||||
|
"react-router": ">=8.3.0 <9",
|
||||||
|
"typescript": "^5.7.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@govoplan/core-webui": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"webui/src",
|
||||||
|
"README.md",
|
||||||
|
"LICENSE"
|
||||||
|
]
|
||||||
|
}
|
||||||
+2
-2
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "govoplan-datasources"
|
name = "govoplan-datasources"
|
||||||
version = "0.1.21"
|
version = "0.1.25"
|
||||||
description = "Governed datasource catalogue, staging, and materialization lifecycle for GovOPlaN."
|
description = "Governed datasource catalogue, staging, and materialization lifecycle for GovOPlaN."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
license = "AGPL-3.0-or-later"
|
license = "AGPL-3.0-or-later"
|
||||||
authors = [{ name = "GovOPlaN" }]
|
authors = [{ name = "GovOPlaN" }]
|
||||||
dependencies = ["govoplan-core>=0.1.20"]
|
dependencies = ["govoplan-core>=0.1.45"]
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
[tool.setuptools.packages.find]
|
||||||
where = ["src"]
|
where = ["src"]
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
"""GovOPlaN Datasources module."""
|
"""GovOPlaN Datasources module."""
|
||||||
|
|
||||||
__version__ = "0.1.21"
|
__version__ = "0.1.25"
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
"""German translations for public structured documentation metadata."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
GERMAN_STRUCTURED_TRANSLATIONS: dict[str, dict[str, Any]] = {'datasources.approval-and-retention': {'limitations': ['Die Ausführung der Retention ist explizit '
|
||||||
|
'und plangebunden; dieses Modul führt '
|
||||||
|
'keinen versteckten Löschplan aus.',
|
||||||
|
'Disponierte '
|
||||||
|
'Materialisierungsaufzeichnungen behalten '
|
||||||
|
'minimierte Schema- und Herkunftsmetadaten '
|
||||||
|
'bei, während ihre Nutzdatenzeilen '
|
||||||
|
'entfernt werden.']},
|
||||||
|
'datasources.quality-gates': {'limitations': ['Referenzregeln verwenden derzeit einen begrenzten '
|
||||||
|
'eingebetteten Wertsatz, anstatt eine andere '
|
||||||
|
'geschützte Datenquelle zu lesen.',
|
||||||
|
'Genehmigungen sind modullokale '
|
||||||
|
'Lebenszyklusnachweise; die Installation eines '
|
||||||
|
'separaten Genehmigungsmoduls ändert nicht '
|
||||||
|
'stillschweigend die konfigurierte '
|
||||||
|
'Datenquellenrichtlinie.',
|
||||||
|
'Die Aufbewahrung erfolgt nie automatisch: Ein '
|
||||||
|
'Administrator muss eine Vorschau eines aktuellen '
|
||||||
|
'Plans anzeigen und ausdrücklich berechtigte Ziele '
|
||||||
|
'anwenden.',
|
||||||
|
'Artefaktbytes bleiben im Besitz ihres '
|
||||||
|
'Payload-Backends; Datasources speichert einen '
|
||||||
|
'unveränderlichen Referenz- und '
|
||||||
|
'Integritätsnachweis.']},
|
||||||
|
'datasources.reference.fields-and-consequences': {'consequence_classes': {'freeze': 'Erstellt '
|
||||||
|
'einen '
|
||||||
|
'gekennzeichneten '
|
||||||
|
'unveränderlichen '
|
||||||
|
'Zustand für '
|
||||||
|
'reproduzierbare '
|
||||||
|
'Verbraucher '
|
||||||
|
'und '
|
||||||
|
'Nachweise.',
|
||||||
|
'promote': 'Erstellt '
|
||||||
|
'oder '
|
||||||
|
'aktualisiert '
|
||||||
|
'eine '
|
||||||
|
'geregelte '
|
||||||
|
'Datenquelle '
|
||||||
|
'und fügt '
|
||||||
|
'eine '
|
||||||
|
'unveränderliche '
|
||||||
|
'Materialisierungsrevision '
|
||||||
|
'hinzu.',
|
||||||
|
'refresh': 'Leset den '
|
||||||
|
'zwischengespeicherten '
|
||||||
|
'Ursprung '
|
||||||
|
'und fügt '
|
||||||
|
'eine neue '
|
||||||
|
'unveränderliche '
|
||||||
|
'Materialisierungsrevision '
|
||||||
|
'hinzu.',
|
||||||
|
'retire': 'Verhindert '
|
||||||
|
'eine neue '
|
||||||
|
'Auswahl, '
|
||||||
|
'während die '
|
||||||
|
'Referenzen '
|
||||||
|
'für die '
|
||||||
|
'Materialisierung '
|
||||||
|
'beibehalten '
|
||||||
|
'werden.'}},
|
||||||
|
'datasources.visibility': {'limitations': ['Zeilenfilter unterstützen deterministische Gleichheit '
|
||||||
|
'oder Mitgliedschaft gegen Hauptansprüche; '
|
||||||
|
'willkürliche Ausdrücke werden nicht ausgeführt.',
|
||||||
|
'Live-gefilterte Vorschauen scannen maximal 10.000 '
|
||||||
|
'Ursprungszeilen und legen eine strukturierte '
|
||||||
|
'Einschränkungsdiagnose offen, wenn der Ursprung '
|
||||||
|
'größer ist.']}}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from govoplan_core.core.modules import with_documentation_structured_translations
|
||||||
|
from govoplan_datasources.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 (
|
||||||
@@ -65,7 +68,7 @@ from govoplan_datasources.backend.payloads import ExternalArtifactPayloadBackend
|
|||||||
|
|
||||||
MODULE_ID = "datasources"
|
MODULE_ID = "datasources"
|
||||||
MODULE_NAME = "Datasources"
|
MODULE_NAME = "Datasources"
|
||||||
MODULE_VERSION = "0.1.21"
|
MODULE_VERSION = "0.1.25"
|
||||||
DATASOURCE_INTERFACE_VERSION = "0.2.0"
|
DATASOURCE_INTERFACE_VERSION = "0.2.0"
|
||||||
|
|
||||||
ARCHITECTURE = ModuleArchitectureDeclaration(
|
ARCHITECTURE = ModuleArchitectureDeclaration(
|
||||||
@@ -252,8 +255,7 @@ def _tenant_summary(session, tenant_id: str) -> dict[str, int]:
|
|||||||
session.query(datasource_models.DatasourceStageRecord)
|
session.query(datasource_models.DatasourceStageRecord)
|
||||||
.filter(
|
.filter(
|
||||||
datasource_models.DatasourceStageRecord.tenant_id == tenant_id,
|
datasource_models.DatasourceStageRecord.tenant_id == tenant_id,
|
||||||
datasource_models.DatasourceStageRecord.state
|
datasource_models.DatasourceStageRecord.state == "awaiting_approval",
|
||||||
== "awaiting_approval",
|
|
||||||
)
|
)
|
||||||
.count()
|
.count()
|
||||||
),
|
),
|
||||||
@@ -485,6 +487,21 @@ manifest = ModuleManifest(
|
|||||||
),
|
),
|
||||||
architecture=ARCHITECTURE,
|
architecture=ARCHITECTURE,
|
||||||
documentation=(
|
documentation=(
|
||||||
|
DocumentationTopic(
|
||||||
|
id="datasources.workspace-layout",
|
||||||
|
title="Datasources workspace actions",
|
||||||
|
summary="Find collection-wide commands in their consistent workspace position.",
|
||||||
|
body="Reload and Add datasource or stage use the persistent full-width workspace header at the upper right; Reload sits immediately before creation. Selecting a record, changing filters, or opening an editor does not move these collection-wide commands into the left pane. Catalogue, staging, and origin filters remain in the collection pane. Snapshot and freeze actions remain with their selected resource. Existing permissions, disabled-state rules, and unsaved-change guards still apply. Administrators configure authority through the existing permission system; no new permission or automatic operation is introduced.",
|
||||||
|
layer="static",
|
||||||
|
documentation_types=("user", "admin"),
|
||||||
|
audience=("user", "module_admin", "operator"),
|
||||||
|
order=5,
|
||||||
|
translations={"de": {
|
||||||
|
"title": "Datenquellen: Aktionen im Arbeitsbereich",
|
||||||
|
"summary": "Sammlungsweite Aktionen an ihrer einheitlichen Position im Arbeitsbereich finden.",
|
||||||
|
"body": "Neu laden und Datenquelle oder Staging hinzufügen stehen oben rechts in der dauerhaft sichtbaren, arbeitsbereichsweiten Leiste; Neu laden steht unmittelbar vor dem Anlegen. Auswahl, Filterwechsel und Bearbeitung verschieben diese sammlungsweiten Aktionen nicht in den linken Bereich. Katalog-, Staging- und Herkunftsfilter bleiben im Sammlungsbereich. Snapshot- und Einfrieraktionen bleiben bei der ausgewählten Ressource. Bestehende Berechtigungen, Deaktivierungsregeln und der Schutz ungespeicherter Änderungen gelten weiterhin. Administratoren konfigurieren Rechte im bestehenden Berechtigungssystem; es entstehen weder neue Rechte noch automatische Vorgänge.",
|
||||||
|
}},
|
||||||
|
),
|
||||||
DocumentationTopic(
|
DocumentationTopic(
|
||||||
id="datasources.data-subject-requests",
|
id="datasources.data-subject-requests",
|
||||||
title="Datasources data-subject requests",
|
title="Datasources data-subject requests",
|
||||||
@@ -498,6 +515,27 @@ manifest = ModuleManifest(
|
|||||||
audience=("user", "operator", "module_admin", "data_steward", "auditor"),
|
audience=("user", "operator", "module_admin", "data_steward", "auditor"),
|
||||||
related_modules=("core", "connectors", "dataflow", "reporting"),
|
related_modules=("core", "connectors", "dataflow", "reporting"),
|
||||||
order=69,
|
order=69,
|
||||||
|
translations={
|
||||||
|
"de": {
|
||||||
|
"title": "Betroffenenanfragen für Datenquellen",
|
||||||
|
"summary": (
|
||||||
|
"Gesteuerte Datenquellenkopien identifizieren und dabei Grenzen für Zugangsdaten, Nutzdaten und unveränderliche "
|
||||||
|
"Nachweise wahren."
|
||||||
|
),
|
||||||
|
"body": (
|
||||||
|
"Datasources gleicht exakte mandantenbezogene Kennungen für Katalog, Governance-Verweis, Materialisierung, Nutzdaten, "
|
||||||
|
"Stufe, Veröffentlichung und Lebenszyklusnachweis sowie minimierte Betriebszuordnungen zu Konto, Identität oder "
|
||||||
|
"Mitgliedschaft ab. DSAR-Ergebnisse kopieren niemals Connector-/Providerverweise, Speicherorte, Zugangsdaten, beliebige "
|
||||||
|
"Zeilen, Schemata, Validierungsstichproben, Metadaten, Herkunftstexte, Checkpoints, Idempotenzmaterial oder Hashes. "
|
||||||
|
"Beliebige tabellarische Nutzdaten werden nicht nach Kennungen durchsucht, weil dies unvollständig und schemaabhängig wäre "
|
||||||
|
"und Daten unbeteiligter Personen offenlegen könnte; das maßgebliche Quellmodul muss Betroffenenmerkmale finden und "
|
||||||
|
"korrigieren. Eine nicht hochgestufte Stufe oder nicht referenzierte Nutzdaten können idempotent gelöscht werden. "
|
||||||
|
"Veröffentlichter Katalogzustand, hochgestufte Stufen, referenzierte Nutzdaten, unveränderliche Materialisierungen, "
|
||||||
|
"Governance-Verweise, Veröffentlichungen, Sperren und Betriebszuordnungen erfordern die Prüfung durch Data Stewards und "
|
||||||
|
"eine Korrektur an der Quelle. Nach der Korrektur müssen nachgelagerte Dataflow- und Reporting-Ausgaben aktualisiert werden."
|
||||||
|
),
|
||||||
|
}
|
||||||
|
},
|
||||||
metadata={
|
metadata={
|
||||||
"seed": True,
|
"seed": True,
|
||||||
"help_contexts": [
|
"help_contexts": [
|
||||||
@@ -543,6 +581,28 @@ manifest = ModuleManifest(
|
|||||||
"search",
|
"search",
|
||||||
),
|
),
|
||||||
order=70,
|
order=70,
|
||||||
|
translations={
|
||||||
|
"de": {
|
||||||
|
"title": "Lebenszyklus einer Datenquelle",
|
||||||
|
"summary": (
|
||||||
|
"Gesteuerte Live-, Cache- und statische Daten-/Registereinträge mit Staging, eingefrorenen Zuständen, Herkunft und "
|
||||||
|
"institutionellem Eigentumskontext."
|
||||||
|
),
|
||||||
|
"body": (
|
||||||
|
"Datasources ist der providerneutrale Katalog für Dataflow, Workflow, Reporting und richtlinienbewusste Module. Statische "
|
||||||
|
"Daten werden vor der Hochstufung bereitgestellt. Cache-Daten aktualisieren Connector-Ursprünge in unveränderliche "
|
||||||
|
"Materialisierungen. Live-Daten werden über einen Connector gelesen und können für reproduzierbare Nachweise eingefroren "
|
||||||
|
"werden. Connectors besitzt Protokolle und Zugangsdaten; Datasources besitzt Datenidentität, Herkunft, Lebenszyklus, "
|
||||||
|
"Lesesemantik und den typisierten Governance-Katalog für Hoheit, Zweck, Qualität, Aktualität, Klassifikation, Korrektur "
|
||||||
|
"sowie abhängige Services, Flows, Berichte, Kontrollen und Entscheidungen. Für Live-Vorschauen bewahrt es Quellmodus, "
|
||||||
|
"strukturierten Gesundheitszustand, deklarierte Pushdown-Unterstützung und wirksame Zeilen-, Byte- und Zeitgrenzen. "
|
||||||
|
"Sichtbarkeit von Governance-Metadaten gewährt keinen Zugriff auf geschützte Zeilen. Ist Search aktiviert, indiziert das "
|
||||||
|
"Modul nur begrenzte Katalogbezeichnungen und governance-sichere Facetten und prüft vor einem Treffer die aktuelle "
|
||||||
|
"Katalogberechtigung erneut. Zeilen, Schemata, Connector-Verweise, Zugangsdaten, beliebige Metadaten und Herkunft werden "
|
||||||
|
"niemals in den Suchindex kopiert."
|
||||||
|
),
|
||||||
|
}
|
||||||
|
},
|
||||||
metadata={
|
metadata={
|
||||||
"seed": True,
|
"seed": True,
|
||||||
"help_contexts": [
|
"help_contexts": [
|
||||||
@@ -582,6 +642,30 @@ manifest = ModuleManifest(
|
|||||||
"risk_compliance",
|
"risk_compliance",
|
||||||
),
|
),
|
||||||
order=71,
|
order=71,
|
||||||
|
translations={
|
||||||
|
"de": {
|
||||||
|
"title": "Datenhoheit und Governance einer Datenquelle",
|
||||||
|
"summary": (
|
||||||
|
"Erläutern, wer Datenbedeutung, Hoheit, Korrektur, Datenschutz, Qualität, Aktualität, Aufbewahrung und abhängige "
|
||||||
|
"Verwendungen verantwortet."
|
||||||
|
),
|
||||||
|
"body": (
|
||||||
|
"Der Hoheitsmodus gibt an, ob GovOPlaN, ein externes System, eine synchronisierte Projektion, ein Overlay oder ein "
|
||||||
|
"verknüpfter Verweis die Daten steuert. Maßgebliche Quelle, Eigentum, Data Steward, verantwortliche Organisation/Funktion, "
|
||||||
|
"Schemaeigentum, Datenschutzprofil, Aufbewahrungsrichtlinie, Übermittlungsvereinbarung, Rechtsgrundlage, Sperren, "
|
||||||
|
"Korrekturverfahren, Zwecke, amtliche Schlüssel und bekannte Grenzen bilden den auffindbaren institutionellen Kontext. "
|
||||||
|
"Ein Aufbewahrungsrichtlinienverweis bezeichnet eine externe Regel im Eigentum von Policy; der lokale versionierte "
|
||||||
|
"Aufbewahrungsvertrag steuert die vorschaufähige Behandlung von Stufen und Nutzdaten. Aufbewahrung überstimmt niemals "
|
||||||
|
"gesetzliche Sperren, die aktuelle Materialisierung oder Veröffentlichungsnachweise. Ein Verweis auf eine "
|
||||||
|
"Übermittlungsvereinbarung dokumentiert die gesteuerte Vereinbarung für externen Austausch; er gewährt weder "
|
||||||
|
"Connector-Zugangsdaten noch Empfängerzugriff oder Befugnis zum Export klassifizierter Zeilen. Aktualitäts- und "
|
||||||
|
"Qualitätsrichtlinien sind typisierte JSON-Verträge, die mit Materialisierungsnachweisen aufbewahrt werden. Datasources "
|
||||||
|
"setzt die deklarierten begrenzten Regeln für tabellarische Stufen und die Schemarichtlinie durch; ursprungs- oder "
|
||||||
|
"verbraucherspezifische Kontrollen verbleiben beim Provider oder der nutzenden Kontrolle, die Unterstützung erklärt. "
|
||||||
|
"Metadatensichtbarkeit gewährt niemals Zeilenzugriff."
|
||||||
|
),
|
||||||
|
}
|
||||||
|
},
|
||||||
metadata={
|
metadata={
|
||||||
"seed": True,
|
"seed": True,
|
||||||
"help_contexts": [
|
"help_contexts": [
|
||||||
@@ -614,6 +698,30 @@ manifest = ModuleManifest(
|
|||||||
audience=("operator", "module_admin", "data_steward", "auditor"),
|
audience=("operator", "module_admin", "data_steward", "auditor"),
|
||||||
related_modules=("policy", "access", "audit", "connectors"),
|
related_modules=("policy", "access", "audit", "connectors"),
|
||||||
order=72,
|
order=72,
|
||||||
|
translations={
|
||||||
|
"de": {
|
||||||
|
"title": "Sichtbarkeit von Datenquellen und Feldern",
|
||||||
|
"summary": (
|
||||||
|
"Kontrollen für Quelle, Materialisierung, Feld und Zeile anwenden, bevor geschützte Zeilen Datasources verlassen."
|
||||||
|
),
|
||||||
|
"body": (
|
||||||
|
"Eine lokale Sichtbarkeitsrichtlinie kann Auffinden und Lesen nach Konto, Mitgliedschaft, Identität, Gruppe, Rolle, "
|
||||||
|
"Dienstkonto oder Authentifizierungsmethode einschränken. Materialisierungs-ACLs schützen zusätzlich aktuelle und "
|
||||||
|
"eingefrorene Revisionen. Feldregeln klassifizieren ein Feld und ersetzen seinen Wert durch null oder lassen es weg, "
|
||||||
|
"sofern keine passende Erlaubnis-ACL vorliegt. Zeilenfilter vergleichen ein konfiguriertes Feld mit Konto-, "
|
||||||
|
"Mitgliedschafts-, Identitäts-, Dienstkonto-, Gruppen-, Rollen- oder Funktionszuweisungsmerkmalen der Hauptperson; alle "
|
||||||
|
"konfigurierten Filter und Richtlinienebenen müssen eine Zeile erlauben. Datasources wendet diese Kontrollen an, bevor "
|
||||||
|
"Zeilen die Providergrenze verlassen, und liefert einen undurchsichtigen Fingerabdruck der erlaubten Ansicht, gebunden an "
|
||||||
|
"Basisrevision, wirksame Richtlinien und relevante Hauptpersonenmerkmale. Verweigerte und gefilterte Lesevorgänge erzeugen "
|
||||||
|
"Auditnachweise mit Ergebnissen und Richtliniendiagnosen, niemals geschützten Werten, Provider-Speicherorten, beliebigen "
|
||||||
|
"Metadaten oder Herkunftstexten. Ein optionaler Zugriffsrichtlinienverweis delegiert hierarchische Ebenen an Policy, das "
|
||||||
|
"lokales Verhalten nur verschärfen kann. Eine nicht auflösbare Referenz, ein nicht verfügbarer konfigurierter Provider oder "
|
||||||
|
"eine fehlerhafte Richtlinie schließt sicher. Ohne Policy und ohne Referenz bleibt die lokale Richtlinie vollständig "
|
||||||
|
"nutzbar. Eingefrorene Lesevorgänge setzen die aktuelle lokale Richtlinie gemeinsam mit einer getrennten einschränkenden "
|
||||||
|
"Richtlinie aus dem eingefrorenen Governance-Snapshot durch."
|
||||||
|
),
|
||||||
|
}
|
||||||
|
},
|
||||||
metadata={
|
metadata={
|
||||||
"seed": True,
|
"seed": True,
|
||||||
"help_contexts": [
|
"help_contexts": [
|
||||||
@@ -661,6 +769,31 @@ manifest = ModuleManifest(
|
|||||||
"workflow_engine",
|
"workflow_engine",
|
||||||
),
|
),
|
||||||
order=73,
|
order=73,
|
||||||
|
translations={
|
||||||
|
"de": {
|
||||||
|
"title": "Bereitgestellte und erzeugte Datenquellenrevisionen validieren",
|
||||||
|
"summary": (
|
||||||
|
"Deterministische Qualitätsregeln und Schemerichtlinien anwenden, bevor bereitgestellte oder erzeugte Daten nutzbar werden."
|
||||||
|
),
|
||||||
|
"body": (
|
||||||
|
"Tabellarische Stufen prüfen konfigurierte Zeilenanzahl, Pflichtfelder, Feldform, Nullbarkeit, Eindeutigkeit, Zahlenbereiche "
|
||||||
|
"und begrenzte Referenzmengen. Fehler halten die Stufe prüfbar, blockieren aber die Hochstufung; Warnungen bleiben sichtbar "
|
||||||
|
"und erlauben eine ausdrückliche Hochstufung. Aktualisierungen vergleichen das erkannte Schema mit dem aktuellen Ziel und "
|
||||||
|
"klassifizieren jede Änderung als kompatibel, Warnung oder brechend. Diagnosen zeigen Anzahlen und begrenzte Zeilennummern, "
|
||||||
|
"niemals Feldwerte. Richtlinienversion und -hash, Diagnosen und Schemadifferenz werden bei erfolgreicher Hochstufung in die "
|
||||||
|
"unveränderliche Materialisierungsherkunft kopiert. Eine Provider-Veröffentlichung wendet dasselbe Gate vor jeder "
|
||||||
|
"Katalogwirkung an, bewahrt Validierungsnachweise an der unveränderlichen Ausgaberevision, serialisiert die "
|
||||||
|
"Veröffentlichungsidentität über PostgreSQL-Worker und sendet ein transaktionales Abschlussereignis. Große Ausgaben können "
|
||||||
|
"stattdessen einen dauerhaften providerneutralen Artefaktverweis mit festgelegtem Speicherort, SHA-256-Prüfsumme, Schema, "
|
||||||
|
"Fingerabdruck und Größe liefern. Das konfigurierte Nutzdaten-Backend prüft das Artefakt und stellt begrenzte Lesevorgänge "
|
||||||
|
"bereit. Inhaltsregeln verlangen prüfsummen- und richtliniengebundene Provider-Nachweise; fehlen sie, entsteht eine "
|
||||||
|
"unveränderliche prüfpflichtige Materialisierung, ohne den aktuellen Zustand der Datenquelle zu verändern. Warnungen und "
|
||||||
|
"Prüfpflicht bleiben für Workflow-Übergaben erhalten. Eine versionierte Freigaberichtlinie kann ein zurechenbares, "
|
||||||
|
"getrenntes Quorum verlangen, bevor eine Stufe oder Aktualisierung aktuell wird; Aufbewahrung verwendet vor jeder "
|
||||||
|
"ausdrücklichen administrativen Anwendung eine frische gehashte Vorschau."
|
||||||
|
),
|
||||||
|
}
|
||||||
|
},
|
||||||
metadata={
|
metadata={
|
||||||
"seed": True,
|
"seed": True,
|
||||||
"help_contexts": [
|
"help_contexts": [
|
||||||
@@ -701,7 +834,24 @@ manifest = ModuleManifest(
|
|||||||
"audit",
|
"audit",
|
||||||
),
|
),
|
||||||
order=74,
|
order=74,
|
||||||
|
translations={
|
||||||
|
"de": {
|
||||||
|
"title": "Datenquellenfelder und Folgen des Lebenszyklus",
|
||||||
|
"summary": "Semantik von Live-, Cache- und statischem Modus, Staging, Hochstufung, Aktualisierung, Einfrieren und Stilllegung.",
|
||||||
|
"body": (
|
||||||
|
"Der Schlüssel einer Datenquelle ist ihre stabile Katalogidentität für Verbraucher. Live-Modus liest über einen "
|
||||||
|
"verfügbaren Ursprung, Cache-Modus aktualisiert einen Ursprung in unveränderliche Revisionen und statischer Modus stuft "
|
||||||
|
"hochgeladene Inhalte aus dem Staging hoch. Stufen sind begrenzt, prüfbar und vor der Hochstufung nicht nutzbar. Die "
|
||||||
|
"Hochstufung legt eine gesteuerte Datenquelle an oder aktualisiert sie und ergänzt eine unveränderliche Materialisierung. "
|
||||||
|
"Ist eine Freigabe konfiguriert, erzeugt eine Aktualisierung zunächst eine nicht nutzbare Stufe; nur ein bestätigtes Quorum "
|
||||||
|
"erlaubt die Hochstufung. Einfrieren kennzeichnet einen unveränderlichen adressierbaren Zustand für reproduzierbare "
|
||||||
|
"Ausführung. Eine Stilllegung entfernt die Datenquelle aus neuen Definitionen, während erhaltene Materialisierungsverweise "
|
||||||
|
"gesteuert bleiben. Fehlt Connectors, ist die Ursprungsregistrierung deaktiviert; lokaler Katalog und Staging bleiben nutzbar."
|
||||||
|
),
|
||||||
|
}
|
||||||
|
},
|
||||||
metadata={
|
metadata={
|
||||||
|
"kind": "reference",
|
||||||
"seed": True,
|
"seed": True,
|
||||||
"help_contexts": [
|
"help_contexts": [
|
||||||
"datasources.field.origin",
|
"datasources.field.origin",
|
||||||
@@ -774,6 +924,11 @@ 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
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,14 @@ from govoplan_datasources.backend.manifest import manifest
|
|||||||
|
|
||||||
|
|
||||||
class DatasourcesInterfaceDocumentationContractTests(unittest.TestCase):
|
class DatasourcesInterfaceDocumentationContractTests(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)
|
||||||
@@ -34,8 +42,12 @@ class DatasourcesInterfaceDocumentationContractTests(unittest.TestCase):
|
|||||||
lifecycle_controls = topics["datasources.approval-and-retention"]
|
lifecycle_controls = topics["datasources.approval-and-retention"]
|
||||||
|
|
||||||
self.assertIn("datasources.staging", lifecycle.metadata["help_contexts"])
|
self.assertIn("datasources.staging", lifecycle.metadata["help_contexts"])
|
||||||
self.assertIn("datasources.field.authority-mode", governance.metadata["help_contexts"])
|
self.assertIn(
|
||||||
self.assertIn("datasources.staging.validation", quality.metadata["help_contexts"])
|
"datasources.field.authority-mode", governance.metadata["help_contexts"]
|
||||||
|
)
|
||||||
|
self.assertIn(
|
||||||
|
"datasources.staging.validation", quality.metadata["help_contexts"]
|
||||||
|
)
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
"datasources.field.visibility-policy",
|
"datasources.field.visibility-policy",
|
||||||
visibility.metadata["help_contexts"],
|
visibility.metadata["help_contexts"],
|
||||||
@@ -46,7 +58,10 @@ class DatasourcesInterfaceDocumentationContractTests(unittest.TestCase):
|
|||||||
self.assertIn("datasources.action.promote", reference.metadata["help_contexts"])
|
self.assertIn("datasources.action.promote", reference.metadata["help_contexts"])
|
||||||
self.assertIn("freeze", reference.metadata["consequence_classes"])
|
self.assertIn("freeze", reference.metadata["consequence_classes"])
|
||||||
self.assertIn("retire", reference.metadata["consequence_classes"])
|
self.assertIn("retire", reference.metadata["consequence_classes"])
|
||||||
self.assertIn("datasources.action.approve", lifecycle_controls.metadata["help_contexts"])
|
self.assertEqual("reference", reference.metadata["kind"])
|
||||||
|
self.assertIn(
|
||||||
|
"datasources.action.approve", lifecycle_controls.metadata["help_contexts"]
|
||||||
|
)
|
||||||
self.assertIn("hash-chained lifecycle evidence", lifecycle_controls.body)
|
self.assertIn("hash-chained lifecycle evidence", lifecycle_controls.body)
|
||||||
self.assertTrue(lifecycle_controls.translations["de"]["body"])
|
self.assertTrue(lifecycle_controls.translations["de"]["body"])
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@govoplan/datasources-webui",
|
"name": "@govoplan/datasources-webui",
|
||||||
"version": "0.1.21",
|
"version": "0.1.25",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
"typecheck": "tsc --noEmit"
|
"typecheck": "tsc --noEmit"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@govoplan/core-webui": "^0.1.18",
|
"@govoplan/core-webui": "^0.1.45",
|
||||||
"lucide-react": "^1.23.0",
|
"lucide-react": "^1.23.0",
|
||||||
"react": ">=19.2.7 <20",
|
"react": ">=19.2.7 <20",
|
||||||
"react-dom": ">=19.2.7 <20",
|
"react-dom": ">=19.2.7 <20",
|
||||||
|
|||||||
@@ -315,6 +315,21 @@ export default function DatasourcesPage({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<WorkspaceFrame as="main" height="viewport" surface="plain" className="datasources-page" label="Datasource workspace">
|
<WorkspaceFrame as="main" height="viewport" surface="plain" className="datasources-page" label="Datasource workspace">
|
||||||
|
<WorkspaceActionBar
|
||||||
|
scope="workspace"
|
||||||
|
variant="collection"
|
||||||
|
refreshable
|
||||||
|
reloadAction={{ onReload: () => void reload(selectedDatasourceRef), loading: loading || working }}
|
||||||
|
contextActions={<strong>Data</strong>}
|
||||||
|
createAction={<IconButton
|
||||||
|
label="Add datasource or stage"
|
||||||
|
icon={<Plus size={17} />}
|
||||||
|
variant="primary"
|
||||||
|
onClick={() => setAddOpen(true)}
|
||||||
|
disabled={!canStage && !canManage}
|
||||||
|
disabledReason={!canStage && !canManage ? DATASOURCES_I18N.manageReason : undefined}
|
||||||
|
/>}
|
||||||
|
/>
|
||||||
<WorkspaceLayout
|
<WorkspaceLayout
|
||||||
variant="split"
|
variant="split"
|
||||||
primarySize="compact"
|
primarySize="compact"
|
||||||
@@ -325,21 +340,6 @@ export default function DatasourcesPage({
|
|||||||
contentLabel="Datasource workspace"
|
contentLabel="Datasource workspace"
|
||||||
contentClassName="datasources-workspace"
|
contentClassName="datasources-workspace"
|
||||||
primary={<>
|
primary={<>
|
||||||
<WorkspaceActionBar
|
|
||||||
scope="collection-pane"
|
|
||||||
variant="collection"
|
|
||||||
refreshable
|
|
||||||
reloadAction={{ onReload: () => void reload(selectedDatasourceRef), loading: loading || working }}
|
|
||||||
contextActions={<strong>Data</strong>}
|
|
||||||
createAction={<IconButton
|
|
||||||
label="Add datasource or stage"
|
|
||||||
icon={<Plus size={17} />}
|
|
||||||
variant="primary"
|
|
||||||
onClick={() => setAddOpen(true)}
|
|
||||||
disabled={!canStage && !canManage}
|
|
||||||
disabledReason={!canStage && !canManage ? DATASOURCES_I18N.manageReason : undefined}
|
|
||||||
/>}
|
|
||||||
/>
|
|
||||||
<div className="datasources-view-switch">
|
<div className="datasources-view-switch">
|
||||||
<SegmentedControl<CatalogueView>
|
<SegmentedControl<CatalogueView>
|
||||||
ariaLabel="Datasource view"
|
ariaLabel="Datasource view"
|
||||||
@@ -448,7 +448,7 @@ export default function DatasourcesPage({
|
|||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
{view === "catalogue" && canAdmin ? (
|
{view === "catalogue" && canAdmin ? (
|
||||||
<Button onClick={() => setRetentionOpen(true)} disabled={working}>
|
<Button helpContextId="datasources.retention" helpModuleId="datasources" onClick={() => setRetentionOpen(true)} disabled={working}>
|
||||||
<Archive size={16} /> Retention
|
<Archive size={16} /> Retention
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
@@ -1337,7 +1337,7 @@ function GovernanceDialog({
|
|||||||
<GovernanceListField label="Purposes" values={draft.purposes} onChange={(values) => setValue("purposes", values)} />
|
<GovernanceListField label="Purposes" values={draft.purposes} onChange={(values) => setValue("purposes", values)} />
|
||||||
<GovernanceListField label="Legal basis references" values={draft.legal_basis_refs} onChange={(values) => setValue("legal_basis_refs", values)} />
|
<GovernanceListField label="Legal basis references" values={draft.legal_basis_refs} onChange={(values) => setValue("legal_basis_refs", values)} />
|
||||||
<GovernanceListField label="Official keys" values={draft.official_keys} onChange={(values) => setValue("official_keys", values)} />
|
<GovernanceListField label="Official keys" values={draft.official_keys} onChange={(values) => setValue("official_keys", values)} />
|
||||||
<GovernanceListField label="Legal hold references" values={draft.hold_refs} onChange={(values) => setValue("hold_refs", values)} />
|
<GovernanceListField label="Legal hold references" helpContextId="datasources.field.retention-policy-contract" values={draft.hold_refs} onChange={(values) => setValue("hold_refs", values)} />
|
||||||
<GovernanceListField label="Affected services and processes" values={draft.affected_refs} onChange={(values) => setValue("affected_refs", values)} />
|
<GovernanceListField label="Affected services and processes" values={draft.affected_refs} onChange={(values) => setValue("affected_refs", values)} />
|
||||||
<GovernanceListField label="Dependent flows, reports, controls and decisions" values={draft.dependency_refs} onChange={(values) => setValue("dependency_refs", values)} />
|
<GovernanceListField label="Dependent flows, reports, controls and decisions" values={draft.dependency_refs} onChange={(values) => setValue("dependency_refs", values)} />
|
||||||
<GovernanceListField label="Known limits" values={draft.known_limits} onChange={(values) => setValue("known_limits", values)} />
|
<GovernanceListField label="Known limits" values={draft.known_limits} onChange={(values) => setValue("known_limits", values)} />
|
||||||
@@ -1370,15 +1370,17 @@ function GovernanceDialog({
|
|||||||
|
|
||||||
function GovernanceListField({
|
function GovernanceListField({
|
||||||
label,
|
label,
|
||||||
|
helpContextId,
|
||||||
values,
|
values,
|
||||||
onChange
|
onChange
|
||||||
}: {
|
}: {
|
||||||
label: string;
|
label: string;
|
||||||
|
helpContextId?: string;
|
||||||
values: string[];
|
values: string[];
|
||||||
onChange: (values: string[]) => void;
|
onChange: (values: string[]) => void;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<FormField label={label}>
|
<FormField label={label} helpContextId={helpContextId} helpModuleId="datasources">
|
||||||
<textarea
|
<textarea
|
||||||
value={values.join("\n")}
|
value={values.join("\n")}
|
||||||
onChange={(event) => onChange(splitLines(event.target.value))}
|
onChange={(event) => onChange(splitLines(event.target.value))}
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ const readScopes = ["datasources:catalogue:read", "datasources:source:admin"];
|
|||||||
export const datasourcesModule: PlatformWebModule = {
|
export const datasourcesModule: PlatformWebModule = {
|
||||||
id: "datasources",
|
id: "datasources",
|
||||||
label: "i18n:govoplan-datasources.datasources",
|
label: "i18n:govoplan-datasources.datasources",
|
||||||
version: "0.1.18",
|
version: "0.1.22",
|
||||||
optionalDependencies: [
|
optionalDependencies: [
|
||||||
"access",
|
"access",
|
||||||
"audit",
|
"audit",
|
||||||
|
|||||||
Reference in New Issue
Block a user