# Config 重要决策记录

**版本：** 3.0  
**最后更新**：2026-01-20

---

本文档记录配置系统的关键设计决策，包括问题背景、可选方案、选择理由和影响。

---

## 决策 1：配置与逻辑彻底分离

**日期**：2025-12-xx  
**状态**：已实施

### 痛点

- 早期代码中，配置文件和加载逻辑混在业务模块中
- 各处直接 `open(...).read()` 读取 JSON，缺乏统一入口
- 修改配置结构容易影响大量代码，缺乏集中治理点

### 可选方案

- **方案 A：各模块自管配置**
  - 优点：实现简单，短期改动少
  - 缺点：配置结构分散，无法整体演进
- **方案 B：集中到 ConfigManager，配置目录只放 JSON** ✅
  - 优点：职责清晰，后续演进只需改一个入口
  - 缺点：需要一次性梳理所有配置访问路径

### 选择理由

1. **职责清晰**：`core/default_config/` 只放 JSON，所有逻辑集中在 `ConfigManager`
2. **可演进性**：未来要加校验 / 热更新，只需在 `ConfigManager` 一处改动
3. **便于排错**：所有配置问题都可以从 `ConfigManager` 和 JSON 文件两处着手

### 影响

- 新增 `core/infra/project_context/ConfigManager` 作为唯一入口
- 业务模块不再直接读取 JSON 文件
- 配置结构调整对业务代码的影响大幅降低

---

## 决策 2：核心配置 + 用户配置 + 环境变量 三层合并

**日期**：2025-12-xx  
**状态**：已实施

### 痛点

- 只有一份配置时，很难同时兼顾「安全默认」和「用户灵活覆盖」
- 项目需要区分「框架默认值」和「用户项目自己的配置」
- 生产环境的敏感信息（密码、连接串）不适合写在 JSON 文件里

### 可选方案

- **方案 A：只有一份配置文件**
  - 优点：简单
  - 缺点：难以区分框架默认与用户配置；不利于版本升级
- **方案 B：核心配置 + 用户配置**  
  - 优点：可以区分默认与覆盖
  - 缺点：敏感信息仍在文件中，不利于生产使用
- **方案 C：核心配置 + 用户配置 + 环境变量** ✅
  - 优点：兼顾默认值、安全和灵活性
  - 缺点：实现稍复杂

### 选择理由

1. **安全性**：敏感信息放在环境变量，避免硬编码到文件或仓库
2. **可升级性**：核心配置可以随版本演进，用户只维护自己的覆盖层
3. **灵活性**：用户可以选择用 JSON 或环境变量的方式进行配置

### 影响

- 确立优先级：`ENV > userspace/config > core/default_config`
- 所有数据库敏感字段都支持环境变量覆盖
- 文档明确推荐在生产环境使用环境变量配置密码等信息

---

## 决策 3：深度合并（Partial Override），而不是完全替换

**日期**：2025-12-xx  
**状态**：已实施

### 痛点

- 传统做法是“有用户配置就完全替换默认配置”
- 结果是：用户为了改一个字段，不得不复制整份配置，容易跟版本漂移

### 可选方案

- **方案 A：浅合并 / 完全替换**
  - 优点：实现简单
  - 缺点：易出错，升级默认配置时难以合并
- **方案 B：字段级别的深度合并** ✅
  - 优点：用户只需配置差异，默认配置仍然生效
  - 缺点：实现稍复杂，需要清晰的合并规则

### 选择理由

1. **用户体验好**：用户只需写少量 JSON，即可覆盖自己关心的字段
2. **配置升级友好**：默认配置新增字段时，用户配置仍然兼容
3. **避免重复**：避免大量 copy-paste 默认配置到 userspace

### 影响

- `ConfigManager` 内部实现 `dict_deep_merge` 逻辑
- 文档统一强调「只写差异，不要复制整份默认配置」

---

## 决策 4：数据库配置简化（用户名 + 密码优先）

**日期**：2025-12-xx  
**状态**：已实施

### 痛点

- 数据库连接参数很多（host、port、database、pool_size、timeout...）
- 大部分用户对这些参数并不熟悉，但又被迫填写

### 可选方案

- **方案 A：所有参数都要求用户填写**
  - 优点：最灵活
  - 缺点：门槛高，容易填错
- **方案 B：提供一大堆示例配置，由用户复制**  
  - 优点：相对友好
  - 缺点：用户仍需理解许多参数
- **方案 C：用户名 + 密码 / db_path 为主，其余使用默认值** ✅
  - 优点：对 90% 用户足够简单
  - 缺点：高级用户需了解如何覆盖默认值

### 选择理由

1. **降低门槛**：让“连上数据库”这件事变得非常简单
2. **保留高级能力**：通过 userspace 覆盖 `_advanced` 字段等支持高级配置

### 影响

- `userspace/config/database/postgresql.json` 只需写 `user` 和 `password`
- 其余参数从 `core/default_config/database/postgresql.json` 自动继承
- 文档中提供 `.example.json` 作为完整模板，对高级用户友好

---

## 决策 5：配置与数据枚举分离

**日期**：2025-12-xx  
**状态**：已实施

### 痛点

- 早期曾把指数列表、股票池等「数据枚举」放进配置系统
- 这些内容更像是「数据定义」，而不是「行为控制」

### 可选方案

- **方案 A：继续把数据枚举放在 config 中**
  - 优点：看起来“一切皆配置”
  - 缺点：职责混乱，容易误删 / 误改
- **方案 B：将数据枚举迁移到 data_source / 业务模块** ✅
  - 优点：配置只做“控制行为”的事，数据放在真正需要它的模块中

### 选择理由

1. **职责清晰**：Config 只负责「配置」本身
2. **可维护性高**：业务数据变更不再影响配置系统

### 影响

- 指数列表等数据枚举迁移到 `data_source` 模块
- Config 系统主要负责 data/system/worker/database/market 等「行为控制」

---

## 决策 6：使用 JSON 作为唯一配置格式

**日期**：2025-12-xx  
**状态**：已实施

### 痛点

- 支持多种配置格式（YAML / TOML / INI）会增加复杂度
- 对于当前项目规模，JSON 已经足够表达需要的结构

### 可选方案

- **方案 A：支持多种格式**
  - 优点：灵活，用户可以用自己熟悉的格式
  - 缺点：实现和文档复杂度显著上升
- **方案 B：统一使用 JSON** ✅
  - 优点：实现简单，生态丰富（工具支持好）

### 选择理由

1. **简单优先**：当前阶段不需要多格式支持
2. **工具兼容**：大多数编辑器 / 工具对 JSON 支持完善

### 影响

- `core/default_config/` 和 `userspace/config/` 统一采用 JSON
- 如需注释，可通过 `_comment` 字段提供说明

---

## 相关文档

- **[overview.md](./overview.md)**：配置系统概览与用法
- **[architecture.md](./architecture.md)**：配置系统整体架构设计
- **`core/default_config/DESIGN.md`**：原始设计记录
- **`userspace/config/README.md`**：用户配置说明

---

**文档结束**

