from __future__ import annotations import json from fastapi import APIRouter, Depends from sqlalchemy.orm import Session from iti.auth import require_service from iti.db import get_db from iti.responses import ok from iti_system.enums import LogType from iti_system.models import SysLog from iti_system.schemas import AuditEventsIn router = APIRouter( prefix="/internal/audit", tags=["system.audit"], dependencies=[Depends(require_service())], ) @router.post("/events") def create_audit_events(payload: AuditEventsIn, db: Session = Depends(get_db)): for event in payload.events: db.add(_to_log(event)) db.commit() return ok({"count": len(payload.events)}) @router.post("/login") def create_login_event(payload: AuditEventsIn, db: Session = Depends(get_db)): for event in payload.events: db.add(_to_log(event, log_type=LogType.AUTH.value)) db.commit() return ok({"count": len(payload.events)}) @router.post("/operation") def create_operation_event(payload: AuditEventsIn, db: Session = Depends(get_db)): for event in payload.events: db.add(_to_log(event, log_type=LogType.OPERATION.value)) db.commit() return ok({"count": len(payload.events)}) def _to_log(event, *, log_type: str | None = None) -> SysLog: desc_parts = [] if event.desc: desc_parts.append(event.desc) if event.target_type or event.target_id: desc_parts.append(f"target={event.target_type or '-'}:{event.target_id or '-'}") if event.diff: desc_parts.append(f"diff={json.dumps(event.diff, ensure_ascii=False, default=str)}") return SysLog( name=event.title, method=event.method, user_id=event.actor_id, path=event.path, ip=event.ip, user_agent=event.user_agent, body_params=json.dumps(event.diff, ensure_ascii=False, default=str) if event.diff else None, response=None, exception=event.error, success=event.success, desc="\n".join(desc_parts) if desc_parts else None, type=log_type or event.type, )