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

120
backend/app/schemas/poi.py Normal file
View File

@@ -0,0 +1,120 @@
"""
Schemas Pydantic para POI (Punto de Interés).
"""
from typing import List, Optional
from pydantic import EmailStr, Field
from app.schemas.base import BaseSchema, TimestampSchema
class POIBase(BaseSchema):
"""Schema base de POI."""
nombre: str = Field(..., min_length=2, max_length=100)
descripcion: Optional[str] = None
categoria: str = Field(default="otro", max_length=50)
lat: float = Field(..., ge=-90, le=90)
lng: float = Field(..., ge=-180, le=180)
direccion: Optional[str] = Field(None, max_length=255)
ciudad: Optional[str] = Field(None, max_length=100)
estado: Optional[str] = Field(None, max_length=100)
codigo_postal: Optional[str] = Field(None, max_length=10)
radio_metros: float = Field(default=100.0, gt=0, le=10000)
class POICreate(POIBase):
"""Schema para crear POI."""
telefono: Optional[str] = Field(None, max_length=20)
email: Optional[EmailStr] = None
contacto_nombre: Optional[str] = Field(None, max_length=100)
horario_json: Optional[str] = None
icono: Optional[str] = Field(None, max_length=50)
color: str = Field(default="#10B981", pattern=r"^#[0-9A-Fa-f]{6}$")
codigo_externo: Optional[str] = Field(None, max_length=50)
notas: Optional[str] = None
class POIUpdate(BaseSchema):
"""Schema para actualizar POI."""
nombre: Optional[str] = Field(None, min_length=2, max_length=100)
descripcion: Optional[str] = None
categoria: Optional[str] = Field(None, max_length=50)
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)
ciudad: Optional[str] = Field(None, max_length=100)
estado: Optional[str] = Field(None, max_length=100)
codigo_postal: Optional[str] = Field(None, max_length=10)
radio_metros: Optional[float] = Field(None, gt=0, le=10000)
telefono: Optional[str] = Field(None, max_length=20)
email: Optional[EmailStr] = None
contacto_nombre: Optional[str] = Field(None, max_length=100)
horario_json: Optional[str] = None
icono: Optional[str] = Field(None, max_length=50)
color: Optional[str] = Field(None, pattern=r"^#[0-9A-Fa-f]{6}$")
codigo_externo: Optional[str] = Field(None, max_length=50)
activo: Optional[bool] = None
notas: Optional[str] = None
class POIResponse(POIBase, TimestampSchema):
"""Schema de respuesta de POI."""
id: int
telefono: Optional[str] = None
email: Optional[str] = None
contacto_nombre: Optional[str] = None
horario_json: Optional[str] = None
icono: Optional[str] = None
color: str
codigo_externo: Optional[str] = None
activo: bool
notas: Optional[str] = None
class POIResumen(BaseSchema):
"""Schema resumido de POI."""
id: int
nombre: str
categoria: str
lat: float
lng: float
icono: Optional[str] = None
color: str
class POICercano(POIResumen):
"""Schema de POI con distancia."""
distancia_metros: float
class BuscarPOIsCercanosRequest(BaseSchema):
"""Schema para buscar POIs cercanos."""
lat: float = Field(..., ge=-90, le=90)
lng: float = Field(..., ge=-180, le=180)
radio_metros: float = Field(default=1000, gt=0, le=50000)
categoria: Optional[str] = None
limite: int = Field(default=10, ge=1, le=100)
class BuscarPOIsCercanosResponse(BaseSchema):
"""Schema de respuesta de búsqueda de POIs cercanos."""
centro_lat: float
centro_lng: float
radio_metros: float
total: int
pois: List[POICercano]
class CategoriasPOIResponse(BaseSchema):
"""Schema de respuesta con categorías de POI."""
categorias: List[dict] # [{codigo, nombre, icono, color}]