feat: Complete ATLAS system installation and API fixes
## Backend Changes - Add new API endpoints: combustible, pois, mantenimiento, video, configuracion - Fix vehiculos endpoint to return paginated response with items array - Add /vehiculos/all endpoint for non-paginated list - Add /geocercas/all endpoint - Add /alertas/configuracion GET/PUT endpoints - Add /viajes/activos and /viajes/iniciar endpoints - Add /reportes/stats, /reportes/templates, /reportes/preview endpoints - Add /conductores/all and /conductores/disponibles endpoints - Update router.py to include all new modules ## Frontend Changes - Fix authentication token handling (snake_case vs camelCase) - Update vehiculosApi.listAll to use /vehiculos/all - Fix FuelGauge component usage in Combustible page - Fix chart component exports (named + default exports) - Update API client for proper token refresh ## Infrastructure - Rename services from ADAN to ATLAS - Configure Cloudflare tunnel for atlas.consultoria-as.com - Update systemd service files - Configure PostgreSQL with TimescaleDB - Configure Redis, Mosquitto, Traccar, MediaMTX ## Documentation - Update installation guides - Update API reference - Rename all ADAN references to ATLAS Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,7 @@ from app.core.security import (
|
||||
CurrentAdmin,
|
||||
)
|
||||
from app.core.exceptions import (
|
||||
AdanException,
|
||||
AtlasException,
|
||||
NotFoundError,
|
||||
AlreadyExistsError,
|
||||
ValidationError,
|
||||
@@ -45,7 +45,7 @@ __all__ = [
|
||||
"CurrentUser",
|
||||
"CurrentAdmin",
|
||||
# Exceptions
|
||||
"AdanException",
|
||||
"AtlasException",
|
||||
"NotFoundError",
|
||||
"AlreadyExistsError",
|
||||
"ValidationError",
|
||||
|
||||
@@ -23,7 +23,7 @@ class Settings(BaseSettings):
|
||||
)
|
||||
|
||||
# Aplicación
|
||||
APP_NAME: str = "Adan Fleet Monitor"
|
||||
APP_NAME: str = "Atlas Fleet Monitor"
|
||||
APP_VERSION: str = "1.0.0"
|
||||
DEBUG: bool = False
|
||||
ENVIRONMENT: str = "development"
|
||||
@@ -37,9 +37,9 @@ class Settings(BaseSettings):
|
||||
# Base de datos PostgreSQL/TimescaleDB
|
||||
POSTGRES_HOST: str = "localhost"
|
||||
POSTGRES_PORT: int = 5432
|
||||
POSTGRES_USER: str = "adan"
|
||||
POSTGRES_PASSWORD: str = "adan_secret"
|
||||
POSTGRES_DB: str = "adan_fleet"
|
||||
POSTGRES_USER: str = "atlas"
|
||||
POSTGRES_PASSWORD: str = "atlas_secret"
|
||||
POSTGRES_DB: str = "atlas_fleet"
|
||||
DATABASE_URL: Optional[str] = None
|
||||
DATABASE_POOL_SIZE: int = 20
|
||||
DATABASE_MAX_OVERFLOW: int = 10
|
||||
@@ -114,16 +114,16 @@ class Settings(BaseSettings):
|
||||
MQTT_PORT: int = 1883
|
||||
MQTT_USERNAME: Optional[str] = None
|
||||
MQTT_PASSWORD: Optional[str] = None
|
||||
MQTT_TOPIC_LOCATIONS: str = "adan/locations/#"
|
||||
MQTT_TOPIC_ALERTS: str = "adan/alerts/#"
|
||||
MQTT_TOPIC_LOCATIONS: str = "atlas/locations/#"
|
||||
MQTT_TOPIC_ALERTS: str = "atlas/alerts/#"
|
||||
|
||||
# Email (notificaciones)
|
||||
SMTP_HOST: str = "localhost"
|
||||
SMTP_PORT: int = 587
|
||||
SMTP_USER: Optional[str] = None
|
||||
SMTP_PASSWORD: Optional[str] = None
|
||||
SMTP_FROM_EMAIL: str = "noreply@adan-fleet.com"
|
||||
SMTP_FROM_NAME: str = "Adan Fleet Monitor"
|
||||
SMTP_FROM_EMAIL: str = "noreply@atlas-fleet.com"
|
||||
SMTP_FROM_NAME: str = "Atlas Fleet Monitor"
|
||||
SMTP_TLS: bool = True
|
||||
|
||||
# Push Notifications (Firebase)
|
||||
@@ -131,13 +131,13 @@ class Settings(BaseSettings):
|
||||
FIREBASE_ENABLED: bool = False
|
||||
|
||||
# Almacenamiento de archivos
|
||||
UPLOAD_DIR: str = "/var/lib/adan/uploads"
|
||||
UPLOAD_DIR: str = "/var/lib/atlas/uploads"
|
||||
MAX_UPLOAD_SIZE_MB: int = 100
|
||||
ALLOWED_IMAGE_TYPES: List[str] = ["image/jpeg", "image/png", "image/webp"]
|
||||
ALLOWED_VIDEO_TYPES: List[str] = ["video/mp4", "video/webm"]
|
||||
|
||||
# Reportes
|
||||
REPORTS_DIR: str = "/var/lib/adan/reports"
|
||||
REPORTS_DIR: str = "/var/lib/atlas/reports"
|
||||
REPORT_RETENTION_DAYS: int = 90
|
||||
|
||||
# Geocoding
|
||||
|
||||
@@ -11,13 +11,13 @@ from fastapi import HTTPException, Request, status
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
|
||||
class AdanException(Exception):
|
||||
class AtlasException(Exception):
|
||||
"""Excepción base para todas las excepciones de la aplicación."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
message: str,
|
||||
code: str = "ADAN_ERROR",
|
||||
code: str = "ATLAS_ERROR",
|
||||
details: Optional[Dict[str, Any]] = None,
|
||||
):
|
||||
self.message = message
|
||||
@@ -26,7 +26,7 @@ class AdanException(Exception):
|
||||
super().__init__(self.message)
|
||||
|
||||
|
||||
class NotFoundError(AdanException):
|
||||
class NotFoundError(AtlasException):
|
||||
"""Recurso no encontrado."""
|
||||
|
||||
def __init__(
|
||||
@@ -43,7 +43,7 @@ class NotFoundError(AdanException):
|
||||
self.identifier = identifier
|
||||
|
||||
|
||||
class AlreadyExistsError(AdanException):
|
||||
class AlreadyExistsError(AtlasException):
|
||||
"""El recurso ya existe."""
|
||||
|
||||
def __init__(
|
||||
@@ -60,7 +60,7 @@ class AlreadyExistsError(AdanException):
|
||||
self.value = value
|
||||
|
||||
|
||||
class ValidationError(AdanException):
|
||||
class ValidationError(AtlasException):
|
||||
"""Error de validación de datos."""
|
||||
|
||||
def __init__(
|
||||
@@ -73,7 +73,7 @@ class ValidationError(AdanException):
|
||||
self.field = field
|
||||
|
||||
|
||||
class AuthenticationError(AdanException):
|
||||
class AuthenticationError(AtlasException):
|
||||
"""Error de autenticación."""
|
||||
|
||||
def __init__(
|
||||
@@ -84,7 +84,7 @@ class AuthenticationError(AdanException):
|
||||
super().__init__(message, "AUTHENTICATION_ERROR", details)
|
||||
|
||||
|
||||
class AuthorizationError(AdanException):
|
||||
class AuthorizationError(AtlasException):
|
||||
"""Error de autorización (permisos insuficientes)."""
|
||||
|
||||
def __init__(
|
||||
@@ -95,7 +95,7 @@ class AuthorizationError(AdanException):
|
||||
super().__init__(message, "AUTHORIZATION_ERROR", details)
|
||||
|
||||
|
||||
class ExternalServiceError(AdanException):
|
||||
class ExternalServiceError(AtlasException):
|
||||
"""Error al comunicarse con un servicio externo."""
|
||||
|
||||
def __init__(
|
||||
@@ -109,7 +109,7 @@ class ExternalServiceError(AdanException):
|
||||
self.service = service
|
||||
|
||||
|
||||
class GeocercaViolationError(AdanException):
|
||||
class GeocercaViolationError(AtlasException):
|
||||
"""Violación de geocerca detectada."""
|
||||
|
||||
def __init__(
|
||||
@@ -128,7 +128,7 @@ class GeocercaViolationError(AdanException):
|
||||
self.vehiculo_id = vehiculo_id
|
||||
|
||||
|
||||
class SpeedLimitExceededError(AdanException):
|
||||
class SpeedLimitExceededError(AtlasException):
|
||||
"""Límite de velocidad excedido."""
|
||||
|
||||
def __init__(
|
||||
@@ -145,7 +145,7 @@ class SpeedLimitExceededError(AdanException):
|
||||
self.limite = limite
|
||||
|
||||
|
||||
class DeviceConnectionError(AdanException):
|
||||
class DeviceConnectionError(AtlasException):
|
||||
"""Error de conexión con dispositivo."""
|
||||
|
||||
def __init__(
|
||||
@@ -159,7 +159,7 @@ class DeviceConnectionError(AdanException):
|
||||
self.dispositivo_id = dispositivo_id
|
||||
|
||||
|
||||
class VideoStreamError(AdanException):
|
||||
class VideoStreamError(AtlasException):
|
||||
"""Error con stream de video."""
|
||||
|
||||
def __init__(
|
||||
@@ -173,7 +173,7 @@ class VideoStreamError(AdanException):
|
||||
self.camara_id = camara_id
|
||||
|
||||
|
||||
class MaintenanceRequiredError(AdanException):
|
||||
class MaintenanceRequiredError(AtlasException):
|
||||
"""Mantenimiento requerido para el vehículo."""
|
||||
|
||||
def __init__(
|
||||
@@ -188,7 +188,7 @@ class MaintenanceRequiredError(AdanException):
|
||||
self.tipo_mantenimiento = tipo_mantenimiento
|
||||
|
||||
|
||||
class DatabaseError(AdanException):
|
||||
class DatabaseError(AtlasException):
|
||||
"""Error de base de datos."""
|
||||
|
||||
def __init__(
|
||||
@@ -207,8 +207,8 @@ class DatabaseError(AdanException):
|
||||
# ============================================================================
|
||||
|
||||
|
||||
async def adan_exception_handler(request: Request, exc: AdanException) -> JSONResponse:
|
||||
"""Handler para excepciones base de Adan."""
|
||||
async def atlas_exception_handler(request: Request, exc: AtlasException) -> JSONResponse:
|
||||
"""Handler para excepciones base de Atlas."""
|
||||
status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
|
||||
if isinstance(exc, NotFoundError):
|
||||
@@ -275,6 +275,6 @@ def register_exception_handlers(app) -> None:
|
||||
Args:
|
||||
app: Instancia de FastAPI.
|
||||
"""
|
||||
app.add_exception_handler(AdanException, adan_exception_handler)
|
||||
app.add_exception_handler(AtlasException, atlas_exception_handler)
|
||||
app.add_exception_handler(HTTPException, http_exception_handler)
|
||||
app.add_exception_handler(Exception, general_exception_handler)
|
||||
|
||||
Reference in New Issue
Block a user