feat: acquire immutable sanctions snapshots

This commit is contained in:
2026-07-29 18:46:53 +02:00
parent 27302f0c39
commit c5a43b3dae
10 changed files with 2093 additions and 9 deletions
+93 -5
View File
@@ -23,8 +23,20 @@ from govoplan_core.core.tabular_sources import (
CAPABILITY_CONNECTORS_TABULAR_SNAPSHOT_WRITER,
CAPABILITY_CONNECTORS_TABULAR_SOURCES,
)
from govoplan_core.core.sanctions import (
CAPABILITY_CONNECTORS_SANCTIONS_SNAPSHOTS,
)
from govoplan_core.db.base import Base
from govoplan_connectors.backend.db.models import ConnectorTabularSource
from govoplan_connectors.backend.db.models import (
ConnectorSanctionsAcquisitionRun,
ConnectorSanctionsSnapshot,
ConnectorTabularSource,
)
from govoplan_connectors.backend.sanctions_sources import (
SANCTIONS_READ_SCOPE,
SANCTIONS_REFRESH_SCOPE,
SqlSanctionsSnapshotProvider,
)
from govoplan_connectors.backend.tabular_sources import (
ADMIN_SCOPE,
READ_SCOPE,
@@ -40,6 +52,7 @@ MODULE_ID = "connectors"
MODULE_VERSION = "0.1.14"
TABULAR_SOURCE_INTERFACE_VERSION = "0.1.0"
DATASOURCE_ORIGIN_INTERFACE_VERSION = "0.1.0"
SANCTIONS_SNAPSHOT_INTERFACE_VERSION = "1.0.0"
def _permission(scope: str, label: str, description: str) -> PermissionDefinition:
@@ -72,6 +85,16 @@ PERMISSIONS = (
"Administer connector sources",
"Manage every tenant connector source and future source policies.",
),
_permission(
SANCTIONS_READ_SCOPE,
"View sanctions source evidence",
"Inspect immutable sanctions snapshots and acquisition health.",
),
_permission(
SANCTIONS_REFRESH_SCOPE,
"Refresh sanctions sources",
"Acquire a new immutable sanctions source snapshot.",
),
)
ROLE_TEMPLATES = (
@@ -79,13 +102,18 @@ ROLE_TEMPLATES = (
slug="connector_source_manager",
name="Connector source manager",
description="Discover, import, preview, and retire tabular sources.",
permissions=(READ_SCOPE, WRITE_SCOPE),
permissions=(
READ_SCOPE,
WRITE_SCOPE,
SANCTIONS_READ_SCOPE,
SANCTIONS_REFRESH_SCOPE,
),
),
RoleTemplate(
slug="connector_source_reader",
name="Connector source reader",
description="Discover and preview tabular connector sources.",
permissions=(READ_SCOPE,),
permissions=(READ_SCOPE, SANCTIONS_READ_SCOPE),
),
)
@@ -104,6 +132,12 @@ def _datasource_origin_provider(_context) -> ConnectorDatasourceOriginProvider:
return ConnectorDatasourceOriginProvider()
def _sanctions_snapshot_provider(
_context,
) -> SqlSanctionsSnapshotProvider:
return SqlSanctionsSnapshotProvider()
def _tenant_summary(session, tenant_id: str) -> dict[str, int]:
return {
"connector_tabular_sources": (
@@ -113,7 +147,22 @@ def _tenant_summary(session, tenant_id: str) -> dict[str, int]:
ConnectorTabularSource.deleted_at.is_(None),
)
.count()
)
),
"connector_sanctions_snapshots": (
session.query(ConnectorSanctionsSnapshot)
.filter(
ConnectorSanctionsSnapshot.tenant_id == tenant_id
)
.count()
),
"connector_sanctions_runs": (
session.query(ConnectorSanctionsAcquisitionRun)
.filter(
ConnectorSanctionsAcquisitionRun.tenant_id
== tenant_id
)
.count()
),
}
@@ -121,7 +170,13 @@ manifest = ModuleManifest(
id=MODULE_ID,
name="Connectors",
version=MODULE_VERSION,
optional_dependencies=("access", "audit", "files", "policy"),
optional_dependencies=(
"access",
"audit",
"files",
"policy",
"risk_compliance",
),
required_capabilities=(
CAPABILITY_AUTH_PRINCIPAL_RESOLVER,
CAPABILITY_AUTH_PERMISSION_EVALUATOR,
@@ -139,6 +194,10 @@ manifest = ModuleManifest(
name="connectors.datasource_origins",
version=DATASOURCE_ORIGIN_INTERFACE_VERSION,
),
ModuleInterfaceProvider(
name="connectors.sanctions_snapshots",
version=SANCTIONS_SNAPSHOT_INTERFACE_VERSION,
),
),
permissions=PERMISSIONS,
role_templates=ROLE_TEMPLATES,
@@ -147,6 +206,9 @@ manifest = ModuleManifest(
CAPABILITY_CONNECTORS_TABULAR_SOURCES: _provider,
CAPABILITY_CONNECTORS_TABULAR_SNAPSHOT_WRITER: _provider,
CAPABILITY_DATASOURCE_ORIGINS: _datasource_origin_provider,
CAPABILITY_CONNECTORS_SANCTIONS_SNAPSHOTS: (
_sanctions_snapshot_provider
),
},
tenant_summary_providers=(_tenant_summary,),
migration_spec=MigrationSpec(
@@ -155,6 +217,8 @@ manifest = ModuleManifest(
script_location=str(Path(__file__).with_name("migrations") / "versions"),
retirement_supported=True,
retirement_provider=drop_table_retirement_provider(
ConnectorSanctionsSnapshot,
ConnectorSanctionsAcquisitionRun,
ConnectorTabularSource,
label="Connectors",
),
@@ -165,6 +229,8 @@ manifest = ModuleManifest(
),
uninstall_guard_providers=(
persistent_table_uninstall_guard(
ConnectorSanctionsSnapshot,
ConnectorSanctionsAcquisitionRun,
ConnectorTabularSource,
label="Connectors",
),
@@ -188,6 +254,27 @@ manifest = ModuleManifest(
related_modules=("dataflow", "files", "reporting", "risk_compliance"),
order=40,
),
DocumentationTopic(
id="connectors.sanctions-snapshots",
title="Sanctions source snapshots",
summary=(
"Acquire immutable, checksum-verifiable sanctions list "
"evidence without transmitting screening subjects."
),
body=(
"Connectors provides a deterministic synthetic fixture and "
"the official United Nations Security Council consolidated "
"XML source. Each fetch records conditional transport "
"evidence, bounded retries, health state, source metadata, "
"raw evidence, and a SHA-256 checksum. Risk Compliance owns "
"normalization, matching, legal review, and dispositions."
),
layer="available",
documentation_types=("admin", "user"),
audience=("operator", "module_admin", "compliance_reviewer"),
related_modules=("risk_compliance", "dataflow"),
order=41,
),
),
)
@@ -200,6 +287,7 @@ __all__ = [
"MODULE_ID",
"MODULE_VERSION",
"DATASOURCE_ORIGIN_INTERFACE_VERSION",
"SANCTIONS_SNAPSHOT_INTERFACE_VERSION",
"TABULAR_SOURCE_INTERFACE_VERSION",
"get_manifest",
"manifest",