Sistema completo para monitoreo y gestion de flotas de vehiculos con: - Backend FastAPI con PostgreSQL/TimescaleDB - Frontend React con TypeScript y TailwindCSS - App movil React Native con Expo - Soporte para dispositivos GPS, Meshtastic y celulares - Video streaming en vivo con MediaMTX - Geocercas, alertas, viajes y reportes - Autenticacion JWT y WebSockets en tiempo real Documentacion completa y guias de usuario incluidas.
173 lines
4.9 KiB
Python
173 lines
4.9 KiB
Python
"""
|
|
Schemas Pydantic para Alerta y Tipo de Alerta.
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from typing import List, Optional
|
|
|
|
from pydantic import Field
|
|
|
|
from app.schemas.base import BaseSchema, TimestampSchema
|
|
|
|
|
|
# ============================================================================
|
|
# Schemas de Tipo de Alerta
|
|
# ============================================================================
|
|
|
|
|
|
class TipoAlertaBase(BaseSchema):
|
|
"""Schema base de tipo de alerta."""
|
|
|
|
codigo: str = Field(..., min_length=2, max_length=50)
|
|
nombre: str = Field(..., min_length=2, max_length=100)
|
|
descripcion: Optional[str] = None
|
|
severidad_default: str = Field(default="media", pattern="^(baja|media|alta|critica)$")
|
|
icono: Optional[str] = Field(None, max_length=50)
|
|
color: str = Field(default="#EF4444", pattern=r"^#[0-9A-Fa-f]{6}$")
|
|
|
|
|
|
class TipoAlertaCreate(TipoAlertaBase):
|
|
"""Schema para crear tipo de alerta."""
|
|
|
|
notificar_email: bool = False
|
|
notificar_push: bool = True
|
|
notificar_sms: bool = False
|
|
prioridad: int = Field(default=50, ge=1, le=100)
|
|
|
|
|
|
class TipoAlertaUpdate(BaseSchema):
|
|
"""Schema para actualizar tipo de alerta."""
|
|
|
|
nombre: Optional[str] = Field(None, min_length=2, max_length=100)
|
|
descripcion: Optional[str] = None
|
|
severidad_default: Optional[str] = Field(None, pattern="^(baja|media|alta|critica)$")
|
|
icono: Optional[str] = Field(None, max_length=50)
|
|
color: Optional[str] = Field(None, pattern=r"^#[0-9A-Fa-f]{6}$")
|
|
notificar_email: Optional[bool] = None
|
|
notificar_push: Optional[bool] = None
|
|
notificar_sms: Optional[bool] = None
|
|
prioridad: Optional[int] = Field(None, ge=1, le=100)
|
|
activo: Optional[bool] = None
|
|
|
|
|
|
class TipoAlertaResponse(TipoAlertaBase, TimestampSchema):
|
|
"""Schema de respuesta de tipo de alerta."""
|
|
|
|
id: int
|
|
notificar_email: bool
|
|
notificar_push: bool
|
|
notificar_sms: bool
|
|
prioridad: int
|
|
activo: bool
|
|
|
|
|
|
# ============================================================================
|
|
# Schemas de Alerta
|
|
# ============================================================================
|
|
|
|
|
|
class AlertaBase(BaseSchema):
|
|
"""Schema base de alerta."""
|
|
|
|
tipo_alerta_id: int
|
|
severidad: str = Field(default="media", pattern="^(baja|media|alta|critica)$")
|
|
mensaje: str = Field(..., min_length=5, max_length=500)
|
|
descripcion: Optional[str] = None
|
|
|
|
|
|
class AlertaCreate(AlertaBase):
|
|
"""Schema para crear alerta manualmente."""
|
|
|
|
vehiculo_id: Optional[int] = None
|
|
conductor_id: Optional[int] = None
|
|
dispositivo_id: Optional[int] = None
|
|
lat: Optional[float] = Field(None, ge=-90, le=90)
|
|
lng: Optional[float] = Field(None, ge=-180, le=180)
|
|
direccion: Optional[str] = Field(None, max_length=255)
|
|
velocidad: Optional[float] = Field(None, ge=0)
|
|
valor: Optional[float] = None
|
|
umbral: Optional[float] = None
|
|
datos_extra: Optional[str] = None # JSON
|
|
|
|
|
|
class AlertaUpdate(BaseSchema):
|
|
"""Schema para actualizar alerta (marcar atendida)."""
|
|
|
|
atendida: Optional[bool] = None
|
|
notas_atencion: Optional[str] = None
|
|
|
|
|
|
class AlertaResponse(AlertaBase, TimestampSchema):
|
|
"""Schema de respuesta de alerta."""
|
|
|
|
id: int
|
|
vehiculo_id: Optional[int] = None
|
|
conductor_id: Optional[int] = None
|
|
dispositivo_id: Optional[int] = None
|
|
lat: Optional[float] = None
|
|
lng: Optional[float] = None
|
|
direccion: Optional[str] = None
|
|
velocidad: Optional[float] = None
|
|
valor: Optional[float] = None
|
|
umbral: Optional[float] = None
|
|
datos_extra: Optional[str] = None
|
|
atendida: bool
|
|
atendida_por_id: Optional[int] = None
|
|
atendida_en: Optional[datetime] = None
|
|
notas_atencion: Optional[str] = None
|
|
notificacion_email_enviada: bool
|
|
notificacion_push_enviada: bool
|
|
notificacion_sms_enviada: bool
|
|
|
|
# Calculado
|
|
es_critica: bool
|
|
|
|
|
|
class AlertaConTipo(AlertaResponse):
|
|
"""Schema de alerta con información del tipo."""
|
|
|
|
tipo_alerta: TipoAlertaResponse
|
|
|
|
|
|
class AlertaConRelaciones(AlertaResponse):
|
|
"""Schema de alerta con todas las relaciones."""
|
|
|
|
tipo_alerta: TipoAlertaResponse
|
|
vehiculo_nombre: Optional[str] = None
|
|
vehiculo_placa: Optional[str] = None
|
|
conductor_nombre: Optional[str] = None
|
|
|
|
|
|
class AlertaResumen(BaseSchema):
|
|
"""Schema resumido de alerta para listas."""
|
|
|
|
id: int
|
|
tipo_codigo: str
|
|
tipo_nombre: str
|
|
severidad: str
|
|
mensaje: str
|
|
vehiculo_nombre: Optional[str] = None
|
|
vehiculo_placa: Optional[str] = None
|
|
creado_en: datetime
|
|
atendida: bool
|
|
|
|
|
|
class AlertasEstadisticas(BaseSchema):
|
|
"""Estadísticas de alertas."""
|
|
|
|
total: int
|
|
pendientes: int
|
|
atendidas: int
|
|
criticas: int
|
|
altas: int
|
|
medias: int
|
|
bajas: int
|
|
por_tipo: List[dict] # [{codigo, nombre, cantidad}]
|
|
por_vehiculo: List[dict] # [{vehiculo_id, nombre, cantidad}]
|
|
|
|
|
|
class AlertaAtenderRequest(BaseSchema):
|
|
"""Schema para marcar alerta como atendida."""
|
|
|
|
notas_atencion: Optional[str] = None
|