""" Call Persistence — Writes completed calls and their transcript chunks to the database when CallManager.end_call() fires. """ import logging import uuid from datetime import datetime from db.database import CallRecord, TranscriptChunk, get_session_factory from models.call import ActiveCall, CallStatus logger = logging.getLogger(__name__) async def persist_call_on_end(call: ActiveCall, final_status: CallStatus) -> None: """Insert a CallRecord and any transcript chunks for `call`. Wired into CallManager via _on_call_ended in gateway.start(). """ try: async with get_session_factory()() as session: record = CallRecord( id=call.id, direction=call.direction, remote_number=call.remote_number, status=final_status.value, mode=call.mode.value, intent=call.intent, started_at=call.started_at, ended_at=datetime.now(), duration=int(call.duration), hold_time=int(call.hold_time), device_used=call.device, call_flow_id=call.call_flow_id, classification_timeline=[ { "timestamp": c.timestamp, "audio_type": c.audio_type.value, "confidence": c.confidence, } for c in call.classification_history ], metadata_={"services": list(call.services)}, ) session.add(record) # Each transcript chunk gets its own row with a sequence number # so the dashboard can render them in order with click-to-seek. for seq, text in enumerate(call.transcript_chunks): speaker = "unknown" payload = text if ":" in text: head, rest = text.split(":", 1) head = head.strip().lower() if head in {"caller", "agent", "receptionist", "caller_message"}: speaker = head if head != "caller_message" else "caller" payload = rest.strip() session.add(TranscriptChunk( id=f"tc_{uuid.uuid4().hex[:10]}", call_id=call.id, seq=seq, t_offset_ms=0, speaker=speaker, text=payload, )) await session.commit() except Exception as e: logger.warning(f"Could not persist call {call.id}: {e}")