Files
company-ai-platform/app/modules/audit/service.py
JiuContinent db751f03b4 ```
refactor(Dockerfile): 使用requirements.txt替代硬编码依赖

将Dockerfile中的硬编码pip包列表替换为通过requirements.txt文件安装,
提高依赖管理的灵活性和可维护性。

feat(scheduling): 移除内置APScheduler,采用独立调度系统

移除app/core/background/scheduler.py中原来的APScheduler实现,
改为使用新的应用级调度系统app.application.scheduling。

refactor(task_queue): 调整任务队列模块结构和导入路径

将任务队列相关常量从app.core.background.task_queue.constants迁移至
app.tasks.constants,并更新所有相关导入路径和引用。

refactor(events): 将事件服务重构为独立的应用层组件

将事件分发逻辑从核心层迁移到应用层,使用app.application.events.EventDispatchService
替代原有的app.modules.events.services.EventService。

feat(ai_memory): 增强AI记忆自动写入的安全策略

新增ai_memory_blocked_content_terms配置项用于阻止敏感内容,
添加TTL过期机制控制自动写入条目的生命周期。

fix(security): 强化生产环境安全验证机制

增加model_validator确保生产环境中数据库连接、API密钥、CORS设置等
关键安全配置符合要求。

feat(risks): 优化风险事件操作动作的外键约束

为RiskEventAction模型的风险事件ID字段添加外键约束,
防止孤立记录并增强数据完整性。

refactor(audit): 优化审计服务方法命名和事务处理

将AuditService的log方法重命名为record以反映其阶段行为,
并调整事务提交时机以提高性能。

feat(events): 增强领域事件并发处理和响应模型

添加事件锁定机制防止重复处理,更新API响应模型以提供
更准确的数据类型定义。
```
2026-07-15 16:36:42 +08:00

77 lines
2.4 KiB
Python

import json
from typing import Any
from sqlalchemy import select
from sqlalchemy.orm import Session
from app.core.http.pagination import bounded_limit
from app.core.http.request_context import get_request_id
from app.modules.audit.constants import AUDIT_REDACTED_VALUE, AUDIT_SENSITIVE_KEYS
from app.modules.audit.models import AuditLog
from app.modules.audit.schemas import AuditLogCreate
def _redact(value: Any) -> Any:
if isinstance(value, dict):
safe: dict[str, Any] = {}
for key, item in value.items():
key_text = str(key)
if key_text.lower() in AUDIT_SENSITIVE_KEYS:
safe[key_text] = AUDIT_REDACTED_VALUE
else:
safe[key_text] = _redact(item)
return safe
if isinstance(value, list):
return [_redact(item) for item in value]
if isinstance(value, tuple):
return [_redact(item) for item in value]
return value
def _dump(value: Any | None) -> str | None:
"""Serialize audit payloads while preserving existing strings."""
if value is None:
return None
if isinstance(value, str):
return value
return json.dumps(_redact(value), ensure_ascii=False, default=str)
class AuditService:
"""Persist and query audit log entries."""
def __init__(self, db: Session):
self.db = db
def record(self, payload: AuditLogCreate) -> AuditLog:
"""Stage an audit record in the caller's transaction."""
record = AuditLog(
actor=payload.actor,
source=payload.source,
action=payload.action,
target_type=payload.target_type,
target_id=payload.target_id,
risk_level=payload.risk_level,
request_payload=_dump(payload.request_payload),
response_payload=_dump(payload.response_payload),
status=payload.status,
request_id=payload.request_id or get_request_id(),
)
self.db.add(record)
self.db.flush()
return record
def log(self, payload: AuditLogCreate) -> AuditLog:
"""Persist an audit record as a standalone transaction."""
record = self.record(payload)
self.db.commit()
self.db.refresh(record)
return record
def list_logs(self, limit: int = 100) -> list[AuditLog]:
stmt = select(AuditLog).order_by(AuditLog.id.desc()).limit(bounded_limit(limit))
return list(self.db.execute(stmt).scalars())