feature/bitacora-correccion-filtro-tenant
This commit is contained in:
@@ -2,12 +2,20 @@
|
||||
Audit Log Events
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from sqlalchemy import event, inspect
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from api.v1.modules.a76.general_catalogs.company.models import Company
|
||||
from core.database import rls_company_var, rls_tenant_var
|
||||
|
||||
from .services.service import AuditService
|
||||
from .utils.serialization import serialize_for_json
|
||||
from core.context import get_user_context
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def register_audit_listeners(models_to_audit):
|
||||
"""
|
||||
@@ -30,11 +38,37 @@ def _get_current_username():
|
||||
or context.get("sub")
|
||||
or "System"
|
||||
)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
return "System"
|
||||
|
||||
|
||||
def _resolve_audit_company_tenant(session: Session, target) -> tuple:
|
||||
"""
|
||||
company_id / tenant_id desde la fila ORM, ContextVars RLS (petición HTTP),
|
||||
o ``Company.tenant_id`` por ``company_id``.
|
||||
"""
|
||||
company_id = getattr(target, "company_id", None)
|
||||
if company_id is None and getattr(target, "__tablename__", None) == "company":
|
||||
company_id = getattr(target, "id", None)
|
||||
if company_id is None:
|
||||
company_id = rls_company_var.get()
|
||||
|
||||
tenant_id = getattr(target, "tenant_id", None)
|
||||
if tenant_id is None:
|
||||
tenant_id = rls_tenant_var.get()
|
||||
if tenant_id is None and company_id is not None:
|
||||
row = (
|
||||
session.query(Company.tenant_id)
|
||||
.filter(Company.id == company_id, Company.deleted_at.is_(None))
|
||||
.first()
|
||||
)
|
||||
if row:
|
||||
tenant_id = int(row[0])
|
||||
|
||||
return company_id, tenant_id
|
||||
|
||||
|
||||
def after_insert_listener(mapper, connection, target):
|
||||
"""
|
||||
Listener for INSERT operations
|
||||
@@ -42,12 +76,19 @@ def after_insert_listener(mapper, connection, target):
|
||||
table_name = target.__tablename__
|
||||
record_data = {c.name: getattr(target, c.name) for c in mapper.columns}
|
||||
username = _get_current_username()
|
||||
company_id = getattr(target, "company_id", None) or getattr(target, "id", None)
|
||||
tenant_id = getattr(target, "tenant_id", None)
|
||||
|
||||
# Create a session bound to the connection
|
||||
session = Session(bind=connection)
|
||||
try:
|
||||
company_id, tenant_id = _resolve_audit_company_tenant(session, target)
|
||||
if company_id is None or tenant_id is None:
|
||||
logger.debug(
|
||||
"Audit skip INSERT %s: missing company_id=%s tenant_id=%s",
|
||||
table_name,
|
||||
company_id,
|
||||
tenant_id,
|
||||
)
|
||||
return
|
||||
|
||||
AuditService.log_crud_operation(
|
||||
db=session,
|
||||
table_name=table_name,
|
||||
@@ -59,7 +100,7 @@ def after_insert_listener(mapper, connection, target):
|
||||
tenant_id=tenant_id,
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error logging insert: {e}")
|
||||
logger.warning("Error logging insert for %s: %s", table_name, e)
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
@@ -87,11 +128,19 @@ def after_update_listener(mapper, connection, target):
|
||||
|
||||
record_data = {c.name: getattr(target, c.name) for c in mapper.columns}
|
||||
username = _get_current_username()
|
||||
company_id = getattr(target, "company_id", None) or getattr(target, "id", None)
|
||||
tenant_id = getattr(target, "tenant_id", None)
|
||||
|
||||
session = Session(bind=connection)
|
||||
try:
|
||||
company_id, tenant_id = _resolve_audit_company_tenant(session, target)
|
||||
if company_id is None or tenant_id is None:
|
||||
logger.debug(
|
||||
"Audit skip UPDATE %s: missing company_id=%s tenant_id=%s",
|
||||
table_name,
|
||||
company_id,
|
||||
tenant_id,
|
||||
)
|
||||
return
|
||||
|
||||
AuditService.log_crud_operation(
|
||||
db=session,
|
||||
table_name=table_name,
|
||||
@@ -105,7 +154,7 @@ def after_update_listener(mapper, connection, target):
|
||||
tenant_id=tenant_id,
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error logging update: {e}")
|
||||
logger.warning("Error logging update for %s: %s", table_name, e)
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
@@ -117,11 +166,19 @@ def after_delete_listener(mapper, connection, target):
|
||||
table_name = target.__tablename__
|
||||
record_data = {c.name: getattr(target, c.name) for c in mapper.columns}
|
||||
username = _get_current_username()
|
||||
company_id = getattr(target, "company_id", None) or getattr(target, "id", None)
|
||||
tenant_id = getattr(target, "tenant_id", None)
|
||||
|
||||
session = Session(bind=connection)
|
||||
try:
|
||||
company_id, tenant_id = _resolve_audit_company_tenant(session, target)
|
||||
if company_id is None or tenant_id is None:
|
||||
logger.debug(
|
||||
"Audit skip DELETE %s: missing company_id=%s tenant_id=%s",
|
||||
table_name,
|
||||
company_id,
|
||||
tenant_id,
|
||||
)
|
||||
return
|
||||
|
||||
AuditService.log_crud_operation(
|
||||
db=session,
|
||||
table_name=table_name,
|
||||
@@ -133,6 +190,6 @@ def after_delete_listener(mapper, connection, target):
|
||||
tenant_id=tenant_id,
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error logging delete: {e}")
|
||||
logger.warning("Error logging delete for %s: %s", table_name, e)
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
Reference in New Issue
Block a user