Add version-pinned reconciliation decisions

This commit is contained in:
2026-08-04 11:45:35 +02:00
parent 3991c179a4
commit 314e7c3edf
15 changed files with 724 additions and 7 deletions
@@ -712,6 +712,73 @@ export default function NodeInspector({
</FormField>
</>
) : null}
{node.type === "reconcile.decisions" ? (
<>
<FormField label="Decision key hash column">
<input
value={textValue(node.config.decision_key_column)}
onChange={(event) => updateConfig({ decision_key_column: event.target.value })}
disabled={readOnly}
/>
</FormField>
<FormField label="Decision input hash column">
<input
value={textValue(node.config.decision_input_column)}
onChange={(event) => updateConfig({ decision_input_column: event.target.value })}
disabled={readOnly}
/>
</FormField>
<FormField label="Decision reference column">
<input
value={textValue(node.config.decision_ref_column)}
onChange={(event) => updateConfig({ decision_ref_column: event.target.value })}
disabled={readOnly}
/>
</FormField>
<FormField label="Action column">
<input
value={textValue(node.config.action_column)}
onChange={(event) => updateConfig({ action_column: event.target.value })}
disabled={readOnly}
/>
</FormField>
<FormField label="Actor reference column">
<input
value={textValue(node.config.actor_column)}
onChange={(event) => updateConfig({ actor_column: event.target.value })}
disabled={readOnly}
/>
</FormField>
<FormField label="Decision time column">
<input
value={textValue(node.config.decided_at_column)}
onChange={(event) => updateConfig({ decided_at_column: event.target.value })}
disabled={readOnly}
/>
</FormField>
<FormField label="Reason column">
<input
value={textValue(node.config.reason_column)}
onChange={(event) => updateConfig({ reason_column: event.target.value })}
disabled={readOnly}
/>
</FormField>
<FormField label="Correction column">
<input
value={textValue(node.config.correction_column)}
onChange={(event) => updateConfig({ correction_column: event.target.value })}
disabled={readOnly}
/>
</FormField>
<FormField label="Allowed actions">
<input
value={stringList(node.config.allowed_actions).join(", ")}
onChange={(event) => updateConfig({ allowed_actions: commaList(event.target.value) })}
disabled={readOnly}
/>
</FormField>
</>
) : null}
{node.type === "subflow" ? (
<>
<FormField label="Template reference">
+25 -1
View File
@@ -243,6 +243,30 @@ export const FALLBACK_NODE_LIBRARY: NodeTypeDefinition[] = [
output,
{ left_keys: [""], right_keys: [""], compare_columns: [], right_prefix: "observed_" }
),
nodeType(
"reconcile.decisions",
"quality",
"Quality",
"Apply review decisions",
"Attach versioned decisions while reconciliation inputs still match.",
"list-checks",
[
{ id: "records", label: "Reconciliation rows", required: true, multiple: false, minimum_connections: 1 },
{ id: "decisions", label: "Decision rows", required: true, multiple: false, minimum_connections: 1 }
],
output,
{
decision_key_column: "key_hash",
decision_input_column: "input_hash",
decision_ref_column: "decision_ref",
action_column: "action",
actor_column: "actor_ref",
decided_at_column: "decided_at",
reason_column: "reason",
correction_column: "correction",
allowed_actions: ["accept", "reject", "correct", "defer"]
}
),
nodeType(
"subflow",
"transform",
@@ -446,7 +470,7 @@ function nodeType(
config_fields: [],
default_config: defaultConfig,
sql_support:
["replace", "quality.rules", "reconcile.compare", "subflow"].includes(type)
["replace", "quality.rules", "reconcile.compare", "reconcile.decisions", "subflow"].includes(type)
? "none"
: ["combine.union", "combine.join", "distinct", "derive", "expression", "convert", "filter.expression"].includes(type)
? "partial"