Merge remote-tracking branch 'origin/development' into feature/Invoice-movements
# Conflicts: # backend/api/v1/modules/a76/reports/importacion/facturas/usa/service.py # backend/core/celery_app.py # frontend/src/lib/api/dashboard/a76/general_catalogs/company.ts
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
import os
|
||||
from celery import Celery
|
||||
|
||||
# Import models in correct order for SQLAlchemy relationship resolution
|
||||
# CRITICAL: FaLineItem must be imported BEFORE LineItem
|
||||
from api.v1.modules.a24.fa.fa_item_lines.models import FaLineItem # noqa: F401
|
||||
from api.v1.modules.a76.items.models import LineItem # noqa: F401
|
||||
|
||||
valkey_url = os.getenv("VALKEY_URL", "redis://valkey:6379/0")
|
||||
|
||||
@@ -15,8 +19,11 @@ celery_app = Celery(
|
||||
"api.v1.modules.a76.reports.exportacion.aviso_consolidado.task",
|
||||
"api.v1.modules.a76.reports.movements.invoices.tasks",
|
||||
"api.v1.modules.a76.reports.exportacion.descargo.task",
|
||||
"api.v1.modules.a76.imports.tasks"
|
||||
] # Ruta al módulo donde están las tareas
|
||||
"api.v1.modules.a76.imports.tasks",
|
||||
"api.v1.modules.a76.reports.exportacion.transmission.MAINX30.task",
|
||||
"api.v1.modules.a76.reports.importacion.transmission.temporal.MAINX30.task",
|
||||
"api.v1.modules.a76.reports.importacion.transmission.definitive.MAINX30.task"
|
||||
] # Ruta al módulo donde están las tareas
|
||||
)
|
||||
|
||||
# Configuraciones adicionales
|
||||
@@ -30,4 +37,4 @@ celery_app.conf.update(
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
celery_app.start()
|
||||
celery_app.start()
|
||||
|
||||
@@ -5,7 +5,7 @@ Manejadores globales de excepciones para FastAPI
|
||||
import logging
|
||||
from typing import Any, Dict
|
||||
|
||||
from fastapi import Request, status
|
||||
from fastapi import Request, status, HTTPException
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.exceptions import RequestValidationError
|
||||
@@ -141,6 +141,23 @@ async def sqlalchemy_error_handler(
|
||||
)
|
||||
|
||||
|
||||
async def http_exception_handler(
|
||||
request: Request,
|
||||
exc: HTTPException,
|
||||
) -> JSONResponse:
|
||||
"""
|
||||
Manejador para HTTPException de FastAPI
|
||||
"""
|
||||
return JSONResponse(
|
||||
status_code=exc.status_code,
|
||||
content={
|
||||
"error": "HTTP_ERROR",
|
||||
"message": exc.detail,
|
||||
"status_code": exc.status_code,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
async def general_exception_handler(
|
||||
request: Request,
|
||||
exc: Exception,
|
||||
@@ -175,6 +192,7 @@ def register_exception_handlers(app) -> None:
|
||||
app: Instancia de FastAPI
|
||||
"""
|
||||
app.add_exception_handler(BaseAPIException, base_exception_handler)
|
||||
app.add_exception_handler(HTTPException, http_exception_handler)
|
||||
app.add_exception_handler(RequestValidationError, validation_exception_handler)
|
||||
app.add_exception_handler(IntegrityError, integrity_error_handler)
|
||||
app.add_exception_handler(SQLAlchemyError, sqlalchemy_error_handler)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import logging
|
||||
import time
|
||||
from typing import Callable
|
||||
from fastapi import HTTPException, Request, Response
|
||||
from fastapi import Request, Response
|
||||
from fastapi.responses import JSONResponse
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
from .config import settings
|
||||
from .database import CoreSessionLocal
|
||||
@@ -34,9 +35,13 @@ class TenantMiddleware(BaseHTTPMiddleware):
|
||||
# 4. Validación estricta de Token (solo para lo que no es público ni OPTIONS)
|
||||
auth_header = request.headers.get("Authorization")
|
||||
if not auth_header or not auth_header.startswith("Bearer "):
|
||||
raise HTTPException(
|
||||
status_code=401,
|
||||
detail="Missing or invalid authorization header"
|
||||
return JSONResponse(
|
||||
status_code=401,
|
||||
content={
|
||||
"error": "HTTP_ERROR",
|
||||
"message": "Missing or invalid authorization header",
|
||||
"status_code": 401,
|
||||
}
|
||||
)
|
||||
|
||||
token = auth_header.split(" ")[1]
|
||||
@@ -48,7 +53,14 @@ class TenantMiddleware(BaseHTTPMiddleware):
|
||||
request.state.user_info = user_info
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Tenant validation error: {str(e)}")
|
||||
raise HTTPException(status_code=401, detail="Invalid authentication")
|
||||
return JSONResponse(
|
||||
status_code=401,
|
||||
content={
|
||||
"error": "HTTP_ERROR",
|
||||
"message": "Invalid authentication",
|
||||
"status_code": 401,
|
||||
}
|
||||
)
|
||||
|
||||
# 5. Continuar con la petición real
|
||||
return await call_next(request)
|
||||
@@ -104,19 +116,28 @@ class LicenseValidationMiddleware(BaseHTTPMiddleware):
|
||||
license_info = license_service.validate_license(tenant_id)
|
||||
|
||||
if not license_info["is_valid"]:
|
||||
raise HTTPException(
|
||||
return JSONResponse(
|
||||
status_code=402,
|
||||
detail=f"License validation failed: {license_info['reason']}",
|
||||
content={
|
||||
"error": "HTTP_ERROR",
|
||||
"message": f"License validation failed: {license_info['reason']}",
|
||||
"status_code": 402,
|
||||
}
|
||||
)
|
||||
|
||||
# Agregar info de licencia al request state
|
||||
request.state.license_info = license_info
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"License validation error: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail="License validation error")
|
||||
return JSONResponse(
|
||||
status_code=500,
|
||||
content={
|
||||
"error": "HTTP_ERROR",
|
||||
"message": "License validation error",
|
||||
"status_code": 500,
|
||||
}
|
||||
)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user