feat: add BLIF Flow v2 authoritative operational adapter
This commit is contained in:
@@ -672,6 +672,42 @@ def get_operations_summary(limit: int = 24) -> Dict[str, Any]:
|
||||
conversation_timeline = {str(row["conversation_id"]): dict(row) for row in timeline_rows}
|
||||
|
||||
seed_rows = [dict(r) for r in work_seed_rows]
|
||||
# In authoritative mode the factual projection, not a legacy task/stage,
|
||||
# selects material processes that have current business work. Synthetic
|
||||
# rows are read-model seeds only and are never persisted.
|
||||
if str(settings.blif_flow_v2_mode or "off").strip().lower() == "authoritative":
|
||||
seeded = {str(row.get("opportunity_id") or "") for row in seed_rows}
|
||||
with engine.connect() as conn:
|
||||
v2_seeds = conn.execute(text("""
|
||||
SELECT p.opportunity_id::text, p.business_next_action, p.derived_at,
|
||||
o.title, o.value_amount, o.currency, o.lifecycle_state,
|
||||
c.name AS customer_name
|
||||
FROM opportunity_flow_state_v2 p
|
||||
JOIN opportunities o ON o.id = p.opportunity_id
|
||||
LEFT JOIN customers c ON c.id = o.local_customer_id
|
||||
WHERE p.is_duplicate_representation = false
|
||||
AND (p.business_next_action IS NOT NULL
|
||||
OR p.business_state IN ('AWAITING_CUSTOMER', 'AWAITING_PAYMENT'))
|
||||
""")).mappings().all()
|
||||
for projection_seed in v2_seeds:
|
||||
oid = str(projection_seed["opportunity_id"])
|
||||
if oid in seeded:
|
||||
continue
|
||||
seed_rows.append({
|
||||
"source": "flow_v2", "id": oid, "opportunity_id": oid,
|
||||
"created_at": projection_seed.get("derived_at"), "due_at": None,
|
||||
"priority": "normal", "queue": "vendas",
|
||||
"action_code": projection_seed.get("business_next_action"), "status": "projected",
|
||||
"title": projection_seed.get("title") or "Oportunidade",
|
||||
"opportunity_title": projection_seed.get("title") or "",
|
||||
"customer_name": projection_seed.get("customer_name") or "",
|
||||
"fiscal_customer_name": projection_seed.get("customer_name") or "",
|
||||
"item_metadata": {}, "opportunity_metadata": {},
|
||||
"opportunity_lifecycle_state": projection_seed.get("lifecycle_state") or "",
|
||||
"opportunity_value_amount": projection_seed.get("value_amount") or 0,
|
||||
"opportunity_currency": projection_seed.get("currency") or "EUR",
|
||||
"href": f"/opportunities/{oid}", "action_label": "Abrir",
|
||||
})
|
||||
for row in seed_rows:
|
||||
timeline = conversation_timeline.get(str(row.get("conversation_id") or ""), {})
|
||||
row.update({key: timeline.get(key) for key in ("latest_public_inbound", "latest_public_outbound")})
|
||||
|
||||
Reference in New Issue
Block a user