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

16
app/models/__init__.py Normal file
View File

@@ -0,0 +1,16 @@
from app.models.cliente import Cliente
from app.models.sito import Sito, TipoSito
from app.models.utente import Utente, RuoloUtente
from app.models.allarme import Allarme, SeveritaAllarme, StatoAllarme, TipoAllarme
__all__ = [
"Cliente",
"Sito",
"TipoSito",
"Utente",
"RuoloUtente",
"Allarme",
"SeveritaAllarme",
"StatoAllarme",
"TipoAllarme",
]

78
app/models/allarme.py Normal file
View File

@@ -0,0 +1,78 @@
from sqlalchemy import Column, Integer, String, DateTime, Float, ForeignKey, Enum as SQLEnum, JSON, Text
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
import enum
from app.core.database import Base
class SeveritaAllarme(str, enum.Enum):
"""Livelli di severità degli allarmi"""
CRITICAL = "critical" # Critico - richiede azione immediata
WARNING = "warning" # Avviso - richiede attenzione
INFO = "info" # Informativo
class StatoAllarme(str, enum.Enum):
"""Stati di un allarme"""
NUOVO = "nuovo"
VISUALIZZATO = "visualizzato"
IN_GESTIONE = "in_gestione"
RISOLTO = "risolto"
FALSO_POSITIVO = "falso_positivo"
class TipoAllarme(str, enum.Enum):
"""Tipologie di allarmi"""
MOVIMENTO_TERRENO = "movimento_terreno"
DEFORMAZIONE = "deformazione"
ACCELERAZIONE = "accelerazione"
INCLINAZIONE = "inclinazione"
FESSURAZIONE = "fessurazione"
VIBRAZIONE = "vibrazione"
TEMPERATURA_ANOMALA = "temperatura_anomala"
UMIDITA_ANOMALA = "umidita_anomala"
PERDITA_SEGNALE = "perdita_segnale"
BATTERIA_SCARICA = "batteria_scarica"
ALTRO = "altro"
class Allarme(Base):
"""Modello per gli allarmi generati dal sistema di monitoraggio"""
__tablename__ = "allarmi"
id = Column(Integer, primary_key=True, index=True)
sito_id = Column(Integer, ForeignKey("siti.id"), nullable=False)
# Classificazione allarme
tipo = Column(SQLEnum(TipoAllarme), nullable=False)
severita = Column(SQLEnum(SeveritaAllarme), nullable=False, index=True)
stato = Column(SQLEnum(StatoAllarme), default=StatoAllarme.NUOVO, index=True)
# Dettagli allarme
titolo = Column(String(255), nullable=False)
descrizione = Column(Text)
messaggio = Column(Text)
# Dati sensori (JSON con i valori rilevati)
dati_sensori = Column(JSON)
# Valori soglia
valore_rilevato = Column(Float)
valore_soglia = Column(Float)
unita_misura = Column(String(20))
# Metadata temporale
timestamp_rilevamento = Column(DateTime(timezone=True), nullable=False, index=True)
timestamp_notifica = Column(DateTime(timezone=True))
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# Note operative
note = Column(Text)
risolto_da = Column(String(255))
timestamp_risoluzione = Column(DateTime(timezone=True))
# Relazioni
sito = relationship("Sito", back_populates="allarmi")

27
app/models/cliente.py Normal file
View File

@@ -0,0 +1,27 @@
from sqlalchemy import Column, Integer, String, DateTime, Boolean
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from app.core.database import Base
class Cliente(Base):
"""Modello per i clienti che possiedono siti monitorati"""
__tablename__ = "clienti"
id = Column(Integer, primary_key=True, index=True)
nome = Column(String(255), nullable=False)
ragione_sociale = Column(String(255))
codice_fiscale = Column(String(16), unique=True)
partita_iva = Column(String(11), unique=True)
email = Column(String(255), nullable=False)
telefono = Column(String(20))
indirizzo = Column(String(500))
attivo = Column(Boolean, default=True)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# Relazioni
siti = relationship("Sito", back_populates="cliente", cascade="all, delete-orphan")
utenti = relationship("Utente", back_populates="cliente", cascade="all, delete-orphan")

49
app/models/sito.py Normal file
View File

@@ -0,0 +1,49 @@
from sqlalchemy import Column, Integer, String, DateTime, Float, ForeignKey, Enum as SQLEnum
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
import enum
from app.core.database import Base
class TipoSito(str, enum.Enum):
"""Tipi di siti monitorati"""
FRANA = "frana"
GALLERIA = "galleria"
PONTE = "ponte"
DIGA = "diga"
VERSANTE = "versante"
EDIFICIO = "edificio"
ALTRO = "altro"
class Sito(Base):
"""Modello per i siti monitorati"""
__tablename__ = "siti"
id = Column(Integer, primary_key=True, index=True)
cliente_id = Column(Integer, ForeignKey("clienti.id"), nullable=False)
nome = Column(String(255), nullable=False)
tipo = Column(SQLEnum(TipoSito), nullable=False)
descrizione = Column(String(1000))
# Coordinate geografiche
latitudine = Column(Float)
longitudine = Column(Float)
altitudine = Column(Float)
# Indirizzo
indirizzo = Column(String(500))
comune = Column(String(100))
provincia = Column(String(2))
regione = Column(String(100))
# Metadata
codice_identificativo = Column(String(50), unique=True, index=True)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# Relazioni
cliente = relationship("Cliente", back_populates="siti")
allarmi = relationship("Allarme", back_populates="sito", cascade="all, delete-orphan")

43
app/models/utente.py Normal file
View File

@@ -0,0 +1,43 @@
from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey, Enum as SQLEnum
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
import enum
from app.core.database import Base
class RuoloUtente(str, enum.Enum):
"""Ruoli utente nell'applicazione"""
ADMIN = "admin"
OPERATORE = "operatore"
VISUALIZZATORE = "visualizzatore"
class Utente(Base):
"""Modello per gli utenti dell'applicazione"""
__tablename__ = "utenti"
id = Column(Integer, primary_key=True, index=True)
cliente_id = Column(Integer, ForeignKey("clienti.id"), nullable=False)
email = Column(String(255), unique=True, nullable=False, index=True)
password_hash = Column(String(255), nullable=False)
nome = Column(String(100), nullable=False)
cognome = Column(String(100), nullable=False)
telefono = Column(String(20))
ruolo = Column(SQLEnum(RuoloUtente), default=RuoloUtente.VISUALIZZATORE)
# FCM token per notifiche push
fcm_token = Column(String(500))
# Flags
attivo = Column(Boolean, default=True)
email_verificata = Column(Boolean, default=False)
# Metadata
ultimo_accesso = Column(DateTime(timezone=True))
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# Relazioni
cliente = relationship("Cliente", back_populates="utenti")