feat(dataflow): add governed DSAR coverage
This commit is contained in:
@@ -17,6 +17,7 @@ from govoplan_core.core.dataflows import (
|
||||
CAPABILITY_DATAFLOW_TRIGGER_DISPATCHER,
|
||||
)
|
||||
from govoplan_core.core.modules import (
|
||||
CapabilityDocumentation,
|
||||
DocumentationTopic,
|
||||
FrontendModule,
|
||||
FrontendRoute,
|
||||
@@ -47,6 +48,10 @@ from govoplan_core.core.search import SearchSourceProviderRegistration
|
||||
from govoplan_core.core.views import ViewSurface
|
||||
from govoplan_core.db.base import Base
|
||||
from govoplan_dataflow.backend.db import models as dataflow_models
|
||||
from govoplan_dataflow.backend.dsar_provider import (
|
||||
DATAFLOW_DSAR_CAPABILITY,
|
||||
DataflowDsarProvider,
|
||||
)
|
||||
|
||||
|
||||
MODULE_ID = "dataflow"
|
||||
@@ -142,6 +147,27 @@ ROLE_TEMPLATES = (
|
||||
)
|
||||
|
||||
DOCUMENTATION = (
|
||||
DocumentationTopic(
|
||||
id="dataflow.data-subject-requests",
|
||||
title="Dataflow data-subject requests",
|
||||
summary="Minimize retained transformation detail without treating derived flows as authoritative subject records.",
|
||||
body=(
|
||||
"Dataflow matches exact tenant-scoped pipeline, revision, reconciliation, run, deployment, trigger, and delivery identifiers plus minimized account, identity, and membership attribution. Results never copy graphs, SQL, request or event payloads, reconciliation corrections, authorization snapshots, provenance bodies, errors, source details, hashes, credentials, or output rows. Dataflow does not scan arbitrary transformation content for a person; the authoritative input module must locate and correct subject facts. "
|
||||
"Explicitly identified terminal run and delivery detail can be minimized idempotently, and automation authority linked to the subject can be disabled and revoked. Definitions, reconciliation evidence, active work, deployments, broad pipeline packages, published Datasource outputs, and institutional attribution require authorized review or retention. Correct sources and refresh Datasource, Search, and Reporting derivatives after review."
|
||||
),
|
||||
layer="configured",
|
||||
documentation_types=("admin", "user"),
|
||||
audience=("user", "operator", "module_admin", "data_steward", "auditor"),
|
||||
order=74,
|
||||
related_modules=("core", "datasources", "reporting", "workflow_engine"),
|
||||
metadata={
|
||||
"help_contexts": [
|
||||
"dataflow.data-subject-requests",
|
||||
"dataflow.runs",
|
||||
"dataflow.triggers",
|
||||
],
|
||||
},
|
||||
),
|
||||
DocumentationTopic(
|
||||
id="dataflow.module-boundary",
|
||||
title="Dataflow module boundary",
|
||||
@@ -248,7 +274,13 @@ DOCUMENTATION = (
|
||||
documentation_types=("admin", "user"),
|
||||
audience=("operator", "module_admin", "power_user", "product_owner"),
|
||||
order=77,
|
||||
related_modules=("datasources", "workflow_engine", "notifications", "policy", "audit"),
|
||||
related_modules=(
|
||||
"datasources",
|
||||
"workflow_engine",
|
||||
"notifications",
|
||||
"policy",
|
||||
"audit",
|
||||
),
|
||||
metadata={
|
||||
"help_contexts": [
|
||||
"dataflow.field.scope",
|
||||
@@ -323,6 +355,11 @@ def _run_provider(context: ModuleContext):
|
||||
return SqlDataflowRunLifecycleProvider(registry=context.registry)
|
||||
|
||||
|
||||
def _dsar_provider(context: ModuleContext) -> DataflowDsarProvider:
|
||||
del context
|
||||
return DataflowDsarProvider()
|
||||
|
||||
|
||||
def _run_worker(context: ModuleContext):
|
||||
from govoplan_dataflow.backend.run_worker import SqlDataflowRunWorker
|
||||
|
||||
@@ -367,25 +404,20 @@ def _tenant_summary(session, tenant_id: str) -> dict[str, int]:
|
||||
),
|
||||
"dataflow_trigger_deliveries": (
|
||||
session.query(dataflow_models.DataflowTriggerDelivery)
|
||||
.filter(
|
||||
dataflow_models.DataflowTriggerDelivery.tenant_id
|
||||
== tenant_id
|
||||
)
|
||||
.filter(dataflow_models.DataflowTriggerDelivery.tenant_id == tenant_id)
|
||||
.count()
|
||||
),
|
||||
"dataflow_reconciliation_decision_sets": (
|
||||
session.query(dataflow_models.DataflowReconciliationDecisionSet)
|
||||
.filter(
|
||||
dataflow_models.DataflowReconciliationDecisionSet.tenant_id
|
||||
== tenant_id
|
||||
dataflow_models.DataflowReconciliationDecisionSet.tenant_id == tenant_id
|
||||
)
|
||||
.count()
|
||||
),
|
||||
"dataflow_reconciliation_decisions": (
|
||||
session.query(dataflow_models.DataflowReconciliationDecision)
|
||||
.filter(
|
||||
dataflow_models.DataflowReconciliationDecision.tenant_id
|
||||
== tenant_id
|
||||
dataflow_models.DataflowReconciliationDecision.tenant_id == tenant_id
|
||||
)
|
||||
.count()
|
||||
),
|
||||
@@ -420,15 +452,22 @@ manifest = ModuleManifest(
|
||||
CAPABILITY_POLICY_DEFINITION_GOVERNANCE,
|
||||
),
|
||||
provides_interfaces=(
|
||||
ModuleInterfaceProvider(name="dataflow.pipeline_catalog", version=MODULE_VERSION),
|
||||
ModuleInterfaceProvider(name="dataflow.pipeline_preview", version=MODULE_VERSION),
|
||||
ModuleInterfaceProvider(
|
||||
name="dataflow.pipeline_catalog", version=MODULE_VERSION
|
||||
),
|
||||
ModuleInterfaceProvider(
|
||||
name="dataflow.pipeline_preview", version=MODULE_VERSION
|
||||
),
|
||||
ModuleInterfaceProvider(name="dataflow.run_lifecycle", version=MODULE_VERSION),
|
||||
ModuleInterfaceProvider(name="dataflow.run_worker", version=MODULE_VERSION),
|
||||
ModuleInterfaceProvider(name=CAPABILITY_DATAFLOW_DATASET_OUTPUT, version=MODULE_VERSION),
|
||||
ModuleInterfaceProvider(
|
||||
name=CAPABILITY_DATAFLOW_DATASET_OUTPUT, version=MODULE_VERSION
|
||||
),
|
||||
ModuleInterfaceProvider(
|
||||
name="dataflow.trigger_dispatcher",
|
||||
version=MODULE_VERSION,
|
||||
),
|
||||
ModuleInterfaceProvider(name=DATAFLOW_DSAR_CAPABILITY, version="0.1.0"),
|
||||
),
|
||||
requires_interfaces=(
|
||||
ModuleInterfaceRequirement(
|
||||
@@ -612,6 +651,16 @@ manifest = ModuleManifest(
|
||||
CAPABILITY_DATAFLOW_RUN_LIFECYCLE: _run_provider,
|
||||
CAPABILITY_DATAFLOW_RUN_WORKER: _run_worker,
|
||||
CAPABILITY_DATAFLOW_TRIGGER_DISPATCHER: _trigger_provider,
|
||||
DATAFLOW_DSAR_CAPABILITY: _dsar_provider,
|
||||
},
|
||||
capability_documentation={
|
||||
DATAFLOW_DSAR_CAPABILITY: CapabilityDocumentation(
|
||||
label="Dataflow data-subject request provider",
|
||||
summary="Finds and minimizes subject-linked transformation state and automation authority.",
|
||||
contract_version="0.1.0",
|
||||
documentation_types=("admin", "user"),
|
||||
audience=("privacy_officer", "data_steward", "user"),
|
||||
),
|
||||
},
|
||||
search_sources=(
|
||||
SearchSourceProviderRegistration(
|
||||
@@ -671,7 +720,12 @@ manifest = ModuleManifest(
|
||||
"reconciliation decision set",
|
||||
"transformation graph",
|
||||
),
|
||||
non_owned_concepts=("datasource binding", "connector transport", "report presentation", "workflow task"),
|
||||
non_owned_concepts=(
|
||||
"datasource binding",
|
||||
"connector transport",
|
||||
"report presentation",
|
||||
"workflow task",
|
||||
),
|
||||
recovery_docs=("README.md", "docs/DURABLE_RUN_RECOVERY.md"),
|
||||
security_docs=("README.md",),
|
||||
operations_docs=("README.md",),
|
||||
|
||||
Reference in New Issue
Block a user