Files

86 lines
2.4 KiB
Python

from __future__ import annotations
from collections.abc import Mapping
from typing import Any
from sqlalchemy import select
from sqlalchemy.orm import Session
from services.shared.core import utc_now_iso
from services.shared.sql_models import ReportingInteractionFactRow
_STRING_FIELDS = (
"interaction_id",
"channel",
"queue_id",
"agent_id",
"status",
"created_at",
"closed_at",
"source",
)
_BOOL_FIELDS = ("answered", "abandoned", "resolved_first_contact")
_INT_FIELDS = ("wait_seconds", "handle_seconds")
def _clean_string(value: Any) -> str | None:
raw = str(value or "").strip()
return raw or None
def _clean_bool(value: Any) -> bool | None:
if value is None:
return None
return bool(value)
def _clean_int(value: Any) -> int | None:
if value is None or value == "":
return None
parsed = int(value)
return max(parsed, 0)
def normalize_reporting_fact_payload(payload: Mapping[str, Any]) -> dict[str, Any]:
normalized: dict[str, Any] = {}
for field in _STRING_FIELDS:
value = _clean_string(payload.get(field))
if value is not None:
normalized[field] = value
for field in _BOOL_FIELDS:
value = _clean_bool(payload.get(field))
if value is not None:
normalized[field] = value
for field in _INT_FIELDS:
value = _clean_int(payload.get(field))
if value is not None:
normalized[field] = value
interaction_id = normalized.get("interaction_id")
if not interaction_id:
raise ValueError("interaction_id is required")
source = normalized.get("source")
if not source:
raise ValueError("source is required")
return normalized
def upsert_reporting_interaction_fact(session: Session, payload: Mapping[str, Any]) -> ReportingInteractionFactRow:
normalized = normalize_reporting_fact_payload(payload)
row = session.execute(
select(ReportingInteractionFactRow).where(
ReportingInteractionFactRow.interaction_id == normalized["interaction_id"]
)
).scalar_one_or_none()
if row is None:
row = ReportingInteractionFactRow(
interaction_id=normalized["interaction_id"],
source=normalized["source"],
updated_at=utc_now_iso(),
)
session.add(row)
for field, value in normalized.items():
setattr(row, field, value)
row.updated_at = utc_now_iso()
return row