Files
ATLAS/backend/app/schemas/viaje.py
FlotillasGPS Developer 51d78bacf4 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.
2026-01-21 08:18:00 +00:00

169 lines
4.3 KiB
Python

"""
Schemas Pydantic para Viaje y Parada.
"""
from datetime import datetime
from typing import List, Optional
from pydantic import Field
from app.schemas.base import BaseSchema, TimestampSchema
class ViajeBase(BaseSchema):
"""Schema base de viaje."""
vehiculo_id: int
conductor_id: Optional[int] = None
proposito: Optional[str] = Field(None, max_length=100)
notas: Optional[str] = None
class ViajeCreate(ViajeBase):
"""Schema para crear viaje manualmente."""
inicio_tiempo: datetime
inicio_lat: float
inicio_lng: float
inicio_direccion: Optional[str] = None
class ViajeUpdate(BaseSchema):
"""Schema para actualizar viaje."""
conductor_id: Optional[int] = None
proposito: Optional[str] = Field(None, max_length=100)
notas: Optional[str] = None
estado: Optional[str] = Field(None, pattern="^(en_curso|completado|cancelado)$")
class ViajeResponse(ViajeBase, TimestampSchema):
"""Schema de respuesta de viaje."""
id: int
inicio_tiempo: datetime
fin_tiempo: Optional[datetime] = None
inicio_lat: float
inicio_lng: float
inicio_direccion: Optional[str] = None
fin_lat: Optional[float] = None
fin_lng: Optional[float] = None
fin_direccion: Optional[str] = None
distancia_km: Optional[float] = None
duracion_segundos: Optional[int] = None
tiempo_movimiento_segundos: Optional[int] = None
tiempo_parado_segundos: Optional[int] = None
velocidad_promedio: Optional[float] = None
velocidad_maxima: Optional[float] = None
combustible_usado: Optional[float] = None
rendimiento: Optional[float] = None
odometro_inicio: Optional[float] = None
odometro_fin: Optional[float] = None
estado: str
puntos_gps: int
# Calculados
duracion_formateada: str
en_curso: bool
class ViajeResumen(BaseSchema):
"""Schema resumido de viaje para listas."""
id: int
vehiculo_id: int
vehiculo_nombre: Optional[str] = None
vehiculo_placa: Optional[str] = None
conductor_nombre: Optional[str] = None
inicio_tiempo: datetime
fin_tiempo: Optional[datetime] = None
inicio_direccion: Optional[str] = None
fin_direccion: Optional[str] = None
distancia_km: Optional[float] = None
duracion_formateada: str
estado: str
class ViajeConParadas(ViajeResponse):
"""Schema de viaje con lista de paradas."""
paradas: List["ParadaResponse"] = []
class ViajeReplayData(BaseSchema):
"""Schema para datos de replay de viaje."""
viaje: ViajeResponse
ubicaciones: List["UbicacionResponse"]
paradas: List["ParadaResponse"]
# ============================================================================
# Schemas de Parada
# ============================================================================
class ParadaBase(BaseSchema):
"""Schema base de parada."""
lat: float = Field(..., ge=-90, le=90)
lng: float = Field(..., ge=-180, le=180)
tipo: str = Field(default="desconocido", max_length=50)
notas: Optional[str] = None
class ParadaCreate(ParadaBase):
"""Schema para crear parada manualmente."""
viaje_id: Optional[int] = None
vehiculo_id: int
inicio_tiempo: datetime
fin_tiempo: Optional[datetime] = None
direccion: Optional[str] = Field(None, max_length=255)
motor_apagado: Optional[bool] = None
class ParadaUpdate(BaseSchema):
"""Schema para actualizar parada."""
tipo: Optional[str] = Field(None, max_length=50)
direccion: Optional[str] = Field(None, max_length=255)
notas: Optional[str] = None
motor_apagado: Optional[bool] = None
class ParadaResponse(ParadaBase):
"""Schema de respuesta de parada."""
id: int
viaje_id: Optional[int] = None
vehiculo_id: int
inicio_tiempo: datetime
fin_tiempo: Optional[datetime] = None
duracion_segundos: Optional[int] = None
direccion: Optional[str] = None
motor_apagado: Optional[bool] = None
poi_id: Optional[int] = None
geocerca_id: Optional[int] = None
en_curso: bool
# Calculado
duracion_formateada: str
class ParadaResumen(BaseSchema):
"""Schema resumido de parada."""
id: int
vehiculo_id: int
inicio_tiempo: datetime
duracion_formateada: str
tipo: str
direccion: Optional[str] = None
# Import fix
from app.schemas.ubicacion import UbicacionResponse # noqa: E402
ViajeReplayData.model_rebuild()