128 lines
4.0 KiB
Python
128 lines
4.0 KiB
Python
"""
|
|
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}
|