增加重构文档
This commit is contained in:
@@ -0,0 +1,352 @@
|
||||
# Project 领域重构指南
|
||||
|
||||
## 1. 范围
|
||||
|
||||
本文档只做 Project 领域的项目侧梳理。
|
||||
|
||||
必须覆盖两类字段:
|
||||
|
||||
- 集团侧 `enum_config` 对应到 Project 的字段:`project_type`、`project_subtype`、`syxs`、`status`
|
||||
- depm 本地已经做成 enum / 类 enum,或者已经承担初始化、创建校验、业务分支职责的字段:`progress_type`、`key_constraints`、`build_methods`
|
||||
|
||||
本文重点只回答四件事:
|
||||
|
||||
- 当前有几种实现
|
||||
- 模型层怎么存
|
||||
- 是否真的用到了
|
||||
- 创建、校验、初始化时怎么取值,以及下一步怎么改
|
||||
|
||||
## 2. 字段盘点
|
||||
|
||||
### 2.1 `project_type`
|
||||
|
||||
当前实现:
|
||||
|
||||
- `app/common/enums.py` 有一套 `ProjectType`
|
||||
- `app/modules/project/enums.py` 又有一套 `ProjectType`
|
||||
- `Project` 模型里是 `String`
|
||||
- `ProjectCreate` / `ProjectUpdate` 里是 `str`
|
||||
|
||||
当前使用:
|
||||
|
||||
- `ProjectService._init_project_data()` 用它作为初始化路由键,去取 `preparation_{project_type}`、`production_{project_type}`、`power_{project_type}` 等配置
|
||||
- construction 模块的部分接口和工具也直接复用 `ProjectType`
|
||||
|
||||
当前问题:
|
||||
|
||||
- 定义重复
|
||||
- 模型层不是 enum
|
||||
- 创建 / 更新入口没有真正按 enum 校验
|
||||
|
||||
项目侧取值范围:
|
||||
|
||||
- 当前代码里的正式候选项是:`photovoltaic`、`onshore_wind`、`offshore_wind`、`pumped_storage`、`hydropower`、`thermal_power`、`gas_turbine`
|
||||
- `app/common/enums.py`、`app/modules/project/enums.py`、初始化 `dict_data.csv` 当前三处是一致的
|
||||
|
||||
集团侧差异:
|
||||
|
||||
- 当前未看到和项目侧不同的取值项
|
||||
- 这个字段目前可视为两边一致
|
||||
- 但同步 schema 里的 `project_type` 字段当前仍写成 `str`,并没有直接收紧成 `ProjectType`
|
||||
|
||||
结论:
|
||||
|
||||
- 保留为代码 enum
|
||||
- 它是核心路由字段,不迁到 `field_config`
|
||||
|
||||
### 2.2 `project_subtype`
|
||||
|
||||
当前实现:
|
||||
|
||||
- 模型里是 `String`
|
||||
- `ProjectCreate` / `ProjectUpdate` 里是 `str`
|
||||
- 没看到本地正式 enum
|
||||
|
||||
当前使用:
|
||||
|
||||
- 当前主要是项目主表字段
|
||||
- 在 Project 模块内没看到稳定初始化使用点
|
||||
|
||||
当前问题:
|
||||
|
||||
- 没有统一候选项来源
|
||||
- 没有统一校验
|
||||
- 现在只是“字符串字段”
|
||||
|
||||
项目侧取值范围:
|
||||
|
||||
- 目前列不出权威范围
|
||||
- 当前项目侧没有正式 enum、没有 `field_config`、没有 schema 白名单
|
||||
- 从代码看,它现在理论上就是任意字符串
|
||||
|
||||
项目侧可举例范围:
|
||||
|
||||
- 目前只能借集团侧样例来猜测,例如光伏下可能是 `centralized`、`distributed`
|
||||
|
||||
集团侧差异:
|
||||
|
||||
- 集团侧至少给出了光伏下的两个候选项:`centralized`、`distributed`
|
||||
- 项目侧目前一个正式值都没有落下来
|
||||
- 其它项目类型在集团侧也基本还是空占位,所以当前只能确认“项目侧缺正式范围,集团侧只给了局部样例”
|
||||
- 同步 schema 对应字段名是 `sub_type`,当前类型是 `Optional[str]`,也还没有 enum 化
|
||||
|
||||
困难:
|
||||
|
||||
- 项目侧没有正式定义源,无法从代码中反推出完整候选项集合
|
||||
- 集团侧除光伏外也没有给出有效值,导致现在只能列出局部范围,不能写成全项目类型完整表
|
||||
|
||||
结论:
|
||||
|
||||
- 改为 `field_config`
|
||||
- 建议 key:`project.project_subtype`
|
||||
|
||||
### 2.3 `syxs`
|
||||
|
||||
当前实现:
|
||||
|
||||
- 模型里是 `String`
|
||||
- 当前 `ProjectCreate` / `ProjectUpdate` 里没有这个字段
|
||||
- 没看到本地正式 enum
|
||||
|
||||
当前使用:
|
||||
|
||||
- 在 Project 模块内暂时没看到明确创建、初始化或校验使用点
|
||||
- 当前更像是“模型里已有字段,但项目侧链路尚未收敛”的状态
|
||||
|
||||
当前问题:
|
||||
|
||||
- 有字段,但没有统一入口
|
||||
- 没有统一候选项来源
|
||||
- 没有统一校验
|
||||
|
||||
项目侧取值范围:
|
||||
|
||||
- 目前列不出权威范围
|
||||
- 项目模型里有这个字段,但 Project 创建 schema 里没有该字段
|
||||
- 代码中也没找到项目侧正式 enum 或统一校验入口
|
||||
|
||||
项目侧可举例范围:
|
||||
|
||||
- 当前只能参考集团侧海风场景,例如 `hssy`、`lssy`
|
||||
|
||||
集团侧差异:
|
||||
|
||||
- 集团侧至少给出了海风下的两个候选项:`hssy`、`lssy`
|
||||
- 项目侧目前还没有正式范围、正式入口和正式校验
|
||||
- 其它项目类型在集团侧也基本还是空占位,所以当前差异主要是“集团侧有局部定义,项目侧还没落下来”
|
||||
- 同步 schema 中 `syxs` 当前也是 `Optional[str]`,还没有 enum 化
|
||||
|
||||
困难:
|
||||
|
||||
- 项目侧没有正式输入入口,也没有权威候选项定义
|
||||
- 集团侧只有海风场景给了有效值,因此暂时只能列局部范围
|
||||
|
||||
结论:
|
||||
|
||||
- 改为 `field_config`
|
||||
- 建议 key:`project.syxs`
|
||||
|
||||
### 2.4 `status`
|
||||
|
||||
当前实现:
|
||||
|
||||
- `app/modules/project/enums.py` 里有 `ProjectStatus`
|
||||
- `app/common/enums.py` 里也有一套 `ProjectStatus`
|
||||
- 模型里是 `String`
|
||||
- 响应 schema 里是 `str`
|
||||
|
||||
当前使用:
|
||||
|
||||
- `ProjectService.change_project_status()` 会根据 `investment_decision_date`、`actual_construction_date`、`actual_production_date`、`actual_full_production_date` 计算并写回 `status`
|
||||
|
||||
当前问题:
|
||||
|
||||
- 定义重复
|
||||
- 模型层不是 enum
|
||||
- 当前状态值由服务逻辑推导,但接口层没有统一约束
|
||||
- `early` 是否正式存在还没定
|
||||
|
||||
项目侧取值范围:
|
||||
|
||||
- `app/common/enums.py` 和 `app/modules/project/enums.py` 当前都只有 4 个正式值:`preparation`、`started`、`partially_connected`、`completed`
|
||||
- `ProjectService.change_project_status()` 当前实际也只会写入这 4 个值,或者写入 `None`
|
||||
|
||||
集团侧差异:
|
||||
|
||||
- 集团侧比项目侧多一个值:`early`
|
||||
- 其余 `preparation`、`started`、`partially_connected`、`completed` 两边都能对上
|
||||
- 同步 schema 里的 `status` 当前也是 `Optional[str]`,没有正式 enum 类型
|
||||
|
||||
结论:
|
||||
|
||||
- 暂不拍板
|
||||
- 先确认正式状态集合,再决定保留代码 enum 还是转 `field_config`
|
||||
|
||||
### 2.5 `progress_type`
|
||||
|
||||
当前实现:
|
||||
|
||||
- `app/common/enums.py` 和 `app/modules/project/enums.py` 都定义了 `ProgressType`
|
||||
- 模型里是 `SQLEnum(ProgressType)`
|
||||
- `ProjectInfoResponse` 里使用 `ProgressType`
|
||||
- `ProjectCreate` 里仍是 `str`
|
||||
|
||||
当前使用:
|
||||
|
||||
- 是 Project 主表正式字段
|
||||
- `project_detail_data` 初始化时会写入 `progress_type`
|
||||
- 列表筛选也会直接按它查询
|
||||
|
||||
当前问题:
|
||||
|
||||
- 定义重复
|
||||
- 模型层已收紧,但创建入口还没收紧
|
||||
|
||||
项目侧取值范围:
|
||||
|
||||
- 当前正式值是:`A`、`B`、`C`
|
||||
- `app/common/enums.py`、`app/modules/project/enums.py`、初始化 `dict_data.csv` 当前是一致的
|
||||
|
||||
集团侧差异:
|
||||
|
||||
- 集团侧同步 schema 中,`progress_type` 也是正式 enum
|
||||
- 同步 schema 的取值项是:`A`、`B`、`C`
|
||||
- 这一点和项目侧代码 enum 一致
|
||||
- 当前真正的差异不在取值范围,而在项目侧创建入口仍是 `str`,还没有像同步 schema 一样收紧到 enum 类型
|
||||
|
||||
困难:
|
||||
|
||||
- 这个字段属于 depm 本地已枚举化字段,不是集团侧 `Project` 段直出字段
|
||||
- 因此这里只能写“项目侧权威范围明确,集团侧暂无直连字段”
|
||||
|
||||
结论:
|
||||
|
||||
- 保留为代码 enum
|
||||
- 不迁到 `field_config`
|
||||
|
||||
### 2.6 `key_constraints`
|
||||
|
||||
当前实现:
|
||||
|
||||
- `app/common/enums.py` 和 `app/modules/project/enums.py` 都定义了 `KeyConstraints`
|
||||
- 两套定义已分叉:common 里有 `OTHER`,project 模块里没有
|
||||
- 模型里是 `SQLEnum(KeyConstraints)`
|
||||
- `ProjectInfoResponse` 里使用 `KeyConstraints`
|
||||
- `ProjectSquareUpdate` 里还是 `str`
|
||||
|
||||
当前使用:
|
||||
|
||||
- 是 Project 主表正式字段
|
||||
- `project_detail_data` 初始化时会和 `progress_type` 一起写入
|
||||
- `project_detail_data` 审批回写时也会更新 Project 主表
|
||||
|
||||
当前问题:
|
||||
|
||||
- 定义分叉
|
||||
- 主表是 enum,但部分接口入参仍是字符串
|
||||
|
||||
项目侧取值范围:
|
||||
|
||||
- `app/modules/project/enums.py` 当前是 4 个值:`NONE`、`LAND`、`TRANSMISSION`、`BOTH`
|
||||
- `app/common/enums.py` 和初始化 `dict_data.csv` 当前是 5 个值:`NONE`、`LAND`、`TRANSMISSION`、`BOTH`、`OTHER`
|
||||
|
||||
集团侧差异:
|
||||
|
||||
- 集团侧同步 schema 中,`key_constraints` 也是正式 enum
|
||||
- 同步 schema 的取值项是:`NONE`、`LAND`、`TRANSMISSION`、`BOTH`、`QT`
|
||||
- 项目侧 `app/common/enums.py` + 初始化数据当前是:`NONE`、`LAND`、`TRANSMISSION`、`BOTH`、`OTHER`
|
||||
- 项目侧 `app/modules/project/enums.py` 当前是:`NONE`、`LAND`、`TRANSMISSION`、`BOTH`
|
||||
|
||||
可见当前不是“无法对照”,而是至少存在两层明确差异:
|
||||
|
||||
- 集团侧同步 schema 用的是 `QT`
|
||||
- 项目侧本地一处用 `OTHER`,一处甚至没有第五个值
|
||||
|
||||
困难:
|
||||
|
||||
- 项目侧自己就已经分叉,当前无法直接写出唯一正式范围
|
||||
- 在先统一本地定义前,任何“正式取值范围”都只能算候选,不算最终结论
|
||||
|
||||
结论:
|
||||
|
||||
- 保留为代码 enum
|
||||
- 先统一正式定义,再补 schema 校验
|
||||
|
||||
### 2.7 `build_methods`
|
||||
|
||||
当前实现:
|
||||
|
||||
- `app/modules/project/enums.py` 里有 `BuildMethod`
|
||||
- 模型里是 `String`
|
||||
- `ProjectCreate` 里是 `str`
|
||||
- 响应 schema 通过 `enum_to_build_method_name` 做名称映射
|
||||
|
||||
当前使用:
|
||||
|
||||
- construction 服务里确实使用了 `project.build_methods`
|
||||
- 它会影响施工分支判断,例如 `power`、`mixed`、`none`、`self`
|
||||
|
||||
当前问题:
|
||||
|
||||
- 模型层不是 enum
|
||||
- 创建入口不是 enum
|
||||
- 已经参与业务分支,但没有统一校验
|
||||
|
||||
项目侧取值范围:
|
||||
|
||||
- 当前代码 enum 给出的值是:`self`、`power`、`mixed`、`none`
|
||||
- construction 分支判断当前也确实在使用这 4 个值
|
||||
|
||||
集团侧差异:
|
||||
|
||||
- 集团侧同步 schema 里没有 `build_methods` 这个名字,对应字段是 `scgc_type`
|
||||
- `scgc_type` 当前在同步 schema 里是 `Optional[str]`
|
||||
- 目前没有看到同步 schema 中为 `scgc_type` 定义正式 enum
|
||||
|
||||
也就是说:
|
||||
|
||||
- 语义上两边大概率是在说同一个字段
|
||||
- 但集团侧当前还没有把它收紧成正式 enum
|
||||
- 因此这个字段更像“项目侧本地先有 enum,集团侧 schema 还停留在字符串字段”
|
||||
|
||||
困难:
|
||||
|
||||
- 这是项目侧本地业务字段,不是集团侧 `Project` 段直出字段
|
||||
- 项目侧虽然已有 enum,但模型和 schema 还没完全收紧
|
||||
|
||||
结论:
|
||||
|
||||
- 保留为代码 enum
|
||||
- 不迁到 `field_config`
|
||||
- 需要把模型层和 schema 层一起收紧
|
||||
|
||||
## 3. 重点结论
|
||||
|
||||
- `project_type` 是初始化路由键,必须保留为代码 enum。
|
||||
- `project_subtype`、`syxs` 是典型的按项目类型变化字段,应迁到 `field_config`。
|
||||
- `progress_type`、`key_constraints`、`build_methods` 都已经在项目侧真实使用,不是可忽略字段;它们应保留为代码 enum,但当前实现没有收紧干净。
|
||||
- `status` 当前最不稳定,因为它一边像固定状态,一边又还没把正式状态集合收敛清楚。
|
||||
|
||||
## 4. 待修改项清单
|
||||
|
||||
1. 统一 `ProjectType` 定义,只保留一套正式 enum。
|
||||
2. 统一 `ProjectStatus` 定义,并先确认是否正式支持 `early`。
|
||||
3. 统一 `ProgressType` 定义,只保留一套正式 enum。
|
||||
4. 统一 `KeyConstraints` 定义,先确定 `OTHER` 是否保留。
|
||||
5. 将 `project.project_subtype` 改为字段级配置,放入 `field_config`。
|
||||
6. 将 `project.syxs` 改为字段级配置,放入 `field_config`。
|
||||
7. 为 `project_type` 在 schema 层增加正式 enum 校验,不再使用裸 `str`。
|
||||
8. 为 `progress_type` 在创建入口增加正式 enum 校验。
|
||||
9. 为 `build_methods` 在 schema 层增加正式 enum 校验。
|
||||
10. 为 `key_constraints` 在仍使用字符串入参的接口上补 enum 校验。
|
||||
11. 评估 `Project` 模型中的 `project_type`、`status`、`build_methods` 是否要收紧为数据库 enum;如果暂不收紧,也要先统一 schema 校验。
|
||||
12. 为 `project_subtype`、`syxs` 增加统一读取入口:`get_field_options()` / `validate_field_value()`。
|
||||
13. 明确 `status` 的唯一来源:是继续由 `change_project_status()` 推导,还是允许手动写入。
|
||||
14. 明确 `progress_type` / `key_constraints` 在 `project_detail_data` 链路中的正式定义源,避免主表和详情链路再各用一套。
|
||||
|
||||
## 5. 推荐落地顺序
|
||||
|
||||
1. 先统一 `ProjectType`、`ProgressType`、`KeyConstraints`、`ProjectStatus` 的定义源。
|
||||
2. 再补 schema 层校验,把 `project_type`、`progress_type`、`build_methods`、`key_constraints` 的裸字符串入口收紧。
|
||||
3. 再把 `project_subtype`、`syxs` 迁到 `field_config`。
|
||||
4. 最后处理 `status`,因为它依赖正式状态集合先收敛。
|
||||
Reference in New Issue
Block a user