Files
X-Financial/server/src/app/services/audit.py
caoxiaozhu 7989f3a159 feat: 新增风险图谱算法与系统仪表盘及操作反馈体系
后端新增风险图谱算法模块、风险观察与反馈服务、规则 DSL
校验器和可解释性引擎,完善系统仪表盘和财务仪表盘统计,
优化 agent 运行和编排执行链路,清理旧开发文档,前端新增
系统趋势、负载热力图等多种仪表盘图表组件,完善操作反馈
对话框和工作台日期选择器,优化报销创建和审批详情交互,
补充单元测试覆盖。
2026-05-30 15:46:51 +08:00

73 lines
2.1 KiB
Python

from __future__ import annotations
import uuid
from datetime import UTC, datetime
from typing import Any
from sqlalchemy.orm import Session
from app.core.logging import get_logger
from app.models.audit_log import AuditLog
from app.repositories.audit_log import AuditLogRepository
from app.schemas.audit_log import AuditLogRead
from app.services.agent_foundation import AgentFoundationService
logger = get_logger("app.services.audit")
class AuditLogService:
def __init__(self, db: Session) -> None:
self.db = db
self.repository = AuditLogRepository(db)
def list_logs(
self,
*,
resource_type: str | None = None,
resource_id: str | None = None,
action: str | None = None,
limit: int = 50,
) -> list[AuditLogRead]:
self._ensure_ready()
items = self.repository.list(
resource_type=resource_type,
resource_id=resource_id,
action=action,
limit=limit,
)
return [AuditLogRead.model_validate(item) for item in items]
def log_action(
self,
*,
actor: str,
action: str,
resource_type: str,
resource_id: str,
before_json: dict[str, Any] | None = None,
after_json: dict[str, Any] | None = None,
request_id: str | None = None,
) -> AuditLog:
log = AuditLog(
actor=actor,
action=action,
resource_type=resource_type,
resource_id=resource_id,
before_json=before_json,
after_json=after_json,
request_id=request_id or uuid.uuid4().hex,
created_at=datetime.now(UTC),
)
created = self.repository.create(log)
logger.info(
"Created audit log id=%s action=%s resource=%s:%s",
created.id,
created.action,
created.resource_type,
created.resource_id,
)
return created
def _ensure_ready(self) -> None:
AgentFoundationService(self.db).ensure_foundation_ready()