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:
168
backend/app/schemas/viaje.py
Normal file
168
backend/app/schemas/viaje.py
Normal file
@@ -0,0 +1,168 @@
|
||||
"""
|
||||
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()
|
||||
Reference in New Issue
Block a user