refactor(#776): 统一配置入口,建立packages/config消除重复定义 #791

Merged
xiaoxia merged 1 commits from refactor/unified-config-entry into develop 2026-07-23 23:55:01 +08:00
Owner

背景

代码质量专项P1:配置文件分散在8处,3处重复单例实现+重复SettingsConfigDict+alembic绕开配置系统。

改动

  • 新增 packages/config/ 作为配置统一入口(base/api_settings/worker_settings)
  • SharedSettings 基类 + 统一单例管理(_settings_cache),消除3处重复单例实现
  • API配置 → packages/config/api_settings.py(APISettings)
  • Worker配置 → packages/config/worker_settings.py(WorkerSettings)
  • 旧路径全部保留为 re-export 向后兼容层
  • alembic/env.py 改用统一配置获取 database_url,不再直接读环境变量
  • 测试更新:改用 reload_settings_cache() 替代手动 _settings=None

验证

  • 全量单测 4383 passed, 8 skipped
  • 净减 397 行

Issue

#776

## 背景 代码质量专项P1:配置文件分散在8处,3处重复单例实现+重复SettingsConfigDict+alembic绕开配置系统。 ## 改动 - ✅ 新增 `packages/config/` 作为配置统一入口(base/api_settings/worker_settings) - ✅ SharedSettings 基类 + 统一单例管理(_settings_cache),消除3处重复单例实现 - ✅ API配置 → `packages/config/api_settings.py`(APISettings) - ✅ Worker配置 → `packages/config/worker_settings.py`(WorkerSettings) - ✅ 旧路径全部保留为 re-export 向后兼容层 - ✅ alembic/env.py 改用统一配置获取 database_url,不再直接读环境变量 - ✅ 测试更新:改用 `reload_settings_cache()` 替代手动 `_settings=None` ## 验证 - 全量单测 4383 passed, 8 skipped ✅ - 净减 397 行 ## Issue #776
xiaoxia added 1 commit 2026-07-23 23:23:39 +08:00
refactor(#776): 统一配置入口,建立packages/config消除重复定义
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 6s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 1m23s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m4s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 33s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 18s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m21s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 51s
Preview Deploy / Deploy Preview Environment (pull_request) Failing after 22s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m10s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 3m57s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m37s
AI Code Review / AI Code Review (pull_request) Successful in 7m16s
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 9m23s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 5m21s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 46s
25820fc2dc
- 新增 packages/config/ 作为配置统一入口(base/api_settings/worker_settings)
- SharedSettings 基类 + 统一单例管理(_settings_cache),消除3处重复单例实现
- API配置迁移到 packages/config/api_settings.py(APISettings)
- Worker配置迁移到 packages/config/worker_settings.py(WorkerSettings)
- 旧路径全部保留为 re-export 向后兼容层
- alembic/env.py 改用统一配置获取 database_url,不再直接读环境变量
- 测试更新:改用 reload_settings_cache() 替代手动 _settings=None

净减 397 行(4新文件 + 7修改)
Collaborator

代码审查结果 - PR #791

⚠️ 问题(3个需要修改)

  1. packages/config/api_settings.py 第113行:环境变量校验逻辑错误,存在安全隐患。

    • 问题描述validate_oss_access_key_idvalidate_oss_access_key_secret 方法中使用了 os.getenv("APP_ENV", "development") 来判断当前环境。如果 APP_ENV 仅在 .env 文件中定义而未导出为系统环境变量,os.getenv 将获取不到值,从而默认为 "development"。这会导致在非开发环境下,如果未导出环境变量,系统将跳过对 OSS 密钥的强制非空校验,可能导致服务以空密钥启动或暴露配置错误。
    • 修改建议:将校验器的 mode 改为 "after",通过 self.environment 访问已解析的环境变量,确保校验逻辑与 Pydantic 加载的配置一致。
  2. apps/api/app/core/config.py 第12行reload_settings 函数未更新模块级单例,导致配置热更新失效。

    • 问题描述:在 reload_settings 函数中,虽然调用了 reload_settings_cache() 清空了缓存并返回了新的配置对象,但未更新模块底部的全局变量 settings。如果外部代码通过 from app.core.config import settings 引入了配置,调用 reload_settings() 后,该引用仍指向旧的配置对象,与 app/config.py 中的实现(正确更新了全局变量)不一致。
    • 修改建议:参考 apps/api/app/config.py 的实现,在函数内部添加 global settings 并更新 settings 变量。
  3. alembic/env.py 第15行:数据库迁移工具配置回退风险。

    • 问题描述:Alembic 现在通过 get_shared_settings() 获取配置。如果当前工作目录下找不到 .env 文件(例如在某些容器启动脚本或非项目根目录执行时),SharedSettings 会使用硬编码的默认值(database_url = "postgresql+psycopg://postgres:postgres@localhost:5432/...")。原代码使用 os.getenv,在未设置时会返回 None 从而跳过覆盖。新代码可能导致生产环境迁移脚本意外连接到本地默认数据库,存在严重的安全误操作风险。
    • 修改建议:在 alembic/env.py 中获取配置后,增加检查逻辑:如果 settings.database_url 等于默认的 localhost 地址且当前环境非 development,应抛出异常或显式警告,防止误连。

💡 建议(1个可选)

  1. packages/config/base.py 第86行:配置缓存键未包含环境文件路径。
    • 具体内容get_cached_settings 使用类名作为缓存键。如果在运行时修改了 APP_ENV 环境变量(例如在测试中切换环境),由于缓存键不变,函数将返回基于旧环境文件加载的配置对象,直到手动调用 reload_settings_cache。建议将 env_file 的路径或内容哈希纳入缓存键的考量,或者在文档中明确说明切换环境必须调用 reload。

格式检查通过 | 逻辑审查需修改 | ⚠️ 建议关注性能


🤖 由 AI 代码审查机器人自动生成 | 2026-07-23 15:38:00 | 模型:

## 代码审查结果 - PR #791 ### ⚠️ 问题(3个需要修改) 1. **packages/config/api_settings.py 第113行**:环境变量校验逻辑错误,存在安全隐患。 - **问题描述**:`validate_oss_access_key_id` 和 `validate_oss_access_key_secret` 方法中使用了 `os.getenv("APP_ENV", "development")` 来判断当前环境。如果 `APP_ENV` 仅在 `.env` 文件中定义而未导出为系统环境变量,`os.getenv` 将获取不到值,从而默认为 `"development"`。这会导致在非开发环境下,如果未导出环境变量,系统将跳过对 OSS 密钥的强制非空校验,可能导致服务以空密钥启动或暴露配置错误。 - **修改建议**:将校验器的 `mode` 改为 `"after"`,通过 `self.environment` 访问已解析的环境变量,确保校验逻辑与 Pydantic 加载的配置一致。 2. **apps/api/app/core/config.py 第12行**:`reload_settings` 函数未更新模块级单例,导致配置热更新失效。 - **问题描述**:在 `reload_settings` 函数中,虽然调用了 `reload_settings_cache()` 清空了缓存并返回了新的配置对象,但未更新模块底部的全局变量 `settings`。如果外部代码通过 `from app.core.config import settings` 引入了配置,调用 `reload_settings()` 后,该引用仍指向旧的配置对象,与 `app/config.py` 中的实现(正确更新了全局变量)不一致。 - **修改建议**:参考 `apps/api/app/config.py` 的实现,在函数内部添加 `global settings` 并更新 `settings` 变量。 3. **alembic/env.py 第15行**:数据库迁移工具配置回退风险。 - **问题描述**:Alembic 现在通过 `get_shared_settings()` 获取配置。如果当前工作目录下找不到 `.env` 文件(例如在某些容器启动脚本或非项目根目录执行时),`SharedSettings` 会使用硬编码的默认值(`database_url = "postgresql+psycopg://postgres:postgres@localhost:5432/..."`)。原代码使用 `os.getenv`,在未设置时会返回 None 从而跳过覆盖。新代码可能导致生产环境迁移脚本意外连接到本地默认数据库,存在严重的安全误操作风险。 - **修改建议**:在 `alembic/env.py` 中获取配置后,增加检查逻辑:如果 `settings.database_url` 等于默认的 localhost 地址且当前环境非 development,应抛出异常或显式警告,防止误连。 ### 💡 建议(1个可选) 1. **packages/config/base.py 第86行**:配置缓存键未包含环境文件路径。 - **具体内容**:`get_cached_settings` 使用类名作为缓存键。如果在运行时修改了 `APP_ENV` 环境变量(例如在测试中切换环境),由于缓存键不变,函数将返回基于旧环境文件加载的配置对象,直到手动调用 `reload_settings_cache`。建议将 `env_file` 的路径或内容哈希纳入缓存键的考量,或者在文档中明确说明切换环境必须调用 reload。 --- ✅ 格式检查通过 | ❌ 逻辑审查需修改 | ⚠️ 建议关注性能 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-07-23 15:38:00 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
xiaoxia merged commit ed21ee11d2 into develop 2026-07-23 23:55:01 +08:00
xiaoxia deleted branch refactor/unified-config-entry 2026-07-23 23:55:02 +08:00

🗑️ 预览环境已清理

PR #791 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #791 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.