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,105 @@
"""
Schemas Pydantic para Mensaje.
"""
from datetime import datetime
from typing import List, Optional
from pydantic import Field
from app.schemas.base import BaseSchema, TimestampSchema
class MensajeBase(BaseSchema):
"""Schema base de mensaje."""
asunto: Optional[str] = Field(None, max_length=200)
contenido: str = Field(..., min_length=1)
class MensajeCreate(MensajeBase):
"""Schema para crear/enviar mensaje."""
conductor_id: int
tipo: str = Field(default="texto", pattern="^(texto|alerta|instruccion|emergencia)$")
prioridad: str = Field(default="normal", pattern="^(baja|normal|alta|urgente)$")
adjuntos: Optional[List[str]] = None # Lista de URLs
class MensajeEnviarAConductores(BaseSchema):
"""Schema para enviar mensaje a múltiples conductores."""
conductores_ids: List[int]
asunto: Optional[str] = Field(None, max_length=200)
contenido: str = Field(..., min_length=1)
tipo: str = Field(default="texto", pattern="^(texto|alerta|instruccion|emergencia)$")
prioridad: str = Field(default="normal", pattern="^(baja|normal|alta|urgente)$")
class MensajeUpdate(BaseSchema):
"""Schema para actualizar mensaje."""
leido: Optional[bool] = None
eliminado_por_admin: Optional[bool] = None
eliminado_por_conductor: Optional[bool] = None
class MensajeResponse(MensajeBase, TimestampSchema):
"""Schema de respuesta de mensaje."""
id: int
conductor_id: int
de_admin: bool
usuario_id: Optional[int] = None
tipo: str
prioridad: str
leido: bool
leido_en: Optional[datetime] = None
adjuntos: Optional[str] = None
respuesta_a_id: Optional[int] = None
eliminado_por_admin: bool
eliminado_por_conductor: bool
class MensajeConConductor(MensajeResponse):
"""Schema con información del conductor."""
conductor_nombre: Optional[str] = None
usuario_nombre: Optional[str] = None
class MensajeResumen(BaseSchema):
"""Schema resumido de mensaje."""
id: int
conductor_id: int
conductor_nombre: str
de_admin: bool
asunto: Optional[str] = None
tipo: str
prioridad: str
leido: bool
creado_en: datetime
class ConversacionConductor(BaseSchema):
"""Schema para conversación con un conductor."""
conductor_id: int
conductor_nombre: str
mensajes: List[MensajeResponse]
no_leidos: int
class MensajesNoLeidosResponse(BaseSchema):
"""Schema con conteo de mensajes no leídos."""
total_no_leidos: int
por_conductor: List[dict] # [{conductor_id, nombre, cantidad}]
class ResponderMensajeRequest(BaseSchema):
"""Schema para responder a un mensaje."""
contenido: str = Field(..., min_length=1)
adjuntos: Optional[List[str]] = None