"""Dashboard metrics API.""" from fastapi import APIRouter, Depends from sqlalchemy import func, select from sqlalchemy.ext.asyncio import AsyncSession from app.db import get_db from app.models import Conversation, Lead, UnansweredQuestion from app.schemas import DashboardStats router = APIRouter(prefix="/api/dashboard", tags=["dashboard"]) @router.get("/stats", response_model=DashboardStats) async def dashboard_stats( db: AsyncSession = Depends(get_db), ) -> DashboardStats: """Aggregate KPIs for the operator dashboard.""" total = await db.scalar( select(func.count(Conversation.id)) ) or 0 resolved = await db.scalar( select(func.count(Conversation.id)).where( Conversation.resolved_without_human.is_(True) ) ) or 0 appointments = await db.scalar( select(func.count(Conversation.id)).where( Conversation.appointment_booked.is_(True) ) ) or 0 handed = await db.scalar( select(func.count(Conversation.id)).where( Conversation.handed_off.is_(True) ) ) or 0 unanswered = await db.scalar( select(func.count(UnansweredQuestion.id)) ) or 0 leads_complete = await db.scalar( select(func.count(Lead.id)).where(Lead.complete.is_(True)) ) or 0 channel_rows = ( await db.execute( select( Conversation.channel, func.count(Conversation.id), ).group_by(Conversation.channel) ) ).all() language_rows = ( await db.execute( select( Conversation.language, func.count(Conversation.id), ).group_by(Conversation.language) ) ).all() recent = ( await db.execute( select(UnansweredQuestion) .order_by(UnansweredQuestion.created_at.desc()) .limit(10) ) ).scalars().all() rate = (resolved / total * 100.0) if total else 0.0 return DashboardStats( total_conversations=int(total), resolved_without_human=int(resolved), resolution_rate=round(rate, 1), appointments_booked=int(appointments), handed_off=int(handed), unanswered_count=int(unanswered), leads_complete=int(leads_complete), by_channel={c: int(n) for c, n in channel_rows}, by_language={lang: int(n) for lang, n in language_rows}, recent_unanswered=[ { "id": q.id, "conversation_id": q.conversation_id, "question": q.question, "created_at": q.created_at.isoformat(), } for q in recent ], )