ifixkart-backend/Backend/app/services/audit_service.py

98 lines
2.6 KiB
Python

from typing import Optional, Any
from sqlalchemy.orm import Session
from fastapi import BackgroundTasks
from app.models.AuditLogModel import AuditLog
from app.core.database.db_session import SessionLocal
import ulid
class AuditService:
@staticmethod
def log_change(
db: Session,
request_id: str,
user_id: Optional[str],
entity_type: str,
entity_id: str,
action: str,
old_value: Optional[Any],
new_value: Optional[Any],
ip_address: str,
user_agent: Optional[str]
) -> AuditLog:
audit_id = str(ulid.ULID())
log_entry = AuditLog(
audit_id=audit_id,
request_id=request_id,
user_id=user_id,
entity_type=entity_type,
entity_id=entity_id,
action=action,
old_value=old_value,
new_value=new_value,
ip_address=ip_address,
user_agent=user_agent
)
db.add(log_entry)
db.commit()
db.refresh(log_entry)
return log_entry
@classmethod
def _log_change_task(
cls,
request_id: str,
user_id: Optional[str],
entity_type: str,
entity_id: str,
action: str,
old_value: Optional[Any],
new_value: Optional[Any],
ip_address: str,
user_agent: Optional[str]
) -> None:
# Open fresh session for background thread
db = SessionLocal()
try:
cls.log_change(
db=db,
request_id=request_id,
user_id=user_id,
entity_type=entity_type,
entity_id=entity_id,
action=action,
old_value=old_value,
new_value=new_value,
ip_address=ip_address,
user_agent=user_agent
)
finally:
db.close()
@classmethod
def log_change_async(
cls,
background_tasks: BackgroundTasks,
request_id: str,
user_id: Optional[str],
entity_type: str,
entity_id: str,
action: str,
old_value: Optional[Any],
new_value: Optional[Any],
ip_address: str,
user_agent: Optional[str]
) -> None:
background_tasks.add_task(
cls._log_change_task,
request_id=request_id,
user_id=user_id,
entity_type=entity_type,
entity_id=entity_id,
action=action,
old_value=old_value,
new_value=new_value,
ip_address=ip_address,
user_agent=user_agent
)
audit_service = AuditService()