后端新增风险图谱算法模块、风险观察与反馈服务、规则 DSL 校验器和可解释性引擎,完善系统仪表盘和财务仪表盘统计, 优化 agent 运行和编排执行链路,清理旧开发文档,前端新增 系统趋势、负载热力图等多种仪表盘图表组件,完善操作反馈 对话框和工作台日期选择器,优化报销创建和审批详情交互, 补充单元测试覆盖。
73 lines
2.1 KiB
Python
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()
|