system-prompts-and-models-o.../salesflow-saas/backend/app/services/dealix_enrichment_runner.py
Sami Assiri d8bb836614 feat(dealix): ship revenue discovery launch hardening
Add revenue discovery APIs/services, launch verification gates, CI quality checks, and frontend E2E/docs updates to prepare the branch for production go-live.

Made-with: Cursor
2026-04-15 17:51:23 +03:00

83 lines
3.0 KiB
Python

"""Shared enrichment pipeline for sync HTTP and background jobs."""
from __future__ import annotations
import hashlib
import json
import logging
import os
from datetime import datetime, timezone
from sqlalchemy.ext.asyncio import AsyncSession
from app.schemas.dealix_master import EnrichExplorationBody
from app.services.intelligence_plane_control import cache_get, cache_set, tenant_may_use_licensed_search
from app.services.revenue_discovery_service import build_enrichment_for_lead, resolve_playbook_id
logger = logging.getLogger("dealix.enrichment_runner")
async def compute_enrich_exploration(
db: AsyncSession,
body: EnrichExplorationBody,
*,
tenant_id: str | None,
tid_for_tavily: str | None,
) -> dict:
"""
Cache-aware enrichment (payload hash + daily idempotency). Returns model_dump dict.
"""
payload_hash = hashlib.sha256(
json.dumps(body.model_dump(), ensure_ascii=False, sort_keys=True).encode("utf-8")
).hexdigest()[:32]
cache_key = f"enrich:{payload_hash}"
cached = cache_get(cache_key)
if cached is not None:
return cached
company_key = str(body.lead.get("company_name") or "").strip().lower()[:160]
day = datetime.now(timezone.utc).strftime("%Y-%m-%d")
idem_key = (
f"enrich:idemp:{day}:{body.sector}:{body.city}:"
f"{hashlib.sha256(company_key.encode('utf-8')).hexdigest()[:24]}"
)
if os.getenv("DEALIX_ENRICH_IDEMPOTENT_DAILY", "true").lower() not in ("0", "false", "no"):
idem_hit = cache_get(idem_key)
if idem_hit is not None:
return idem_hit
allow_search = (os.getenv("TAVILY_API_KEY") or "").strip() != ""
if os.getenv("DEALIX_ALLOW_LICENSED_SEARCH", "true").lower() in ("0", "false", "no"):
allow_search = False
if tid_for_tavily and not tenant_may_use_licensed_search(tid_for_tavily):
allow_search = False
knowledge_chunks: list[dict] = []
if os.getenv("DEALIX_KNOWLEDGE_RAG_ENRICH", "true").lower() not in ("0", "false", "no"):
try:
from app.services.knowledge_service import KnowledgeService
ks = KnowledgeService(db)
q = f"{company_key} {body.sector} {body.city} sales partnership B2B"
pb = resolve_playbook_id(body.sector)
knowledge_chunks = await ks.search_sector_knowledge(q, sector=pb, limit=3)
if not knowledge_chunks:
knowledge_chunks = await ks.search_sector_knowledge(q, sector=None, limit=3)
except Exception as e:
logger.debug("knowledge RAG skipped: %s", e)
enrichment = await build_enrichment_for_lead(
sector=body.sector,
city=body.city,
lead=body.lead,
icp_notes_ar=body.icp_notes_ar,
icp_notes_en=body.icp_notes_en,
use_licensed_search=allow_search,
knowledge_chunks=knowledge_chunks or None,
)
out = enrichment.model_dump()
cache_set(cache_key, out)
if os.getenv("DEALIX_ENRICH_IDEMPOTENT_DAILY", "true").lower() not in ("0", "false", "no"):
cache_set(idem_key, out, ttl_sec=86400)
return out