OCR + reportistica

This commit is contained in:
2026-03-27 13:54:07 +01:00
parent cbeedc2d2f
commit bb2060c1ae
26 changed files with 5503 additions and 237 deletions
+75
View File
@@ -0,0 +1,75 @@
"""
Schemi Pydantic per la Dashboard e Reportistica (Fase 7).
"""
from datetime import date, datetime
from typing import Optional
import uuid
from pydantic import BaseModel, Field
class KpiSummary(BaseModel):
"""Contatori KPI principali del tenant."""
# Oggi
received_today: int = Field(0, description="PEC ricevute oggi")
sent_today: int = Field(0, description="PEC inviate oggi (outbound)")
# Ultimi 7 giorni
received_7d: int = Field(0, description="PEC ricevute negli ultimi 7 giorni")
sent_7d: int = Field(0, description="PEC inviate negli ultimi 7 giorni")
# Ultimi 30 giorni
received_30d: int = Field(0, description="PEC ricevute negli ultimi 30 giorni")
sent_30d: int = Field(0, description="PEC inviate negli ultimi 30 giorni")
# Stato
anomalie_attive: int = Field(0, description="Messaggi outbound in stato anomaly")
tasso_consegna: float = Field(0.0, description="Percentuale consegna (0-100)")
caselle_in_errore: int = Field(0, description="Caselle con status=error")
messaggi_non_letti: int = Field(0, description="Messaggi inbound non letti")
# Totali assoluti
totale_messaggi: int = Field(0, description="Totale messaggi nel tenant")
class DailyStat(BaseModel):
"""Statistiche giornaliere per il grafico a barre."""
day: date = Field(..., description="Data (YYYY-MM-DD)")
received: int = Field(0, description="PEC ricevute in quel giorno")
sent: int = Field(0, description="PEC inviate in quel giorno")
class OutboundStateStat(BaseModel):
"""Conteggio messaggi outbound per stato (per il grafico a torta)."""
state: str
count: int
class MailboxStat(BaseModel):
"""Statistiche per singola casella."""
mailbox_id: uuid.UUID
email_address: str
display_name: Optional[str] = None
status: str
received_total: int = 0
sent_total: int = 0
anomalie: int = 0
non_letti: int = 0
last_sync_at: Optional[datetime] = None
class ReportSummaryResponse(BaseModel):
"""Risposta completa dell'endpoint /reports/summary."""
generated_at: datetime
period_days: int = Field(..., description="Numero di giorni del periodo selezionato")
kpi: KpiSummary
daily_stats: list[DailyStat] = Field(default_factory=list)
outbound_states: list[OutboundStateStat] = Field(default_factory=list)
mailbox_stats: list[MailboxStat] = Field(default_factory=list)