Add durable reconciliation decisions

This commit is contained in:
2026-08-06 12:42:20 +02:00
parent 3dae80b6b8
commit b14c693bde
14 changed files with 2037 additions and 19 deletions
+55 -2
View File
@@ -86,6 +86,12 @@ from govoplan_dataflow.backend.recovery import (
begin_dataflow_run_recovery,
dataflow_run_recovery_state,
)
from govoplan_dataflow.backend.reconciliation_decisions import (
current_decision_rows,
decision_set_fingerprint,
decision_set_id_from_ref,
get_decision_set,
)
from govoplan_dataflow.backend.sql_compiler import (
SqlCompilationError,
compile_sql,
@@ -1352,8 +1358,12 @@ def _run_authorization_payload(
graph = PipelineGraph.model_validate(revision.graph)
scopes = {RUN_SCOPE}
if any(
node.type == "source.reference"
or bool(node.config.get("source_ref"))
(
node.type == "source.reference"
or bool(node.config.get("source_ref"))
)
and decision_set_id_from_ref(str(node.config.get("source_ref") or ""))
is None
for node in graph.nodes
):
scopes.add(DATASOURCE_READ_SCOPE)
@@ -1880,6 +1890,49 @@ def _datasource_source_resolver(
provider = datasource_catalogue(registry)
def resolve_source(node: GraphNode, limit: int) -> ResolvedSource:
source_ref = str(node.config.get("source_ref") or "")
decision_set_id = decision_set_id_from_ref(source_ref)
if decision_set_id is not None:
try:
decision_set = get_decision_set(
session,
tenant_id=principal.tenant_id,
decision_set_id=decision_set_id,
include_decisions=False,
)
require_definition_action(
decision_set.pipeline,
principal=principal,
registry=registry,
action="view",
)
except (PermissionError, ValueError) as exc:
raise PipelineExecutionError(
str(exc),
node_id=node.id,
) from exc
rows, total_rows = current_decision_rows(
session,
decision_set_id=decision_set.id,
limit=limit,
)
fingerprint = decision_set_fingerprint(decision_set)
expected_fingerprint = _clean_optional(
node.config.get("expected_fingerprint")
)
if expected_fingerprint and expected_fingerprint != fingerprint:
raise PipelineExecutionError(
"Reconciliation decisions changed; refresh the decision source before running it.",
node_id=node.id,
)
return ResolvedSource(
rows=rows,
source_ref=source_ref,
provider="dataflow.reconciliation_decisions",
fingerprint=fingerprint,
total_rows=total_rows,
truncated=total_rows > len(rows),
)
if provider is None:
raise PipelineExecutionError(
"Datasource-backed execution requires the Datasources "