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:
249
backend/app/models/configuracion.py
Normal file
249
backend/app/models/configuracion.py
Normal file
@@ -0,0 +1,249 @@
|
||||
"""
|
||||
Modelo de Configuración para almacenar settings del sistema.
|
||||
"""
|
||||
|
||||
from sqlalchemy import String, Text
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
from app.core.database import Base
|
||||
from app.models.base import TimestampMixin
|
||||
|
||||
|
||||
class Configuracion(Base, TimestampMixin):
|
||||
"""
|
||||
Modelo para almacenar configuraciones del sistema.
|
||||
|
||||
Permite guardar configuraciones dinámicas sin necesidad
|
||||
de reiniciar la aplicación.
|
||||
"""
|
||||
|
||||
__tablename__ = "configuraciones"
|
||||
|
||||
clave: Mapped[str] = mapped_column(String(100), primary_key=True)
|
||||
valor_json: Mapped[str] = mapped_column(Text, nullable=False) # Valor en formato JSON
|
||||
categoria: Mapped[str] = mapped_column(
|
||||
String(50),
|
||||
default="general",
|
||||
nullable=False,
|
||||
index=True,
|
||||
)
|
||||
descripcion: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
|
||||
# Tipo de dato para validación
|
||||
tipo_dato: Mapped[str] = mapped_column(
|
||||
String(20),
|
||||
default="string",
|
||||
nullable=False,
|
||||
) # string, number, boolean, json, array
|
||||
|
||||
# Si la configuración es sensible (no mostrar en logs)
|
||||
sensible: Mapped[bool] = mapped_column(default=False, nullable=False)
|
||||
|
||||
# Si puede ser modificada desde la UI
|
||||
editable: Mapped[bool] = mapped_column(default=True, nullable=False)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<Configuracion(clave='{self.clave}', categoria='{self.categoria}')>"
|
||||
|
||||
def get_value(self):
|
||||
"""Parsea y retorna el valor según su tipo."""
|
||||
import json
|
||||
if self.tipo_dato == "string":
|
||||
return json.loads(self.valor_json)
|
||||
elif self.tipo_dato == "number":
|
||||
return float(json.loads(self.valor_json))
|
||||
elif self.tipo_dato == "boolean":
|
||||
return bool(json.loads(self.valor_json))
|
||||
else:
|
||||
return json.loads(self.valor_json)
|
||||
|
||||
|
||||
# Configuraciones por defecto del sistema
|
||||
CONFIGURACIONES_DEFAULT = [
|
||||
# Alertas
|
||||
{
|
||||
"clave": "alerta_velocidad_maxima",
|
||||
"valor_json": "120",
|
||||
"categoria": "alertas",
|
||||
"descripcion": "Velocidad máxima permitida (km/h) antes de generar alerta",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
{
|
||||
"clave": "alerta_parada_minutos",
|
||||
"valor_json": "15",
|
||||
"categoria": "alertas",
|
||||
"descripcion": "Minutos de parada para considerar como parada prolongada",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
{
|
||||
"clave": "alerta_bateria_minima",
|
||||
"valor_json": "20",
|
||||
"categoria": "alertas",
|
||||
"descripcion": "Porcentaje mínimo de batería antes de alertar",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
{
|
||||
"clave": "alerta_sin_señal_minutos",
|
||||
"valor_json": "30",
|
||||
"categoria": "alertas",
|
||||
"descripcion": "Minutos sin señal para generar alerta",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
{
|
||||
"clave": "alerta_motor_encendido_minutos",
|
||||
"valor_json": "10",
|
||||
"categoria": "alertas",
|
||||
"descripcion": "Minutos con motor encendido sin movimiento para alertar",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
|
||||
# Viajes
|
||||
{
|
||||
"clave": "viaje_velocidad_minima",
|
||||
"valor_json": "5",
|
||||
"categoria": "viajes",
|
||||
"descripcion": "Velocidad mínima (km/h) para considerar movimiento",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
{
|
||||
"clave": "viaje_parada_minutos",
|
||||
"valor_json": "5",
|
||||
"categoria": "viajes",
|
||||
"descripcion": "Minutos de parada para finalizar un viaje automáticamente",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
|
||||
# Paradas
|
||||
{
|
||||
"clave": "parada_duracion_minima",
|
||||
"valor_json": "120",
|
||||
"categoria": "paradas",
|
||||
"descripcion": "Segundos mínimos para registrar una parada",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
|
||||
# Combustible
|
||||
{
|
||||
"clave": "combustible_precio_gasolina",
|
||||
"valor_json": "22.50",
|
||||
"categoria": "combustible",
|
||||
"descripcion": "Precio por defecto del litro de gasolina",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
{
|
||||
"clave": "combustible_precio_diesel",
|
||||
"valor_json": "23.80",
|
||||
"categoria": "combustible",
|
||||
"descripcion": "Precio por defecto del litro de diesel",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
|
||||
# Mantenimiento
|
||||
{
|
||||
"clave": "mantenimiento_recordatorio_dias",
|
||||
"valor_json": "7",
|
||||
"categoria": "mantenimiento",
|
||||
"descripcion": "Días de anticipación para recordatorio de mantenimiento",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
{
|
||||
"clave": "mantenimiento_recordatorio_km",
|
||||
"valor_json": "500",
|
||||
"categoria": "mantenimiento",
|
||||
"descripcion": "Km de anticipación para recordatorio de mantenimiento",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
|
||||
# Notificaciones
|
||||
{
|
||||
"clave": "notificaciones_email_habilitado",
|
||||
"valor_json": "true",
|
||||
"categoria": "notificaciones",
|
||||
"descripcion": "Habilitar notificaciones por email",
|
||||
"tipo_dato": "boolean",
|
||||
},
|
||||
{
|
||||
"clave": "notificaciones_push_habilitado",
|
||||
"valor_json": "true",
|
||||
"categoria": "notificaciones",
|
||||
"descripcion": "Habilitar notificaciones push",
|
||||
"tipo_dato": "boolean",
|
||||
},
|
||||
{
|
||||
"clave": "notificaciones_destinatarios",
|
||||
"valor_json": '["admin@adan-fleet.com"]',
|
||||
"categoria": "notificaciones",
|
||||
"descripcion": "Lista de emails para notificaciones críticas",
|
||||
"tipo_dato": "array",
|
||||
"sensible": True,
|
||||
},
|
||||
|
||||
# Mapas
|
||||
{
|
||||
"clave": "mapa_centro_lat",
|
||||
"valor_json": "19.4326",
|
||||
"categoria": "mapas",
|
||||
"descripcion": "Latitud del centro del mapa por defecto",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
{
|
||||
"clave": "mapa_centro_lng",
|
||||
"valor_json": "-99.1332",
|
||||
"categoria": "mapas",
|
||||
"descripcion": "Longitud del centro del mapa por defecto",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
{
|
||||
"clave": "mapa_zoom_default",
|
||||
"valor_json": "12",
|
||||
"categoria": "mapas",
|
||||
"descripcion": "Nivel de zoom inicial del mapa",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
|
||||
# Retención de datos
|
||||
{
|
||||
"clave": "retencion_ubicaciones_dias",
|
||||
"valor_json": "365",
|
||||
"categoria": "retencion",
|
||||
"descripcion": "Días de retención de ubicaciones GPS",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
{
|
||||
"clave": "retencion_alertas_dias",
|
||||
"valor_json": "180",
|
||||
"categoria": "retencion",
|
||||
"descripcion": "Días de retención de alertas",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
{
|
||||
"clave": "retencion_videos_dias",
|
||||
"valor_json": "30",
|
||||
"categoria": "retencion",
|
||||
"descripcion": "Días de retención de videos",
|
||||
"tipo_dato": "number",
|
||||
},
|
||||
|
||||
# General
|
||||
{
|
||||
"clave": "empresa_nombre",
|
||||
"valor_json": '"Adan Fleet"',
|
||||
"categoria": "general",
|
||||
"descripcion": "Nombre de la empresa",
|
||||
"tipo_dato": "string",
|
||||
},
|
||||
{
|
||||
"clave": "empresa_logo_url",
|
||||
"valor_json": '""',
|
||||
"categoria": "general",
|
||||
"descripcion": "URL del logo de la empresa",
|
||||
"tipo_dato": "string",
|
||||
},
|
||||
{
|
||||
"clave": "zona_horaria",
|
||||
"valor_json": '"America/Mexico_City"',
|
||||
"categoria": "general",
|
||||
"descripcion": "Zona horaria del sistema",
|
||||
"tipo_dato": "string",
|
||||
},
|
||||
]
|
||||
Reference in New Issue
Block a user