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,198 @@
"""
Schemas Pydantic para Mantenimiento y Tipo de Mantenimiento.
"""
from datetime import date, datetime
from typing import List, Optional
from pydantic import Field
from app.schemas.base import BaseSchema, TimestampSchema
# ============================================================================
# Schemas de Tipo de Mantenimiento
# ============================================================================
class TipoMantenimientoBase(BaseSchema):
"""Schema base de tipo de mantenimiento."""
nombre: str = Field(..., min_length=2, max_length=100)
descripcion: Optional[str] = None
codigo: Optional[str] = Field(None, max_length=20)
categoria: str = Field(default="preventivo", pattern="^(preventivo|correctivo|predictivo)$")
class TipoMantenimientoCreate(TipoMantenimientoBase):
"""Schema para crear tipo de mantenimiento."""
intervalo_km: Optional[int] = Field(None, gt=0)
intervalo_dias: Optional[int] = Field(None, gt=0)
costo_estimado: Optional[float] = Field(None, ge=0)
duracion_estimada_horas: Optional[float] = Field(None, ge=0)
prioridad: int = Field(default=50, ge=1, le=100)
requiere_inmovilizacion: bool = False
class TipoMantenimientoUpdate(BaseSchema):
"""Schema para actualizar tipo de mantenimiento."""
nombre: Optional[str] = Field(None, min_length=2, max_length=100)
descripcion: Optional[str] = None
codigo: Optional[str] = Field(None, max_length=20)
categoria: Optional[str] = Field(None, pattern="^(preventivo|correctivo|predictivo)$")
intervalo_km: Optional[int] = Field(None, gt=0)
intervalo_dias: Optional[int] = Field(None, gt=0)
costo_estimado: Optional[float] = Field(None, ge=0)
duracion_estimada_horas: Optional[float] = Field(None, ge=0)
prioridad: Optional[int] = Field(None, ge=1, le=100)
requiere_inmovilizacion: Optional[bool] = None
activo: Optional[bool] = None
class TipoMantenimientoResponse(TipoMantenimientoBase, TimestampSchema):
"""Schema de respuesta de tipo de mantenimiento."""
id: int
intervalo_km: Optional[int] = None
intervalo_dias: Optional[int] = None
costo_estimado: Optional[float] = None
duracion_estimada_horas: Optional[float] = None
prioridad: int
requiere_inmovilizacion: bool
activo: bool
# ============================================================================
# Schemas de Mantenimiento
# ============================================================================
class MantenimientoBase(BaseSchema):
"""Schema base de mantenimiento."""
vehiculo_id: int
tipo_mantenimiento_id: int
fecha_programada: date
class MantenimientoCreate(MantenimientoBase):
"""Schema para crear/programar mantenimiento."""
odometro_programado: Optional[float] = Field(None, ge=0)
costo_estimado: Optional[float] = Field(None, ge=0)
proveedor: Optional[str] = Field(None, max_length=100)
proveedor_direccion: Optional[str] = Field(None, max_length=255)
proveedor_telefono: Optional[str] = Field(None, max_length=20)
descripcion: Optional[str] = None
notas: Optional[str] = None
class MantenimientoUpdate(BaseSchema):
"""Schema para actualizar mantenimiento."""
estado: Optional[str] = Field(None, pattern="^(programado|en_proceso|completado|cancelado|vencido)$")
fecha_programada: Optional[date] = None
fecha_realizada: Optional[date] = None
odometro_programado: Optional[float] = Field(None, ge=0)
odometro_realizado: Optional[float] = Field(None, ge=0)
costo_estimado: Optional[float] = Field(None, ge=0)
costo_real: Optional[float] = Field(None, ge=0)
costo_mano_obra: Optional[float] = Field(None, ge=0)
costo_refacciones: Optional[float] = Field(None, ge=0)
proveedor: Optional[str] = Field(None, max_length=100)
proveedor_direccion: Optional[str] = Field(None, max_length=255)
proveedor_telefono: Optional[str] = Field(None, max_length=20)
numero_factura: Optional[str] = Field(None, max_length=50)
numero_orden: Optional[str] = Field(None, max_length=50)
descripcion: Optional[str] = None
trabajos_realizados: Optional[str] = None
refacciones_usadas: Optional[str] = None
tecnico: Optional[str] = Field(None, max_length=100)
proximo_km: Optional[float] = Field(None, ge=0)
proxima_fecha: Optional[date] = None
notas: Optional[str] = None
class MantenimientoResponse(MantenimientoBase, TimestampSchema):
"""Schema de respuesta de mantenimiento."""
id: int
estado: str
fecha_realizada: Optional[date] = None
odometro_programado: Optional[float] = None
odometro_realizado: Optional[float] = None
costo_estimado: Optional[float] = None
costo_real: Optional[float] = None
costo_mano_obra: Optional[float] = None
costo_refacciones: Optional[float] = None
proveedor: Optional[str] = None
proveedor_direccion: Optional[str] = None
proveedor_telefono: Optional[str] = None
numero_factura: Optional[str] = None
numero_orden: Optional[str] = None
descripcion: Optional[str] = None
trabajos_realizados: Optional[str] = None
refacciones_usadas: Optional[str] = None
tecnico: Optional[str] = None
proximo_km: Optional[float] = None
proxima_fecha: Optional[date] = None
archivos_adjuntos: Optional[str] = None
recordatorio_enviado: bool
notas: Optional[str] = None
# Calculados
esta_vencido: bool
dias_para_vencimiento: Optional[int] = None
class MantenimientoConRelaciones(MantenimientoResponse):
"""Schema con información del vehículo y tipo."""
vehiculo_nombre: Optional[str] = None
vehiculo_placa: Optional[str] = None
tipo_mantenimiento_nombre: Optional[str] = None
tipo_mantenimiento_categoria: Optional[str] = None
class MantenimientoResumen(BaseSchema):
"""Schema resumido de mantenimiento."""
id: int
vehiculo_id: int
vehiculo_nombre: str
vehiculo_placa: str
tipo_mantenimiento_nombre: str
estado: str
fecha_programada: date
dias_para_vencimiento: Optional[int] = None
esta_vencido: bool
class ProximosMantenimientos(BaseSchema):
"""Schema para próximos mantenimientos."""
vencidos: List[MantenimientoResumen]
proximos_7_dias: List[MantenimientoResumen]
proximos_30_dias: List[MantenimientoResumen]
class CompletarMantenimientoRequest(BaseSchema):
"""Schema para completar un mantenimiento."""
fecha_realizada: date
odometro_realizado: Optional[float] = Field(None, ge=0)
costo_real: Optional[float] = Field(None, ge=0)
costo_mano_obra: Optional[float] = Field(None, ge=0)
costo_refacciones: Optional[float] = Field(None, ge=0)
trabajos_realizados: Optional[str] = None
refacciones_usadas: Optional[str] = None
tecnico: Optional[str] = Field(None, max_length=100)
numero_factura: Optional[str] = Field(None, max_length=50)
notas: Optional[str] = None
# Próximo mantenimiento
programar_siguiente: bool = False
proximo_km: Optional[float] = Field(None, ge=0)
proxima_fecha: Optional[date] = None