Spaces:
Sleeping
Sleeping
File size: 1,854 Bytes
3c4a809 76089f2 3c4a809 76089f2 3c4a809 76089f2 3c4a809 76089f2 3c4a809 76089f2 3c4a809 76089f2 3c4a809 76089f2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session
from sqlalchemy import func
from typing import Optional
from database import get_db
from models import Lead, AnalyticsResponse, LeadResponse
router = APIRouter(prefix="/analytics", tags=["analytics"])
@router.get("", response_model=AnalyticsResponse)
def get_analytics(project_id: Optional[int] = Query(None), db: Session = Depends(get_db)):
base = db.query(Lead)
if project_id is not None:
base = base.filter(Lead.project_id == project_id)
total_leads = base.count()
# Leads by status
status_rows = base.with_entities(Lead.status, func.count(Lead.id)).group_by(Lead.status).all()
leads_by_status = {row[0] or "unknown": row[1] for row in status_rows}
# Leads by source
source_rows = base.with_entities(Lead.source, func.count(Lead.id)).group_by(Lead.source).all()
leads_by_source = {row[0] or "unknown": row[1] for row in source_rows}
# Leads by industry (top 10)
industry_rows = (
base.with_entities(Lead.industry, func.count(Lead.id))
.filter(Lead.industry.isnot(None))
.group_by(Lead.industry)
.order_by(func.count(Lead.id).desc())
.limit(10)
.all()
)
leads_by_industry = {row[0]: row[1] for row in industry_rows}
# Recent leads
recent = base.order_by(Lead.created_at.desc()).limit(5).all()
# Conversion rate = converted / total
converted = leads_by_status.get("converted", 0)
conversion_rate = round((converted / total_leads * 100), 2) if total_leads > 0 else 0.0
return AnalyticsResponse(
total_leads=total_leads,
leads_by_status=leads_by_status,
leads_by_source=leads_by_source,
leads_by_industry=leads_by_industry,
recent_leads=recent,
conversion_rate=conversion_rate,
)
|