perf: add opportunity detail read context
This commit is contained in:
@@ -55,10 +55,13 @@ def _operation_snapshot_safe(opportunity_id: str) -> dict[str, Any]:
|
||||
return {"cards": [], "links": []}
|
||||
|
||||
|
||||
def _build_db_evidence(opportunity_id: str) -> OpportunityEvidence | None:
|
||||
def _build_db_evidence(
|
||||
opportunity_id: str, preloaded: Optional[Dict[str, Any]] = None,
|
||||
) -> OpportunityEvidence | None:
|
||||
preloaded = preloaded or {}
|
||||
params = {"opportunity_id": opportunity_id}
|
||||
with engine.begin() as conn:
|
||||
opp = _first_row(conn, """
|
||||
opp = preloaded.get("opportunity") or _first_row(conn, """
|
||||
SELECT
|
||||
id::text,
|
||||
stage,
|
||||
@@ -73,7 +76,9 @@ def _build_db_evidence(opportunity_id: str) -> OpportunityEvidence | None:
|
||||
if not opp:
|
||||
return None
|
||||
|
||||
tasks = _rows(conn, """
|
||||
tasks = preloaded.get("tasks")
|
||||
if tasks is None:
|
||||
tasks = _rows(conn, """
|
||||
SELECT id::text, action_code, action, note, priority, route, status, due_at, created_at, metadata
|
||||
FROM tasks
|
||||
WHERE opportunity_id = CAST(:opportunity_id AS UUID)
|
||||
@@ -88,14 +93,16 @@ def _build_db_evidence(opportunity_id: str) -> OpportunityEvidence | None:
|
||||
# SELECT id::text, external_id, document_kind
|
||||
# The SQL now qualifies these fields because links and documents both
|
||||
# have ids; relationship comes exclusively from the canonical link.
|
||||
from app.document_reconciliation_service import resolve_document_links
|
||||
docs = [row for row in resolve_document_links(opportunity_id, conn=conn)
|
||||
if row.get("system") == "jasmin" and row.get("relationship") in
|
||||
docs = preloaded.get("resolved_documents")
|
||||
if docs is None:
|
||||
from app.document_reconciliation_service import resolve_document_links
|
||||
docs = resolve_document_links(opportunity_id, conn=conn)
|
||||
docs = [row for row in docs if row.get("system") == "jasmin" and row.get("relationship") in
|
||||
{"PRIMARY", "SECONDARY", "HISTORICAL"}]
|
||||
|
||||
linked_customer = None
|
||||
linked_customer = preloaded.get("customer")
|
||||
customer_id = opp.get("fiscal_customer_id") or opp.get("customer_id")
|
||||
if customer_id:
|
||||
if customer_id and linked_customer is None:
|
||||
linked_customer = _first_row(conn, """
|
||||
SELECT
|
||||
id::text,
|
||||
@@ -120,7 +127,7 @@ def _build_db_evidence(opportunity_id: str) -> OpportunityEvidence | None:
|
||||
LIMIT 1
|
||||
""", params)
|
||||
|
||||
snapshot = _operation_snapshot_safe(opportunity_id)
|
||||
snapshot = preloaded.get("operation_snapshot") or _operation_snapshot_safe(opportunity_id)
|
||||
fiscal_complete = False
|
||||
if linked_customer:
|
||||
fiscal_complete = bool(
|
||||
@@ -144,14 +151,17 @@ def _build_db_evidence(opportunity_id: str) -> OpportunityEvidence | None:
|
||||
)
|
||||
|
||||
|
||||
def get_opportunity_next_action(opportunity_id: str) -> Dict[str, Any]:
|
||||
def get_opportunity_next_action(
|
||||
opportunity_id: str, *, preloaded: Optional[Dict[str, Any]] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""Return the recommended operator action for one opportunity.
|
||||
|
||||
This remains a read-only service and returns the legacy dict shape, but the
|
||||
decision is now produced by the company workflow engine.
|
||||
"""
|
||||
|
||||
evidence = _build_db_evidence(opportunity_id)
|
||||
evidence = (_build_db_evidence(opportunity_id, preloaded=preloaded)
|
||||
if preloaded is not None else _build_db_evidence(opportunity_id))
|
||||
if evidence is None:
|
||||
return OpportunityNextAction(
|
||||
action_code="NOT_FOUND",
|
||||
|
||||
Reference in New Issue
Block a user