fix: harden Flow v2 authoritative cutover semantics
This commit is contained in:
@@ -15,6 +15,7 @@ class Result:
|
||||
def __init__(self, row): self.row = row
|
||||
def mappings(self): return self
|
||||
def one(self): return self.row
|
||||
def all(self): return self.row if isinstance(self.row, list) else [self.row]
|
||||
|
||||
|
||||
class Connection:
|
||||
@@ -26,6 +27,8 @@ class Connection:
|
||||
return Result({"database": self.database, "user": "audit", "transaction_read_only": self.readonly})
|
||||
if "count(*) FROM opportunities" in sql:
|
||||
return Result({"opportunities": 328, "projections": 328})
|
||||
if "GROUP BY business_state" in sql:
|
||||
return Result([])
|
||||
return Result({})
|
||||
def close(self): pass
|
||||
|
||||
@@ -37,8 +40,8 @@ class Engine:
|
||||
|
||||
def named_decisions(fail=False):
|
||||
result = {}
|
||||
for name, (oid, action, queue) in sim.NAMED.items():
|
||||
result[oid] = {"effective_action": action,
|
||||
for name, (oid, business_action, action, queue) in sim.NAMED.items():
|
||||
result[oid] = {"business_next_action": business_action, "effective_action": action,
|
||||
"operational_queue": "not_current" if queue == "suppressed" else queue,
|
||||
"suppress_current_card": queue == "suppressed"}
|
||||
if fail:
|
||||
@@ -136,3 +139,29 @@ def test_named_case_failure_is_nonzero():
|
||||
report = sim.build_report(identity={}, configured_mode="compare", v1={"work_items": []},
|
||||
v2={"work_items": []}, named_decisions=named_decisions(True), missing_projections=0)
|
||||
assert sim.exit_code(report) != 0
|
||||
|
||||
|
||||
def test_action_changes_correlate_by_material_process_not_action_key():
|
||||
v1_item = {"work_item_key": "opportunity:o:action:OLD", "opportunity_id": "o",
|
||||
"action_code": "OLD", "operational_queue": "do_now"}
|
||||
v2_item = {"work_item_key": "opportunity:o:action:NEW", "opportunity_id": "o",
|
||||
"canonical_opportunity_id": "o", "action_code": "NEW", "operational_queue": "do_now"}
|
||||
report = sim.build_report(identity={}, configured_mode="compare",
|
||||
v1={"work_items": [v1_item]}, v2={"work_items": [v2_item]},
|
||||
named_decisions=named_decisions(), missing_projections=0)
|
||||
assert len(report["changed_actions"]) == 1
|
||||
assert report["removed_cards"] == [] and report["added_cards"] == []
|
||||
|
||||
|
||||
def test_authoritative_material_collapse_selects_one_card_and_retains_evidence():
|
||||
from app.operations_service import _collapse_authoritative_material_processes
|
||||
rows = [
|
||||
{"process_key": "conversation:chatwoot:1863", "work_item_key": "x:SEND_INFO",
|
||||
"action_code": "SEND_INFO", "operational_queue": "do_now", "source_refs": [{"source": "task", "id": "1"}]},
|
||||
{"process_key": "conversation:chatwoot:1863", "work_item_key": "x:REVIEW_MANUALLY",
|
||||
"action_code": "REVIEW_MANUALLY", "operational_queue": "review", "source_refs": [{"source": "communication", "id": "2"}]},
|
||||
]
|
||||
result = _collapse_authoritative_material_processes(rows)
|
||||
assert len(result) == 1
|
||||
assert result[0]["action_code"] == "REVIEW_MANUALLY"
|
||||
assert {ref["id"] for ref in result[0]["source_refs"]} == {"1", "2"}
|
||||
|
||||
Reference in New Issue
Block a user