14 KiB
14 KiB
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有一套ProjectTypeapp/modules/project/enums.py又有一套ProjectTypeProject模型里是StringProjectCreate/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里有ProjectStatusapp/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 - 当前库里还存在
NULL,这说明状态机和历史数据都还没收口干净
项目侧取值范围:
- 目标正式值应为:
early、preparation、started、partially_connected、completed - 当前代码定义和服务推导还没有完整覆盖这 5 个值
- 当前实际数据里还存在
NULL,这应视为待清理异常值,而不是正式取值
集团侧差异:
- 项目侧最终也要纳入
early - 因此这个字段的目标差异不是“是否要 early”,而是“项目侧何时补齐 early 并清掉 NULL”
- 同步 schema 里的
status当前也是Optional[str],没有正式 enum 类型
结论:
- 保留为代码 enum
- 正式状态集合按
early、preparation、started、partially_connected、completed收口 NULL不是正式值,必须通过数据修复和状态回填消除
2.5 progress_type
当前实现:
app/common/enums.py和app/modules/project/enums.py都定义了ProgressType- 模型里是
SQLEnum(ProgressType) ProjectInfoResponse里使用ProgressTypeProjectCreate里仍是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里使用KeyConstraintsProjectSquareUpdate里还是str
当前使用:
- 是 Project 主表正式字段
project_detail_data初始化时会和progress_type一起写入project_detail_data审批回写时也会更新 Project 主表
当前问题:
- 定义分叉
- 主表是 enum,但部分接口入参仍是字符串
- 项目侧正式口径应保留
OTHER
项目侧取值范围:
- 项目侧正式值应为:
NONE、LAND、TRANSMISSION、BOTH、OTHER - 当前
app/common/enums.py和初始化dict_data.csv已包含这 5 个值 - 当前
app/modules/project/enums.py还少OTHER
集团侧差异:
- 集团侧同步 schema 中,
key_constraints也是正式 enum - 同步 schema 的取值项是:
NONE、LAND、TRANSMISSION、BOTH、QT - 项目侧正式口径保留
OTHER - 这里需要备注的差异只有一条:集团侧用
QT,项目侧用OTHER
结论:
- 保留为代码 enum
- 项目侧按
OTHER收口 - 在同步和推送链路上单独备注
OTHER/QT差异 - 同时补齐 project 模块那套缺失的
OTHER
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也应保留为代码 enum,正式集合必须包含early,并且要清掉历史NULL。key_constraints项目侧正式口径保留OTHER,只需要在文档和同步链路上备注集团侧使用QT。
4. 待修改项清单
- 统一
ProjectType定义,只保留一套正式 enum。 - 统一
ProjectStatus定义,并把early纳入正式状态集合。 - 统一
ProgressType定义,只保留一套正式 enum。 - 统一
KeyConstraints定义,项目侧正式保留OTHER。 - 将
project.project_subtype改为字段级配置,放入field_config。 - 将
project.syxs改为字段级配置,放入field_config。 - 为
project_type在 schema 层增加正式 enum 校验,不再使用裸str。 - 为
progress_type在创建入口增加正式 enum 校验。 - 为
build_methods在 schema 层增加正式 enum 校验。 - 为
key_constraints在仍使用字符串入参的接口上补 enum 校验。 - 清理
Project.status的历史NULL数据,并补状态回填逻辑,确保NULL不再出现。 - 评估
Project模型中的project_type、status、build_methods是否要收紧为数据库 enum;如果暂不收紧,也要先统一 schema 校验。 - 为
project_subtype、syxs增加统一读取入口:get_field_options()/validate_field_value()。 - 明确
status的唯一来源:是继续由change_project_status()推导,还是允许手动写入。
5. 推荐落地顺序
- 先统一
ProjectType、ProgressType、KeyConstraints、ProjectStatus的定义源。 - 再补 schema 层校验,把
project_type、progress_type、build_methods、key_constraints的裸字符串入口收紧。 - 先补
status=early和历史NULL清理,再把project_subtype、syxs迁到field_config。
6. 按本轮要求的改造落点
project 领域这轮要区分两类字段:
- 固定语义枚举:继续保留代码 enum
- 按项目类型变化的候选项:迁到 field config
6.1 初始化
Project 本身不直接批量初始化子表候选项,但 project_type 是整个初始化流程的路由键。
因此本轮在 project 领域的初始化要求是:
project_type继续保留代码 enum,作为 config 路由键project_subtype、syxs如果进入初始化或默认值链路,应直接从 field config 读取
6.2 Create / Update 校验
这轮 project 领域要分开处理:
project_type、status、progress_type、key_constraints、build_methods:继续按代码 enum 收紧project_subtype、syxs:通过新的 config 工具校验
也就是说,project 领域不是“全部配置化”,而是“固定 enum 和 field config 分流后分别收紧”。
6.3 下拉列表
当前 project 领域里:
project_type、progress_type、key_constraints、build_methods更适合继续由代码 enum 提供候选项project_subtype、syxs后续如果提供前端下拉,应直接走 field config
本轮目标是明确边界,避免把本地固定枚举误迁到 config,也避免把按项目类型变化字段继续留成自由字符串。
6.4 清理项
project 领域本轮改造完成后,应清理:
- 重复的 enum 定义源
- 仍以裸字符串接收固定 enum 字段的入口
status历史NULL值
7. 测试关注点
project 领域 service 层集成测试至少覆盖:
project_type、progress_type、key_constraints、build_methods的合法/非法值校验。project_subtype、syxs的 field config 读取与校验。status状态推导补齐early且不再产生NULL。