diff --git a/pyproject.toml b/pyproject.toml index 458c3ec..9531bc2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "govoplan-core" -version = "0.1.35" +version = "0.1.36" description = "Reusable GovOPlaN platform core, access, tenancy, and RBAC components." readme = "README.md" requires-python = ">=3.12" diff --git a/src/govoplan_core/core/datasources.py b/src/govoplan_core/core/datasources.py index 2b65b1f..3a60be0 100644 --- a/src/govoplan_core/core/datasources.py +++ b/src/govoplan_core/core/datasources.py @@ -101,6 +101,8 @@ class DatasourceGovernance: transfer_agreement_ref: str | None = None freshness_policy: Mapping[str, object] = field(default_factory=dict) quality_policy: Mapping[str, object] = field(default_factory=dict) + approval_policy: Mapping[str, object] = field(default_factory=dict) + retention_policy: Mapping[str, object] = field(default_factory=dict) known_limits: tuple[str, ...] = () correction_procedure_ref: str | None = None affected_refs: tuple[str, ...] = () @@ -179,6 +181,8 @@ class DatasourceGovernance: ), freshness_policy=_governance_mapping(source.get("freshness_policy")), quality_policy=_governance_mapping(source.get("quality_policy")), + approval_policy=_governance_mapping(source.get("approval_policy")), + retention_policy=_governance_mapping(source.get("retention_policy")), known_limits=_governance_texts(source.get("known_limits")), correction_procedure_ref=_optional_governance_text( source.get("correction_procedure_ref") @@ -210,6 +214,8 @@ class DatasourceGovernance: "transfer_agreement_ref": self.transfer_agreement_ref, "freshness_policy": dict(self.freshness_policy), "quality_policy": dict(self.quality_policy), + "approval_policy": dict(self.approval_policy), + "retention_policy": dict(self.retention_policy), "known_limits": list(self.known_limits), "correction_procedure_ref": self.correction_procedure_ref, "affected_refs": list(self.affected_refs), @@ -289,6 +295,8 @@ class DatasourceMaterialization: frozen_label: str | None = None source_timestamp: datetime | None = None created_at: datetime | None = None + disposed_at: datetime | None = None + disposition: Mapping[str, object] = field(default_factory=dict) provenance: Mapping[str, object] = field(default_factory=dict) metadata: Mapping[str, object] = field(default_factory=dict) governance: DatasourceGovernance = field(default_factory=DatasourceGovernance) @@ -309,6 +317,7 @@ class DatasourceStage: row_count: int | None = None byte_count: int | None = None validation: Mapping[str, object] = field(default_factory=dict) + approval: Mapping[str, object] = field(default_factory=dict) created_at: datetime | None = None promoted_at: datetime | None = None promoted_materialization_ref: str | None = None diff --git a/tests/test_datasource_contract.py b/tests/test_datasource_contract.py index 8013328..0ad89ea 100644 --- a/tests/test_datasource_contract.py +++ b/tests/test_datasource_contract.py @@ -13,6 +13,7 @@ from govoplan_core.core.datasources import ( DatasourceArtifactBackendProvider, DatasourceDescriptor, DatasourceField, + DatasourceGovernance, DatasourceLifecycleProvider, DatasourceMaterialization, DatasourceOrigin, @@ -212,6 +213,55 @@ class DatasourceContractTests(unittest.TestCase): self.assertEqual("upload", descriptor.kind) self.assertEqual("tabular", descriptor.shape) + def test_lifecycle_governance_round_trips_without_provider_specific_types(self) -> None: + governance = DatasourceGovernance.from_mapping( + { + "approval_policy": { + "version": "approval-v2", + "required": True, + "required_approvals": 2, + }, + "retention_policy": { + "version": "retention-v3", + "enabled": True, + "stage_days": 30, + }, + } + ) + + self.assertEqual("approval-v2", governance.approval_policy["version"]) + self.assertEqual(30, governance.retention_policy["stage_days"]) + self.assertEqual( + governance.approval_policy, + governance.to_dict()["approval_policy"], + ) + self.assertEqual( + governance.retention_policy, + governance.to_dict()["retention_policy"], + ) + + stage = DatasourceStage( + ref="stage:governed", + name="Governed stage", + source_name="governed", + kind="upload", + mode="static", + shape="tabular", + state="awaiting_approval", + approval={"status": "pending", "policy_version": "approval-v2"}, + ) + materialization = DatasourceMaterialization( + ref="materialization:disposed", + datasource_ref="datasource:governed", + revision=1, + state="disposed", + fingerprint="abc123", + disposition={"reason": "retention_policy", "policy_version": "retention-v3"}, + ) + + self.assertEqual("pending", stage.approval["status"]) + self.assertEqual("retention_policy", materialization.disposition["reason"]) + if __name__ == "__main__": unittest.main() diff --git a/webui/package-lock.json b/webui/package-lock.json index a0f848d..1c305f7 100644 --- a/webui/package-lock.json +++ b/webui/package-lock.json @@ -1,12 +1,12 @@ { "name": "@govoplan/core-webui", - "version": "0.1.35", + "version": "0.1.36", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@govoplan/core-webui", - "version": "0.1.35", + "version": "0.1.36", "dependencies": { "@govoplan/access-webui": "file:../../govoplan-access/webui", "@govoplan/addresses-webui": "file:../../govoplan-addresses/webui", diff --git a/webui/package-lock.release.json b/webui/package-lock.release.json index daffdfb..eb066e1 100644 --- a/webui/package-lock.release.json +++ b/webui/package-lock.release.json @@ -1,12 +1,12 @@ { "name": "@govoplan/core-webui", - "version": "0.1.35", + "version": "0.1.36", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@govoplan/core-webui", - "version": "0.1.35", + "version": "0.1.36", "dependencies": { "@govoplan/access-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-access.git#v0.1.20", "@govoplan/admin-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-admin.git#v0.1.19", diff --git a/webui/package.json b/webui/package.json index 126ca97..61da970 100644 --- a/webui/package.json +++ b/webui/package.json @@ -1,6 +1,6 @@ { "name": "@govoplan/core-webui", - "version": "0.1.35", + "version": "0.1.36", "private": true, "type": "module", "main": "src/index.ts", diff --git a/webui/package.release.json b/webui/package.release.json index 36b6e4a..26fc809 100644 --- a/webui/package.release.json +++ b/webui/package.release.json @@ -1,6 +1,6 @@ { "name": "@govoplan/core-webui", - "version": "0.1.35", + "version": "0.1.36", "private": true, "type": "module", "main": "src/index.ts",