You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
buffer_platform/openspec/changes/config-to-mysql/design.md

102 lines
2.5 KiB

# Design: Config to MySQL
## 架构决策
### 决策 1统一配置管理模块
**决策**:创建 `app/config_store.py` 作为所有配置读写的唯一入口。
**理由**
- 消除多处重复的文件读取逻辑
- 集中管理降级策略
- 便于后续扩展(如缓存、审计)
### 决策 2单表存储键值对
**决策**:使用单表 `app_config` 存储所有配置,以 `config_key` 区分 `symbols``ai`
**表结构**
```sql
CREATE TABLE app_config (
id INT PRIMARY KEY AUTO_INCREMENT,
config_key VARCHAR(64) UNIQUE NOT NULL, -- 'symbols' 或 'ai'
config_value JSON NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
```
**理由**
- 与现有 JSON schema 兼容
- 减少表数量
- 未来新增配置无需改表结构
### 决策 3MySQL + JSON 文件降级
**决策**MySQL 可用时优先读写数据库MySQL 不可用时回退到 JSON 文件。
**理由**
- 用户明确要求无需 Redis
- JSON 文件作为 fallback 简单可靠
- 与现有配置读取方式兼容
## 数据流
```
业务代码
app/config_store.py
MySQL 可用?
↓ 是 ↓ 否
读/写 app_config 读/写 JSON 文件
```
## 配置键设计
| config_key | 对应文件 | 用途 |
|------------|----------|------|
| `symbols` | `config/symbols_config.json` | 品种合约映射 |
| `ai` | `config/ai_config.json` | AI 模型配置 |
## 降级策略
### 读取流程
1. 检查 MySQL 可用性
2. MySQL 可用则查询 `app_config`
3. 数据库无数据则读取 JSON 文件并回填数据库
4. MySQL 不可用则直接读取 JSON 文件
### 写入流程
1. 检查 MySQL 可用性
2. MySQL 可用则写入 `app_config`
3. 无论数据库是否成功,同步写入 JSON 文件(保持一致性)
4. MySQL 不可用则只写入 JSON 文件
## 兼容性
- 保持 `symbols_config.json``ai_config.json` 的 schema 不变
- API 接口签名不变
- 文件路径不变,作为 fallback 使用
## 数据迁移
启动时执行一次性迁移:
1. 检测 `app_config` 表是否已有 `symbols``ai` 配置
2. 缺失则从 JSON 文件读取并写入数据库
3. 迁移幂等:已存在则跳过
## 测试策略
1. 单元测试:
- `ConfigStore.get_config` 从 MySQL 读取
- `ConfigStore.get_config` 在 MySQL 不可用时读取 JSON
- `ConfigStore.set_config` 写入 MySQL 和 JSON
- 迁移幂等性
2. 集成测试:
- 启动时自动创建表并迁移
- API 接口正常工作