FlotillasGPS - Sistema completo de monitoreo de flotillas GPS

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.
This commit is contained in:
FlotillasGPS Developer
2026-01-21 08:18:00 +00:00
commit 51d78bacf4
248 changed files with 50171 additions and 0 deletions

View File

@@ -0,0 +1,172 @@
"""
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