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响应模型以提供
更准确的数据类型定义。
```
This commit is contained in:
2026-07-15 16:36:42 +08:00
parent 267b01b9f4
commit db751f03b4
73 changed files with 1615 additions and 933 deletions

View File

@@ -2,7 +2,7 @@ import json
from functools import lru_cache
from typing import Annotated, Any
from pydantic import Field, field_validator
from pydantic import Field, field_validator, model_validator
from pydantic_settings import BaseSettings, NoDecode, SettingsConfigDict
from app.core.constants import (
@@ -112,6 +112,25 @@ class Settings(BaseSettings):
ai_memory_enabled: bool = True
ai_memory_auto_write_enabled: bool = True
ai_memory_recall_limit: int = 5
ai_memory_auto_write_ttl_days: int = Field(default=90, ge=1, le=3650)
ai_memory_blocked_content_terms: list[str] = Field(
default_factory=lambda: [
"bank account",
"budget",
"cash flow",
"financial statement",
"id card",
"payment",
"salary",
"成本",
"付款",
"工资",
"收款",
"现金流",
"财务",
"预算",
]
)
ai_analysis_max_attempts: int = 3
ai_memory_forbidden_keys: list[str] = Field(
default_factory=lambda: [
@@ -151,6 +170,7 @@ class Settings(BaseSettings):
"openclaw_allowed_tools",
"openclaw_allowed_actions",
"ai_memory_forbidden_keys",
"ai_memory_blocked_content_terms",
mode="before",
)
@classmethod
@@ -216,6 +236,27 @@ class Settings(BaseSettings):
return {str(key): str(item) for key, item in data.items()}
raise ValueError(ConfigErrorDetail.LEGACY_ALLOWED_QUERIES_FORMAT)
@model_validator(mode="after")
def validate_production_safety(self) -> "Settings":
if self.app_env.lower() not in {"prod", "production"}:
return self
errors: list[str] = []
if self.database_url.startswith("sqlite"):
errors.append("DATABASE_URL must use PostgreSQL in production")
if not self.api_key and not any(item.get("key") for item in self.api_keys):
errors.append("API_KEY or API_KEYS is required in production")
if not self.audit_api_key and not any(
item.get("key") for item in self.audit_api_keys
):
errors.append("AUDIT_API_KEY or AUDIT_API_KEYS is required in production")
if "*" in self.cors_origins:
errors.append("CORS_ORIGINS cannot contain '*' in production")
if self.debug:
errors.append("DEBUG must be false in production")
if errors:
raise ValueError("; ".join(errors))
return self
@lru_cache
def get_settings() -> Settings: