app backend prima

This commit is contained in:
2025-10-20 19:10:08 +02:00
commit 438255d27b
42 changed files with 4622 additions and 0 deletions

127
app/api/statistiche.py Normal file
View File

@@ -0,0 +1,127 @@
"""
Endpoint API per statistiche e dashboard
"""
from datetime import datetime, timedelta
from fastapi import APIRouter, Depends
from sqlalchemy import func
from sqlalchemy.orm import Session
from app.core.database import get_db
from app.models import Allarme, Sito, Utente
from app.api.auth import get_current_user
from app.schemas.statistiche import StatisticheResponse, AllarmiPerGiornoResponse
router = APIRouter(prefix="/statistiche", tags=["statistiche"])
@router.get("", response_model=StatisticheResponse)
async def get_statistiche(
current_user: Utente = Depends(get_current_user),
db: Session = Depends(get_db),
):
"""Recupera statistiche generali per il dashboard"""
# Totali
totale_allarmi = db.query(Allarme).join(Sito).filter(
Sito.cliente_id == current_user.cliente_id
).count()
totale_siti = db.query(Sito).filter(
Sito.cliente_id == current_user.cliente_id
).count()
# Allarmi per severità
allarmi_per_severita = db.query(
Allarme.severita,
func.count(Allarme.id).label('count')
).join(Sito).filter(
Sito.cliente_id == current_user.cliente_id
).group_by(Allarme.severita).all()
severita_dict = {s: c for s, c in allarmi_per_severita}
# Allarmi per stato
allarmi_per_stato = db.query(
Allarme.stato,
func.count(Allarme.id).label('count')
).join(Sito).filter(
Sito.cliente_id == current_user.cliente_id
).group_by(Allarme.stato).all()
stato_dict = {s: c for s, c in allarmi_per_stato}
# Allarmi aperti (non risolti)
allarmi_aperti = db.query(Allarme).join(Sito).filter(
Sito.cliente_id == current_user.cliente_id,
Allarme.stato != 'risolto'
).count()
# Allarmi ultimi 7 giorni
seven_days_ago = datetime.now() - timedelta(days=7)
allarmi_recenti = db.query(Allarme).join(Sito).filter(
Sito.cliente_id == current_user.cliente_id,
Allarme.created_at >= seven_days_ago
).count()
# Siti per tipo
siti_per_tipo = db.query(
Sito.tipo,
func.count(Sito.id).label('count')
).filter(
Sito.cliente_id == current_user.cliente_id
).group_by(Sito.tipo).all()
tipo_dict = {t: c for t, c in siti_per_tipo}
return {
"totale_allarmi": totale_allarmi,
"totale_siti": totale_siti,
"allarmi_aperti": allarmi_aperti,
"allarmi_recenti_7gg": allarmi_recenti,
"allarmi_critical": severita_dict.get('critical', 0),
"allarmi_warning": severita_dict.get('warning', 0),
"allarmi_info": severita_dict.get('info', 0),
"allarmi_nuovo": stato_dict.get('nuovo', 0),
"allarmi_in_gestione": stato_dict.get('in_gestione', 0),
"allarmi_risolto": stato_dict.get('risolto', 0),
"siti_ponte": tipo_dict.get('ponte', 0),
"siti_galleria": tipo_dict.get('galleria', 0),
"siti_diga": tipo_dict.get('diga', 0),
"siti_frana": tipo_dict.get('frana', 0),
"siti_versante": tipo_dict.get('versante', 0),
"siti_edificio": tipo_dict.get('edificio', 0),
}
@router.get("/allarmi-per-giorno", response_model=AllarmiPerGiornoResponse)
async def get_allarmi_per_giorno(
giorni: int = 30,
current_user: Utente = Depends(get_current_user),
db: Session = Depends(get_db),
):
"""Recupera statistiche allarmi per giorno (per grafici temporali)"""
start_date = datetime.now() - timedelta(days=giorni)
# Query allarmi raggruppati per giorno
allarmi_giornalieri = db.query(
func.date(Allarme.created_at).label('data'),
func.count(Allarme.id).label('count')
).join(Sito).filter(
Sito.cliente_id == current_user.cliente_id,
Allarme.created_at >= start_date
).group_by(
func.date(Allarme.created_at)
).order_by(
func.date(Allarme.created_at)
).all()
# Converti in lista di dict
dati = []
for data, count in allarmi_giornalieri:
dati.append({
"data": data.isoformat(),
"count": count
})
return {"dati": dati}