from datetime import datetime, timedelta, timezone from app.authoritative_operational_adapter import decide_authoritative_operation from app.canonical_operations import canonicalize_operations NOW = datetime(2026, 8, 16, tzinfo=timezone.utc) def projection(state="AWAITING_CUSTOMER", action=None, **extra): return {"opportunity_id": "opp", "canonical_opportunity_id": "opp", "business_state": state, "business_next_action": action, "confidence": "high", **extra} def task(code, due=NOW, **extra): return {"id": code, "status": "pending", "action_code": code, "due_at": due, **extra} def test_business_baselines_and_terminal(): for state, action in [("PROFORMA_REQUIRED", "CREATE_PROFORMA"), ("INVOICE_REQUIRED", "CREATE_INVOICE"), ("ODOO_ORDER_REQUIRED", "PREPARE_ORDER"), ("ODOO_ORDER_CREATED", "VALIDATE_ODOO_ORDER")]: got = decide_authoritative_operation(projection(state, action), now=NOW) assert (got.effective_action, got.queue) == (action, "do_now") assert decide_authoritative_operation(projection("COMPLETED"), now=NOW).queue == "not_current" def test_terminal_state_ignores_leftover_pending_obligation(): got = decide_authoritative_operation(projection("COMPLETED"), obligations=[task("REVIEW_RECONSTRUCTED_PROCESS")], now=NOW) assert (got.effective_action, got.queue, got.reason_code) == (None, "not_current", "TERMINAL_BUSINESS_STATE") def test_specific_reconstructed_review_overrides_generic_business_review(): got = decide_authoritative_operation(projection("REVIEW_REQUIRED", "REVIEW_REQUIRED"), obligations=[task("REVIEW_RECONSTRUCTED_PROCESS")], now=NOW) assert (got.business_next_action, got.effective_action, got.queue) == ( "REVIEW_REQUIRED", "REVIEW_RECONSTRUCTED_PROCESS", "review") def test_missing_projection_fails_closed_without_v1(): got = decide_authoritative_operation(None, now=NOW) assert (got.effective_action, got.queue, got.reason_code) == ("REVIEW_REQUIRED", "review", "MISSING_V2_PROJECTION") def test_due_and_future_customer_followup_semantics(): due = decide_authoritative_operation(projection(), obligations=[task("FOLLOW_UP_CUSTOMER_REVIEW")], now=NOW) assert (due.effective_action, due.queue) == ("FOLLOW_UP_CUSTOMER_REVIEW", "do_now") future = decide_authoritative_operation(projection(), obligations=[task("FOLLOW_UP_CUSTOMER_REVIEW", NOW + timedelta(days=1))], now=NOW) assert (future.effective_action, future.queue) == (None, "waiting") future_item = canonicalize_operations([{ "source": "flow_v2", "id": "opp", "opportunity_id": "opp", "status": "projected", "action_code": "WAIT_CUSTOMER", "created_at": NOW, }], {"opp": future.to_dict()})["items"] assert len(future_item) == 1 and future_item[0]["operational_queue"] == "waiting" assert decide_authoritative_operation(projection(), now=NOW).queue == "waiting" def test_unanswered_send_info_remains_valid_on_awaiting_customer(): inbound = NOW - timedelta(hours=2) obligation = task("SEND_INFO", latest_public_inbound=inbound, latest_public_outbound=None) got = decide_authoritative_operation(projection(), obligations=[obligation], now=NOW) assert (got.effective_action, got.queue, got.reason_code) == ( "SEND_INFO", "do_now", "ACTIVE_RESPONSE_OBLIGATION") def test_send_info_satisfied_by_later_outbound_is_not_current(): inbound = NOW - timedelta(hours=2) obligation = task("SEND_INFO", latest_public_inbound=inbound, latest_public_outbound=inbound + timedelta(minutes=10)) got = decide_authoritative_operation(projection(), obligations=[obligation], now=NOW) assert (got.effective_action, got.queue) == (None, "waiting") def test_only_active_non_superseded_tasks_override_and_precedence(): stale = task("SUPPORT", resolved_at=NOW) assert decide_authoritative_operation(projection("PROFORMA_REQUIRED", "CREATE_PROFORMA"), obligations=[stale], now=NOW).effective_action == "CREATE_PROFORMA" obligations = [task("CALL_CUSTOMER"), task("SEND_INFO"), task("SUPPORT"), task("REVIEW_MANUALLY")] assert decide_authoritative_operation(projection(), obligations=obligations, now=NOW).effective_action == "REVIEW_MANUALLY" assert decide_authoritative_operation(projection(), obligations=[task("SUPPORT")], now=NOW).effective_action == "SUPPORT" assert decide_authoritative_operation(projection("INQUIRY", "SEND_INFO"), obligations=[task("SEND_INFO")], now=NOW).effective_action == "SEND_INFO" assert decide_authoritative_operation(projection(), obligations=[task("SEND_INFO")], now=NOW).effective_action is None assert decide_authoritative_operation(projection(), obligations=[task("CALL_CUSTOMER")], now=NOW).effective_action == "CALL_CUSTOMER" def test_fiscal_and_reconciliation_only_block_formal_action(): inquiry = decide_authoritative_operation(projection("INQUIRY", "SEND_INFO"), fiscal_complete=False, reconciliation_blocking=True, now=NOW) assert inquiry.effective_action == "SEND_INFO" formal = decide_authoritative_operation(projection("PROFORMA_REQUIRED", "CREATE_PROFORMA"), fiscal_complete=False, now=NOW) assert (formal.effective_action, formal.blocking_action_code) == ("VALIDATE_FISCAL_CUSTOMER", "VALIDATE_FISCAL_CUSTOMER") def test_duplicate_is_suppressed_even_with_pending_legacy_task(): decision = decide_authoritative_operation(projection("REVIEW_REQUIRED", "REVIEW_REQUIRED", is_duplicate_representation=True, canonical_opportunity_id="canonical"), obligations=[task("REVIEW_MANUALLY")], now=NOW).to_dict() source = {"source": "task", "id": "t", "status": "pending", "action_code": "REVIEW_MANUALLY", "opportunity_id": "opp", "created_at": NOW} assert canonicalize_operations([source], {"opp": decision})["items"] == [] def test_xmat_duplicate_suppresses_diagnostic_review_business_action(): got = decide_authoritative_operation({ **projection("REVIEW_REQUIRED", "REVIEW_REQUIRED"), "opportunity_id": "1816a06e-9a69-4a9b-9279-1263156892d3", "canonical_opportunity_id": "dc89a466-db24-401b-bfe9-d47644b2d0c8", "is_duplicate_representation": True, }, now=NOW).to_dict() assert got["business_next_action"] == "REVIEW_REQUIRED" assert got["effective_action"] is None and got["suppress_current_card"] is True assert got["canonical_opportunity_id"] == "dc89a466-db24-401b-bfe9-d47644b2d0c8" def test_authoritative_queue_and_action_survive_canonical_boundary(): decision = decide_authoritative_operation(projection(), obligations=[task("FOLLOW_UP_CUSTOMER_REVIEW")], now=NOW).to_dict() source = {"source": "task", "id": "old", "status": "pending", "action_code": "SEND_INVOICE", "opportunity_id": "opp", "created_at": NOW} item = canonicalize_operations([source], {"opp": decision})["items"][0] assert (item["action_code"], item["operational_queue"]) == ("FOLLOW_UP_CUSTOMER_REVIEW", "do_now") def test_named_case_acceptance_decisions(): cases = { "5c33db95-fab8-477a-bddd-0b9cc8f91302": ("PROFORMA_REQUIRED", "CREATE_PROFORMA", [], "CREATE_PROFORMA", "do_now"), "fd79b9a1-07e6-4f61-95e8-09eab89c155e": ("AWAITING_CUSTOMER", None, [task("FOLLOW_UP_CUSTOMER_REVIEW")], "FOLLOW_UP_CUSTOMER_REVIEW", "do_now"), "61f1c955-a372-4ea7-b9b0-b8528d74a141": ("ODOO_ORDER_REQUIRED", "PREPARE_ORDER", [], "PREPARE_ORDER", "do_now"), "e3b23ac5-84db-4763-8a31-a684e873032c": ("ODOO_ORDER_REQUIRED", "PREPARE_ORDER", [], "PREPARE_ORDER", "do_now"), "dc89a466-db24-401b-bfe9-d47644b2d0c8": ("COMPLETED", None, [], None, "not_current"), "fd221608-e007-4043-a23d-07e0c119a345": ("REVIEW_REQUIRED", "REVIEW_REQUIRED", [], "REVIEW_REQUIRED", "review"), } for oid, (state, action, obligations, effective, queue) in cases.items(): got = decide_authoritative_operation({**projection(state, action), "opportunity_id": oid, "canonical_opportunity_id": oid}, obligations=obligations, now=NOW) assert (got.effective_action, got.queue) == (effective, queue) for duplicate, canonical in [ ("1816a06e-9a69-4a9b-9279-1263156892d3", "dc89a466-db24-401b-bfe9-d47644b2d0c8"), ("434124fb-ac19-4d78-909a-55761d7e8daa", "fd221608-e007-4043-a23d-07e0c119a345"), ]: got = decide_authoritative_operation({**projection("REVIEW_REQUIRED", "REVIEW_REQUIRED"), "opportunity_id": duplicate, "canonical_opportunity_id": canonical, "is_duplicate_representation": True}, now=NOW) assert (got.effective_action, got.queue, got.canonical_opportunity_id) == (None, "not_current", canonical)