|
|
---
|
|
|
change: config-to-mysql
|
|
|
design-doc: docs/superpowers/specs/2026-07-04-config-to-mysql-design.md
|
|
|
base-ref: 4956086
|
|
|
---
|
|
|
|
|
|
# Config to MySQL - 实施计划
|
|
|
|
|
|
> 基于 [Design Doc](docs/superpowers/specs/2026-07-04-config-to-mysql-design.md) 拆分的可执行任务。
|
|
|
> 目标:将 `symbols_config.json` 和 `ai_config.json` 迁移到 MySQL,保留 JSON 文件作为 fallback。
|
|
|
|
|
|
---
|
|
|
|
|
|
## 任务总览
|
|
|
|
|
|
| # | 任务 | 依赖 |
|
|
|
|---|------|------|
|
|
|
| T1 | 新增 AppConfig 模型和 ConfigStore | - |
|
|
|
| T2 | 创建 config_migration.py 迁移脚本 | T1 |
|
|
|
| T3 | 在 main.py lifespan 中集成 | T1, T2 |
|
|
|
| T4 | 修改配置 API | T1 |
|
|
|
| T5 | 修改业务使用方 | T1 |
|
|
|
| T6 | 编写测试用例 | T1-T5 |
|
|
|
|
|
|
---
|
|
|
|
|
|
## T1: 新增 AppConfig 模型和 ConfigStore
|
|
|
|
|
|
**文件**:
|
|
|
- `app/models.py`
|
|
|
- `app/config_store.py`
|
|
|
|
|
|
**任务**:
|
|
|
1. 在 `app/models.py` 中新增 `AppConfig` 模型
|
|
|
2. 创建 `app/config_store.py` 和 `ConfigStore` 类
|
|
|
3. 实现 `get_config(key, fallback)`
|
|
|
4. 实现 `set_config(key, value)`
|
|
|
5. 实现 `load_from_json(key, fallback)` 和 `save_to_json(key, value)`
|
|
|
6. 实现 `get_config_store()` 单例函数
|
|
|
|
|
|
**验收**:
|
|
|
- `ConfigStore` 支持 MySQL 命中、未命中回填、JSON fallback
|
|
|
- `set_config` 始终写入 JSON,MySQL 可用时同时写入数据库
|
|
|
|
|
|
---
|
|
|
|
|
|
## T2: 创建 config_migration.py 迁移脚本
|
|
|
|
|
|
**文件**: `app/config_migration.py`
|
|
|
|
|
|
**任务**:
|
|
|
1. 定义配置映射(key → file path → default)
|
|
|
2. 实现 `migrate_configs_to_mysql()`
|
|
|
3. 检测数据库是否已有配置
|
|
|
4. 从 JSON 读取并写入 MySQL
|
|
|
|
|
|
**验收**:
|
|
|
- 幂等性:数据库已有数据时跳过
|
|
|
- 缺失配置时从 JSON 迁移
|
|
|
|
|
|
---
|
|
|
|
|
|
## T3: 在 main.py lifespan 中集成
|
|
|
|
|
|
**文件**: `app/main.py`
|
|
|
|
|
|
**任务**:
|
|
|
1. 在 MySQL 初始化后创建 `app_config` 表
|
|
|
2. 调用 `migrate_configs_to_mysql()`
|
|
|
3. 记录迁移日志
|
|
|
|
|
|
**验收**:
|
|
|
- 启动时自动创建配置表
|
|
|
- 自动迁移 JSON 配置
|
|
|
|
|
|
---
|
|
|
|
|
|
## T4: 修改配置 API
|
|
|
|
|
|
**文件**:
|
|
|
- `app/api/config.py`
|
|
|
- `app/api/ai_config.py`
|
|
|
|
|
|
**任务**:
|
|
|
1. `config.py` 的 `get_config` 和 `upload_config` 使用 `ConfigStore`
|
|
|
2. `ai_config.py` 的 `_load_ai_config` 和 `_save_ai_config` 使用 `ConfigStore`
|
|
|
3. 保持 API 接口签名不变
|
|
|
|
|
|
**验收**:
|
|
|
- 上传配置同时写入数据库和 JSON 文件
|
|
|
- 读取配置优先从数据库
|
|
|
|
|
|
---
|
|
|
|
|
|
## T5: 修改业务使用方
|
|
|
|
|
|
**文件**:
|
|
|
- `app/api/futures_analysis.py`
|
|
|
- `app/api/trade_review.py`
|
|
|
- `app/services/trade_parser.py`
|
|
|
- `app/services/plan_generator.py`
|
|
|
- `app/services/ai_analysis.py`
|
|
|
|
|
|
**任务**:
|
|
|
1. 替换所有 `_load_symbols_config()` / `load_symbols_config()` 为 `ConfigStore.get_config("symbols")`
|
|
|
2. 替换 `_load_ai_config()` 为 `ConfigStore.get_config("ai")`
|
|
|
|
|
|
**验收**:
|
|
|
- 所有读取点统一使用 `ConfigStore`
|
|
|
- 不修改业务逻辑
|
|
|
|
|
|
---
|
|
|
|
|
|
## T6: 编写测试用例
|
|
|
|
|
|
**文件**: `tests/test_config_store.py`
|
|
|
|
|
|
**任务**:
|
|
|
1. 测试 MySQL 命中场景
|
|
|
2. 测试 MySQL 未命中时读取 JSON 并回填
|
|
|
3. 测试 MySQL 不可用时读取 JSON
|
|
|
4. 测试 `set_config` 双写
|
|
|
5. 测试迁移幂等性
|
|
|
6. 运行全部测试套件确保无回归
|
|
|
|
|
|
**验收**:
|
|
|
- 所有测试通过
|
|
|
- 测试覆盖核心降级场景
|