# Construction 领域重构指南

## 1. 范围

本文档应覆盖 construction 领域中两部分字段的并集：

- 集团侧 `enum_config` 中 construction 相关的全部字段
- depm 中所有已经使用代码 enum、代码中的初始化列表、硬编码 dict、类 enum、`config` 表、`dict` 表承载，并且会影响施工初始化、手动创建、手动编辑、接口展示或业务校验的相关字段

当前这份文档先给出 construction 领域的总范围和主线判断，再把本轮优先落地对象收敛到一条主线：

- `construction.section_type_code`

以下复杂问题本轮先不展开具体迁移方案，但仍属于 construction 领域后续必须补齐的梳理范围：

- `task_id`
- `task_type`
- 其它施工节点层级和映射规则特别复杂的问题

也就是说，施工文档不是永久只看 section，而是本轮先把 section 这一层讲清楚，同时把 task 相关复杂问题明确记为后续梳理项，而不是视为领域外问题。

## 2. 当前现状

construction 领域当前至少有两类配置来源：

### 2.1 `construction_section_config`

当前按项目类型配置 section 信息，例如光伏下的：

- `code`
- `name`
- `weight`
- `project_root_nodes`

这份配置同时承担：

- section 候选项来源
- 施工初始化入口信息来源

### 2.2 `construction_node_config`

当前按项目类型配置节点信息，例如：

- `task_code`
- `type_id`
- `type_name`
- `unit`
- `weight`
- `is_primary`
- `section`

这份配置描述的是节点补充信息，不是字段级配置。

## 3. 重构目标

construction 领域本轮的目标不是重写全部施工配置，而是：

- 把 section 候选项迁到新的字段级配置
- 保留 `construction_node_config` 作为自由业务配置
- 让施工初始化和手动校验可以逐步复用统一的字段级入口

## 4. `construction.section_type_code` 的新结构

`construction_section_config` 应改造成新的字段级 key：

- `construction.section_type_code`

它的 JSON 中必须包含：

- `field_config`

并且可以额外包含业务自定义字段，例如：

- `description`
- `init_config`

推荐结构：

```json
{
  "description": "施工区字段配置",
  "field_config": [
    {"value": "GF", "label": "光伏场区", "weight": 1.4},
    {"value": "SY", "label": "升压站", "weight": 1.4},
    {"value": "SC", "label": "送出(自建)", "weight": 1.2},
    {"value": "SCDW", "label": "送出(电网建设)", "weight": 1.0}
  ],
  "init_config": {
    "root_nodes_by_value": {
      "GF": [
        {"type_id": "01", "type_code": "01", "type_name": "光伏区土建工程"},
        {"type_id": "03", "type_code": "03", "type_name": "光伏区安装工程"}
      ],
      "SY": [
        {"type_id": "02", "type_code": "02", "type_name": "升压站土建工程"}
      ]
    }
  }
}
```

这里的原则是：

- `field_config` 负责 section 候选项
- `init_config` 负责 section 相关初始化附属数据
- 两者可以同处一个 JSON 中，不需要再拆第二份 section 配置

## 5. `construction_node_config` 的定位

`construction_node_config` 不迁到字段级配置。

它仍然是自由业务配置，负责描述：

- 可能节点有哪些种类
- 哪些节点是主节点
- 节点单位、权重等补充信息

建议只做一项统一性改造：

- 顶层补 `description`

## 6. 需要迁移到 `field_config` 的功能

construction 领域应重点梳理下面两类功能：

### 6.1 项目初始化链路

需要明确：

- 初始化 section 时，候选项是否改由 `get_field_options(project_type, "construction.section_type_code")` 提供
- 初始化 root node 时，是否从同一配置对象中的业务自定义字段读取附属数据

也就是说，初始化链路应逐步从“直接解释旧 `construction_section_config`”迁移到“先读取字段级配置，再读取其业务附属字段”。

### 6.2 手动创建 / 编辑链路

需要明确：

- 如果某接口允许手动传 `section_type_code`
- 是否应改为调用 `validate_field_value(project_type, "construction.section_type_code", value)`

这样可以保证手动写入与初始化使用同一套候选项来源。

## 7. 当前迁移示例

### 示例 1：section 候选项读取

当前：

- 通过 construction 私有 helper 直接读取并解释 `construction_section_config`

目标：

- 通过 `ConfigService.get_field_options(project_type, "construction.section_type_code")` 获取 section 列表

### 示例 2：section 合法值校验

当前：

- 可能由业务代码自行判断，或者根本没有统一校验入口

目标：

- 统一走 `ConfigService.validate_field_value(...)`

### 示例 3：初始化附属数据读取

当前：

- 直接从旧 `construction_section_config` 读取 `project_root_nodes`

目标：

- 从 `construction.section_type_code` 的完整配置对象中读取业务自定义字段

## 8. 梳理清单

construction 领域后续梳理时，至少要回答下面这些问题：

1. 哪些字段属于集团侧 `enum_config` 已覆盖或可对应的字段。
2. 哪些字段在初始化时使用候选项，哪些字段在手动创建时也要校验。
3. 哪些逻辑仍在直接解释旧 JSON，而不是通过统一 helper 读取。
4. 哪些逻辑仍在使用硬编码白名单。
5. `construction_node_config` 中哪些数据只是节点补充信息，哪些其实已经在承担字段候选项职责。

如果发现某字段既参与初始化又参与手动创建，就应优先考虑迁到字段级配置。

## 9. 按本轮要求的改造落点

construction 领域这轮不是泛泛地“改配置”，而是明确围绕 3 条链路收口：

- 初始化
- create 校验
- 下拉列表

### 9.1 初始化

当前施工初始化本来就不是 dict 驱动，而是：

- `construction_section_config`
- `ConstructionTypeTree`
- `ConstructionTypeMapping`

因此本轮初始化改造的重点不是“把 dict 搬到 config”，而是：

- 把 `section_type_code` 的候选项读取统一收口到新的 config 工具
- 保留类型树和 root node 等结构化数据，但不再让 section 候选项散落在私有 helper 里

### 9.2 Create 校验

当前 `ConstructionService.create()` / `create_for_scdw()` 已经在 service 开头做了较强校验：

- `section_type_code` 来自 `construction_section_config`
- `section_sub_type_code` 来自 section config 和类型树映射
- `type_id` 来自施工类型树或 SCDW 专用配置

本轮目标是：

- `section_type_code` 统一改成通过 `ConfigService.validate_field_value(project_type, "construction.section_type_code", value)` 校验
- `section_sub_type_code`、`type_id` 继续走配置/类型树校验，不做降级

### 9.3 下拉列表

当前施工下拉接口已经基本同源：

- `/construction/section/type/list`
- `/construction/section/sub/type/list`
- `/construction/task/type/list`

它们当前都来自 `construction_section_config + 类型树`。

本轮目标不是重做接口，而是：

- 让 section 级选项由新的 config 工具统一返回
- 保证下拉、初始化、create 校验继续同源

### 9.4 清理项

construction 领域这轮优先清理的是“section 候选项读取分散”问题，不是一次性重写全部施工结构。

完成后应清理：

- 只负责 section 候选项翻译的旧 helper 直接解析逻辑
- 不再适合作为 section 真源的旧硬编码映射

但下面这些不属于本轮删除目标：

- `ConstructionTypeTree`
- `ConstructionTypeMapping`
- 与节点树生成强绑定的结构化配置

## 10. 测试关注点

construction 领域 service 层集成测试至少覆盖：

1. 初始化：项目初始化后生成的 section / root node / 主施工任务是否来自目标 config。
2. 下拉：section / sub type / task type 列表是否和初始化使用同源配置。
3. Create：合法 `section_type_code`、`section_sub_type_code`、`type_id` 可以创建，非法值明确报错。
