import logging from fastapi import APIRouter, Depends, Query from sqlalchemy.orm import Session from backend.database.db import get_db from backend.analytics.metrics import get_dashboard_metrics, get_evaluation_history from backend.database.models import EvaluationResult, FailureLog from sqlalchemy import desc router = APIRouter(prefix="/analytics", tags=["analytics"]) logger = logging.getLogger(__name__) @router.get("/dashboard") async def dashboard(db: Session = Depends(get_db)): return get_dashboard_metrics(db) @router.get("/history") async def history(limit: int = Query(50, le=200), db: Session = Depends(get_db)): return get_evaluation_history(db, limit=limit) @router.get("/evaluation/{eval_id}") async def get_evaluation(eval_id: int, db: Session = Depends(get_db)): ev = db.query(EvaluationResult).filter(EvaluationResult.id == eval_id).first() if not ev: from fastapi import HTTPException raise HTTPException(status_code=404, detail="Evaluation not found") failure = db.query(FailureLog).filter(FailureLog.eval_id == eval_id).first() return { "id": ev.id, "session_id": ev.session_id, "query": ev.query, "response": ev.response, "code_eval": { "result": ev.code_eval_result, "details": ev.code_eval_details }, "scores": { "policy_compliance": ev.policy_compliance, "faithfulness": ev.faithfulness, "relevance": ev.relevance, "tone": ev.tone, "correctness": ev.correctness }, "judge_verdict": ev.judge_verdict, "judge_reasoning": ev.judge_reasoning, "hallucination": { "detected": ev.hallucination_detected, "details": ev.hallucination_details, "severity": ev.hallucination_severity }, "trust_score": ev.trust_score, "final_verdict": ev.final_verdict, "is_retry": ev.is_retry, "deployment_ready": ev.deployment_ready, "failure_analysis": { "primary_failure_reason": failure.primary_failure_reason if failure else None, "policy_violations": failure.policy_violations if failure else [], "hallucinations": failure.hallucinations if failure else [], "improvement_suggestions": failure.improvement_suggestions if failure else [], "corrected_response": failure.corrected_response if failure else None, "severity": failure.severity if failure else None } if failure else None, "created_at": ev.created_at.isoformat() } @router.get("/failures") async def get_failures(limit: int = Query(20, le=100), db: Session = Depends(get_db)): failures = ( db.query(FailureLog) .order_by(desc(FailureLog.created_at)) .limit(limit) .all() ) return [ { "id": f.id, "eval_id": f.eval_id, "query": f.query, "response": f.response, "primary_failure_reason": f.primary_failure_reason, "policy_violations": f.policy_violations, "hallucinations": f.hallucinations, "improvement_suggestions": f.improvement_suggestions, "corrected_response": f.corrected_response, "severity": f.severity, "created_at": f.created_at.isoformat() } for f in failures ] @router.get("/policies") async def get_policies(): from backend.prompts.policies import COMPANY_POLICIES return { k: { "title": v["title"], "content": v["content"] } for k, v in COMPANY_POLICIES.items() } @router.get("/dataset") async def get_dataset(): from backend.datasets.queries import CUSTOMER_QUERIES_DATASET return { "total": len(CUSTOMER_QUERIES_DATASET), "queries": CUSTOMER_QUERIES_DATASET }