增加重构文档

This commit is contained in:
strepsiades
2026-03-12 14:23:15 +08:00
parent 0ae2db1808
commit 758b1c4f77
16 changed files with 1626 additions and 15 deletions
+7 -4
View File
@@ -2,19 +2,22 @@
## 1. 范围
本文档只讨论 construction 领域中,与集团侧 `enum_config` 对应、且和项目类型初始化有关的字段。
本文档应覆盖 construction 领域中两部分字段的并集:
当前本轮只聚焦一条主线:
- 集团侧 `enum_config` 中 construction 相关的全部字段
- depm 中所有已经使用代码 enum、代码中的初始化列表、硬编码 dict、类 enum、`config` 表、`dict` 表承载,并且会影响施工初始化、手动创建、手动编辑、接口展示或业务校验的相关字段
当前这份文档先给出 construction 领域的总范围和主线判断,再把本轮优先落地对象收敛到一条主线:
- `construction.section_type_code`
以下复杂问题本轮先明确跳过,不在本文展开
以下复杂问题本轮先不展开具体迁移方案,但仍属于 construction 领域后续必须补齐的梳理范围
- `task_id`
- `task_type`
- 其它施工节点层级和映射规则特别复杂的问题
也就是说,施工文档本轮先解决 section 这一层,不强行把 task 相关复杂问题一起收进来
也就是说,施工文档不是永久只看 section,而是本轮先 section 这一层讲清楚,同时把 task 相关复杂问题明确记为后续梳理项,而不是视为领域外问题
## 2. 当前现状
+108
View File
@@ -0,0 +1,108 @@
# Construction Task 领域重构指南
## 1. 范围
本文档对应 backend 的 `construction` 主表,也就是施工任务本体。
当前优先关注:
- `construction.section_type_code`
- `construction.task_type`
- `construction.status`
## 2. 字段盘点
### 2.1 `section_type_code`
当前实现:
- 本地有硬编码 `section_type_id_dict`
- 也有 `construction_section_config` 作为配置来源
- 模型里是 `String`
- 创建 schema 里是 `str`
- 同步 schema 对应字段名是 `construction_section`,类型是 `str`
当前使用:
- 是施工初始化和施工任务分区的关键字段
- construction 服务和 config helper 都直接依赖它
项目侧取值范围:
- 本地明确值:`GF``SY``SC``SCDW`
集团侧差异:
- 当前没看到集团侧 `enum_config` 有独立的 Construction 顶层段
- 同步 schema 里有对应字段,但仍是普通字符串
结论:
- 应迁到 `field_config`
- 继续沿用 `construction.section_type_code`
### 2.2 `task_type`
当前实现:
- 模型里是 `String`
- 创建 schema 里是 `str`
- 本地只有一个层级 enum `ConstructionCategory`,值是 `01``02``0201``03``0301``04``05`
当前使用:
- 施工树和类型树逻辑会使用它
- 但业务任务实际取值往往来自施工树节点,而不只是 `ConstructionCategory`
项目侧取值范围:
- 如果按层级 category 看,明确值是:`01``02``0201``03``0301``04``05`
- 如果按真实任务类型看,当前无法从单一代码 enum 列出完整集合,因为还受施工树/`construction_node_config` 影响
集团侧差异:
- 同步 schema 里 `task_type` 仍是 `str`
- 当前没有看到集团侧 `enum_config` 对这个字段给出统一候选项表
结论:
- 不能简单做成单一代码 enum
- 更适合拆成“层级 category”与“真实任务类型”两层定义
### 2.3 `status`
当前实现:
- 模型里是 `SmallInteger`
- 同步 schema 里是 `Optional[int]`
- 本地有 `progress_status_dict`
项目侧取值范围:
- `-1`
- `0`
- `1`
集团侧差异:
- 当前没看到集团侧 `enum_config` 独立列出 Construction.status
- 同步 schema 仍是 `int`
结论:
- 保留数值状态字段
- 需要统一是走代码常量、dict 映射还是后续字段配置
## 3. 重点结论
- `section_type_code` 是典型的字段级配置候选。
- `task_type` 当前最复杂,不能直接当成一个静态 enum 处理。
- `status` 目前是简单数值状态,但也需要统一正式定义源。
## 4. 待修改项清单
1.`section_type_code` 正式迁到 `field_config`
2. 清理 `section_type_code` 的硬编码 dict 与 config helper 双来源。
3. 拆分 `task_type` 的“层级 category”与“真实任务类型”语义。
4. 明确哪些 `task_type` 值来自施工树,哪些来自配置表。
5.`status` 建立统一常量定义,避免散落数值字面量。
@@ -0,0 +1,89 @@
# Construction Task Detail 领域重构指南
## 1. 范围
本文档对应 backend 的 `construction_detail` 明细表。
当前优先关注:
- `construction_detail.status`
- `construction_detail.approval_status`
- `construction_detail.is_complete`
## 2. 字段盘点
### 2.1 `status`
当前实现:
- 模型里是 `SmallInteger`
- 代码注释已经说明该字段废弃
- 同步 schema 里仍有 `Optional[int] status`
项目侧取值范围:
- 当前无法列出稳定正式范围
- 只能确认它仍是 int 状态字段,且与进度状态相关
集团侧差异:
- 当前没看到集团侧 `enum_config` 为该明细领域单独列值
- 同步 schema 仍保留该字段,说明推送侧还没有完全去掉它
结论:
- 应优先决定是否彻底下线该字段
### 2.2 `approval_status`
当前实现:
- backend 依赖 `ApprovalMixin`,数据库侧是审批状态数值字段
- 同步 schema `construction_detail.py` 用的是 `ApprovalStatus` enum
项目侧取值范围:
- 当前项目侧没有单独的 construction_detail 审批 enum 文件
- 实际范围跟随通用审批体系,不在 construction 模块内独立定义
集团侧差异:
- 同步 schema 已经收紧成 `ApprovalStatus`
- 项目侧 construction_detail 自身还没有独立、清晰的 enum 入口
结论:
- 应统一接入通用审批状态定义
### 2.3 `is_complete`
当前实现:
- 模型里是 `Boolean`
- backend 和 sync schema 都存在
项目侧取值范围:
- `true`
- `false`
集团侧差异:
- 当前没有明显差异
结论:
- 保持布尔字段即可
## 3. 重点结论
- `construction_detail.status` 现在的核心问题不是值域不清,而是字段本身是否还应继续存在。
- `approval_status` 应直接并到通用审批体系,不要在 construction 模块单独再造一套。
- `is_complete` 语义明确,不需要做枚举化改造。
## 4. 待修改项清单
1. 决定 `construction_detail.status` 是否正式废弃。
2. 如果不废弃,补上正式状态定义源。
3.`approval_status` 明确统一到通用审批 enum 体系。
4. 清理明细层里“旧 status”和“审批状态”并存的混乱状态。
+116
View File
@@ -0,0 +1,116 @@
# Contract 领域重构指南
## 1. 范围
本文档只做 Contract 领域的项目侧梳理。
当前优先关注:
- `contract.contract_type`
- `contract.code`
- `contract.currency`
## 2. 字段盘点
### 2.1 `contract_type`
当前实现:
- `app/modules/contract/enums.py` 定义了 `ContractType`
- 取值:`product``service``project`
- `Contract` 模型里是 `String`
- `ContractCreate` 里是 `str | None`
- 同步 schema `schemas/contract/contract.py` 里也是 `str`
当前使用:
- 是合同主表核心分类字段
- 合同结算服务里会按 `contract_type == "project"` 分支处理工程类合同
项目侧取值范围:
- `product`
- `service`
- `project`
集团侧差异:
- 集团侧 `enum_config.Contract.contract_type` 当前只有 `product``service`
- 项目侧比集团侧多一个 `project`
- 同步 schema 当前没有把它收紧成 enum
结论:
- 保留为代码 enum
- 先统一“是否正式保留 `project`
### 2.2 `code`
当前实现:
- 模型里是普通 `String`
- 没有本地正式 enum
- 初始化侧实际依赖 `contract_config` / `contract_code_dict` / `supply_chain_group`
当前使用:
- 初始化合同时,`code` 承担业务子类型编码职责,例如 `EPC``PC``KY``JL`
- 不是单纯的“自由合同编号”
项目侧取值范围:
- 当前无法从单一代码 enum 列出权威全集
- 本地已明确出现的典型值包括:`EPC``PC``PF``CG``OSC``KY``JL``E``SCYW``ZJ``TY``NB``XB``ZB``GS``CN``QT`
集团侧差异:
- 集团侧 `enum_config.Contract.code` 已明确把这类值当成正式候选项,并且按项目类型变化
- 同步 schema 里的 `code` 仍是普通 `str`
- 项目侧现在没有把这组值沉成统一的字段配置或正式 enum
结论:
- 不建议继续当自由字符串处理
- 更适合迁到 `field_config`,或至少统一走配置表来源
### 2.3 `currency`
当前实现:
- 模型里是 `String`
- 默认值 `CNY`
- schema 里是普通字符串
当前使用:
- 当前主要是合同基础信息字段
- 没看到复杂分支逻辑
项目侧取值范围:
- 当前代码里唯一明确值是默认值 `CNY`
集团侧差异:
- 当前没看到集团侧 `enum_config` 对这个字段给出正式候选项
- 同步 schema 里也是 `str`
结论:
- 先保持字符串字段
- 如果未来真的出现多币种,再决定是否需要正式枚举
## 3. 重点结论
- `contract_type` 应保留为代码 enum,但要先明确是否保留 `project`
- `code` 当前实际上承担合同业务子类型职责,不应继续当自由字符串处理。
- `currency` 当前没有足够证据说明要做枚举化。
## 4. 待修改项清单
1. 统一 `ContractType` 的正式定义源。
2. 确认 `contract_type=project` 是否继续作为正式值保留。
3.`contract_type` 在 schema 层补 enum 校验。
4.`contract.code` 从“自由字符串”改成统一配置来源。
5. 评估 `contract.code` 是否直接迁到 `field_config`
6. 区分清楚 `contract.code` 与“合同编号/contract_sn”的职责,避免一个字段同时承担两层语义。
+97
View File
@@ -0,0 +1,97 @@
# Contract Settlement 领域重构指南
## 1. 范围
本文档对应 backend 的 `contract_settlement` 主表。
当前优先关注:
- `contract_settlement.contract_type`
- `contract_settlement.status`
- `contract_settlement.payment_method`
## 2. 字段盘点
### 2.1 `contract_type`
当前实现:
- 模型里是 `String`
- 没有单独 enum 类型绑定到模型
项目侧取值范围:
- 当前主要跟随关联合同的 `contract_type`
- 代码现状至少包含:`product``service``project`
集团侧差异:
- 集团侧 `enum_config.ContractSettlement.contract_type` 当前只有 `product``service`
- 项目侧如果继续沿用 `project`,会比集团侧多一个值
- 当前仓库里没有 standalone 的同步 schema 来收紧这个字段
结论:
- 先与合同主表 `contract_type` 保持一致
- 再确认结算领域是否允许 `project`
### 2.2 `status`
当前实现:
- 模型里是 `SmallInteger`
- 默认值 `0`
项目侧取值范围:
- 当前没有独立 enum 类
- 从集团侧和现有语义看,应至少覆盖 `-1``0``1`
集团侧差异:
- 集团侧 `enum_config.ContractSettlement.status` 明确给出 `-1``0``1`
- 项目侧模型没有沉成统一常量或 enum
结论:
- 应补统一状态定义源
### 2.3 `payment_method`
当前实现:
- 本地 `PaymentMethod` enum 有两个值:`node_payment``progress_payment`
- 模型里仍是 `String`
- `SettlePaymentMethodsSelect` 手动校验合法值
当前使用:
- 合同结算服务会按 `payment_method` 分支校验和处理
项目侧取值范围:
- `node_payment`
- `progress_payment`
集团侧差异:
- 当前没看到集团侧 `enum_config` 为该字段给出正式候选项
- 当前仓库里也没有 standalone 的同步 schema 覆盖该字段
结论:
- 保留为本地代码 enum
- 需要把“手动 validator”提升为统一 schema / service 约束
## 3. 重点结论
- `contract_settlement` 里最稳定的枚举字段是 `payment_method`,应继续保留为代码 enum。
- `contract_type` 不能单独拍板,必须跟合同主表一起决定是否保留 `project`
- `status` 当前只是模型整数,没有正式定义源,需要补齐。
## 4. 待修改项清单
1. 明确 `contract_settlement.contract_type` 是否允许 `project`
2.`status` 补正式常量或 enum 定义。
3.`payment_method` 的合法值校验统一沉到正式 schema/enum,而不是只在个别 schema 手动校验。
4. 明确结算主表与合同主表在 `contract_type` 上是否必须同源。
@@ -0,0 +1,97 @@
# Contract Settlement Detail 领域重构指南
## 1. 范围
本文档对应 backend 的 `contract_settlement_detail` 明细表。
当前优先关注:
- `contract_settlement_detail.payment_type`
- `contract_settlement_detail.advance_type`
- `contract_settlement_detail.approval_status`
## 2. 字段盘点
### 2.1 `payment_type`
当前实现:
- 本地 `PaymentType` enum 定义在 `app/modules/contract/enums.py`
- 取值:`advance``progress``settlement`
- 模型里是 `String`
- `PostDetailData` schema 里已使用 `PaymentType | None`
当前使用:
- 结算服务会按 `payment_type` 分支处理,例如预付款与进度款逻辑不同
项目侧取值范围:
- `advance`
- `progress`
- `settlement`
集团侧差异:
- 当前没看到集团侧 `enum_config` 为结算明细单独列出该字段
- 当前仓库也没有 standalone 的同步 schema 对应 `contract_settlement_detail`
结论:
- 保留为代码 enum
- 这是少数已经在 schema 层显式使用 enum 的字段,应该延续这种做法
### 2.2 `advance_type`
当前实现:
- 本地 `AdvanceType` enum 取值:`project``product``service`
- 模型里是 `String`
- `PostDetailData` schema 里已使用 `AdvanceType | None`
项目侧取值范围:
- `project`
- `product`
- `service`
集团侧差异:
- 当前没看到集团侧 `enum_config` 为该字段给出正式候选项
- 当前仓库也没有 standalone 的同步 schema 对照该字段
结论:
- 保留为代码 enum
### 2.3 `approval_status`
当前实现:
- 模型依赖 `ApprovalMixin`
- 结算明细服务强依赖审批流
项目侧取值范围:
- 当前跟随通用审批状态体系
- 本领域自身没有单独 enum 文件
集团侧差异:
- 当前没看到 standalone 的同步 schema 对这个明细领域建模
结论:
- 接入通用审批定义即可
## 3. 重点结论
- `payment_type``advance_type` 已经是本地相对成熟的代码 enum,用法比结算主表更收敛。
- 这一层不需要优先迁 `field_config`,重点是把模型层和 schema 层收口一致。
- `approval_status` 继续走通用审批定义即可。
## 4. 待修改项清单
1.`payment_type``advance_type` 保持为正式 enum,不要退回自由字符串。
2. 评估模型层是否也要收紧,而不只是 schema 层使用 enum。
3. 明确结算明细审批状态与通用审批体系的正式映射。
+100
View File
@@ -0,0 +1,100 @@
# 项目侧字段分流总表草案
## 1. 目的
这份总表只回答一件事:
- 哪些字段继续保留为代码 enum / 代码常量。
- 哪些字段应迁到 `field_config`
- 哪些字段暂时不能直接收口,必须先补领域边界或映射关系。
## 2. 分流原则
优先按三类处理:
- 保留代码 enum:值域固定、语义稳定、业务分支已直接依赖。
- 迁到 `field_config`:值域跟 `project_type`、初始化模板或业务配置强相关。
- 暂缓收口:当前 backend 与 sync schema 映射不完整,或领域边界本身还没定。
## 3. 总表
| 领域 | 字段 | 当前主要来源 | 建议归类 | 备注 |
| --- | --- | --- | --- | --- |
| project | `project_type` | 代码 enum + 初始化字典 | 保留代码 enum | 核心路由字段 |
| project | `project_subtype` | 自由字符串 | 迁到 `field_config` | 建议 key`project.project_subtype` |
| project | `syxs` | 自由字符串 | 迁到 `field_config` | 建议 key`project.syxs` |
| project | `status` | 代码 enum + 服务推导 | 暂缓收口 | 先确认是否保留 `early` |
| project | `progress_type` | 代码 enum + DB enum | 保留代码 enum | 已与 sync schema 对齐 |
| project | `key_constraints` | 代码 enum 分叉 + DB enum | 暂缓收口 | 先统一 `OTHER/QT` 差异 |
| contract | `contract_type` | 代码 enum | 保留代码 enum | 先确认是否保留 `project` |
| contract | `code` | 初始化字典 / config / 自由字符串 | 迁到 `field_config` | 建议 key`contract.code` |
| contract | `currency` | 自由字符串 | 暂不处理 | 当前仅见 `CNY` |
| construction_task | `section_type_code` | 硬编码 dict + config | 迁到 `field_config` | 建议 key`construction.section_type_code` |
| construction_task | `task_type` | 类型树 + 字符串字段 | 暂缓收口 | 先拆 category 与真实任务类型 |
| construction_task | `status` | 数值字段 + dict | 保留代码常量 | 先统一常量定义源 |
| construction_task_detail | `status` | 旧数值字段 | 暂缓收口 | 先决定是否废弃 |
| construction_task_detail | `approval_status` | 通用审批体系 | 接入通用审批定义 | 不单独建 `field_config` |
| material | `material_type` | 本地列表 + 自由字符串 | 迁到 `field_config` | 建议 key`material.material_type` |
| material | `status` | 数值字段 | 暂缓收口 | 先和 `supply_status` 划边界 |
| material | `supply_status` | 代码 enum | 保留代码常量 | 先确认是否为正式推送字段 |
| material | `approval_party` | 本地候选项 | 暂不处理 | 当前无集团侧对应 |
| material_detail | `kit` | 本地配置字典 | 暂缓收口 | 先确认是否进入推送口径 |
| material_detail | `part` | 自由字符串 | 暂不处理 | 当前更像说明字段 |
| material_detail | `status` | sync schema 有,backend 缺正式来源 | 暂缓收口 | 先补字段来源映射 |
| material_detail | `approval_status` | 通用审批体系 | 接入通用审批定义 | 不单独建 `field_config` |
| contract_settlement | `contract_type` | 跟随合同主表 | 暂缓收口 | 先确认是否允许 `project` |
| contract_settlement | `status` | 数值字段 | 保留代码常量 | 需补统一定义源 |
| contract_settlement | `payment_method` | 代码 enum | 保留代码 enum | 不建议迁 `field_config` |
| contract_settlement_detail | `payment_type` | 代码 enum | 保留代码 enum | schema 已在使用 |
| contract_settlement_detail | `advance_type` | 代码 enum | 保留代码 enum | schema 已在使用 |
| contract_settlement_detail | `approval_status` | 通用审批体系 | 接入通用审批定义 | 不单独建 `field_config` |
| personnel | `personnel_type` | 本地代码常量 | 保留代码 enum | 本地真实领域是人员资质 |
| personnel | `task_type` | 本地候选项常量 | 保留代码常量 | 先补 schema 白名单 |
| personnel | `is_duty` | 数值常量 | 保留代码常量 | 与集团侧 `status` 不是同一字段 |
| personnel_detail | 全领域 | 当前无独立模型 | 暂缓收口 | 先确认领域是否存在 |
| preparation | `code` | 初始化字典 + 自由字符串 | 迁到 `field_config` | 建议 key`preparation.code` |
| preparation | `approval_status` | 通用审批体系 | 接入通用审批定义 | 不单独建 `field_config` |
| preparation | `is_exist` | 布尔字段 | 暂不处理 | 不属于候选项字段 |
| production | `code` | 初始化字典 + 自由字符串 | 迁到 `field_config` | 建议 key`production.code` |
| production | `approval_status` | 通用审批体系 | 接入通用审批定义 | 不单独建 `field_config` |
| production | `is_exist` | 布尔字段 | 暂不处理 | 不属于候选项字段 |
| project_detail_data | `key` | 开放字符串集合 | 暂缓收口 | 先统一 backend key 与 sync key 命名 |
## 4. 第一批建议落地项
优先进入 `field_config` 的字段:
- `project.project_subtype`
- `project.syxs`
- `contract.code`
- `construction.section_type_code`
- `material.material_type`
- `preparation.code`
- `production.code`
优先保留并收紧 schema 的代码 enum 字段:
- `project.project_type`
- `project.progress_type`
- `contract.contract_type`
- `contract_settlement.payment_method`
- `contract_settlement_detail.payment_type`
- `contract_settlement_detail.advance_type`
优先先做边界确认、暂不直接配置化的字段:
- `project.status`
- `project.key_constraints`
- `construction.task_type`
- `material.status`
- `contract_settlement.contract_type`
- `project_detail_data.key`
- `personnel_detail` 全领域
## 5. 使用方式
这份表可以直接作为后续代码改造顺序的输入:
1. 先处理“迁到 `field_config`”的一组字段。
2. 再处理“保留代码 enum,但 schema 还没收口”的一组字段。
3. 最后处理“暂缓收口”的结构性问题字段。
+127
View File
@@ -0,0 +1,127 @@
# Material 领域重构指南
## 1. 范围
本文档只做 Material 主表梳理。
当前优先关注:
- `material.material_type`
- `material.status`
- `material.supply_status`
- `material.approval_party`
## 2. 字段盘点
### 2.1 `material_type`
当前实现:
- 本地没有独立 enum 类
- 主要来源是 `contract_product_type_list`
- 模型里是 `String`
- 创建 schema 里是 `str`
- 同步 schema 里也是 `str`
当前使用:
- 是物资主类型字段
- schema 示例和业务逻辑都直接依赖 `contract_product_type_list`
项目侧取值范围:
- 当前本地明确值:`TY``ZJ``NB``XB``ZB``GS``CN``DL``XT``CBJDB``SX``ECXT``QT`
集团侧差异:
- 集团侧 `enum_config.Material.material_type` 是按项目类型变化的
- 光伏下有:`ZJ``TY``NB``XB``ZB``GS``CN``QT`
- 陆风/海风下有:`FJ``TT``XB``ZB``GS``CN``QT`
- 项目侧当前使用的本地列表明显偏光伏,且代码里还存在命名差异:例如本地用 `XT` / `CBJDB` / `SX` / `ECXT`,集团侧常见的是 `35KV` / `CYJD` / `SVG` / `ECPG`
- 同步 schema 里 `material_type` 仍是 `str`
结论:
- 应迁到 `field_config`
- 不能继续只靠本地 `contract_product_type_list`
### 2.2 `status`
当前实现:
- 模型里是 `SmallInteger`
- 同步 schema 里是 `Optional[int]`
项目侧取值范围:
- 当前未看到单独 enum 类
- 现有注释和使用都表明它是数值状态字段
集团侧差异:
- 集团侧 `enum_config.Material.status` 给的是 `-1``0``1`
- 项目侧没有在 material 模块里沉成统一常量
结论:
- 应统一正式状态定义源
### 2.3 `supply_status`
当前实现:
- 模型里是 `SmallInteger`
- 本地有 `SupplyStatus` enum`-1``0``1``None`
项目侧取值范围:
- `-1`
- `0`
- `1`
- `None`
集团侧差异:
- 集团侧 Material.status 也是按 `-1``0``1` 表达进度状态
- 项目侧存在 `status``supply_status` 两个相近字段,语义有重叠
结论:
- 需要明确 `status``supply_status` 哪个才是正式推送字段
### 2.4 `approval_party`
当前实现:
- 模型里是 `String`
- schema 里是 `str`
- 当前示例值是 `jiagong``yigong`
项目侧取值范围:
- `jiagong`
- `yigong`
集团侧差异:
- 当前没看到集团侧 `enum_config` 对这个字段给出正式候选项
- 同步 schema 里也没有这个字段
结论:
- 先保留本地代码级候选项
- 后续如需推送再决定是否外提
## 3. 重点结论
- `material_type` 是标准的 `field_config` 候选字段,不能再继续绑死在本地光伏型列表上。
- `status``supply_status` 当前语义重叠,必须先定正式推送字段。
- `approval_party` 暂时还是本地专有字段,不需要现在就硬并到集团侧。
## 4. 待修改项清单
1.`material_type` 正式迁到 `field_config`
2. 按项目类型重建 `material_type` 候选项,不再只用本地光伏型列表。
3. 统一 `35KV/XT``CYJD/CBJDB``SVG/SX``ECPG/ECXT` 这类命名差异。
4. 明确 `status``supply_status` 的职责边界。
5.`material_type` 在 schema 层增加统一校验入口。
+109
View File
@@ -0,0 +1,109 @@
# Material Detail 领域重构指南
## 1. 范围
本文档对应 backend 的 `material_detail` 明细表。
当前优先关注:
- `material_detail.kit`
- `material_detail.part`
- `material_detail.status`
- `material_detail.approval_status`
## 2. 字段盘点
### 2.1 `kit`
当前实现:
- 模型里是 `String`
- 本地候选项来自 `kit_part_dict`
- 没有独立 enum 类
项目侧取值范围:
- 当前本地明确值包括:`TY``ZJ``LZ``XC``ZT``NB``XB``ZB``GS``CN``PCS``DCC``35KV``CYJD``SVG``DL``35-DL``10-DL``400DL``two-DL``TXDL``GX``WX``ECPG``QT`
集团侧差异:
- 集团侧没有独立的 `MaterialDetail` 顶层段
- 同步 schema `material_detail.py` 里也没有 `kit` 字段
结论:
- 当前是本地专有字段
- 先保留配置字典来源
### 2.2 `part`
当前实现:
- 模型里是 `String`
- 没有统一 enum 或配置表
项目侧取值范围:
- 当前无法列出稳定范围
- 更像是自由文本/部件说明字段
集团侧差异:
- 当前没看到同步 schema 或集团侧 `enum_config` 给出对应候选项
结论:
- 暂不枚举化
### 2.3 `status`
当前实现:
- backend 明细模型没有显式业务 status 字段
- 同步 schema `material_detail.py``status: Optional[int]`
项目侧取值范围:
- 当前无法从 backend `material_detail` 模型中列出正式取值范围
集团侧差异:
- 同步 schema 仍保留该字段
- backend 当前没有同名正式字段,存在领域映射缺口
结论:
- 需要先确认推送时该字段来源到底是 material 主表还是 detail 明细计算值
### 2.4 `approval_status`
当前实现:
- backend 依赖 `ApprovalMixin`
- 同步 schema 使用 `ApprovalStatus` enum
项目侧取值范围:
- 当前 material_detail 自身没有独立审批 enum 文件
- 依赖通用审批体系
集团侧差异:
- 同步 schema 已经显式收紧为审批 enum
结论:
- 统一接入通用审批 enum 即可
## 3. 重点结论
- `material_detail` 当前不是一个干净的“可直接枚举化”领域,最大的缺口是 backend 与 sync schema 的字段映射不完整。
- `kit` 可以继续保留为本地候选项来源,但是否外提到 `field_config` 取决于后续是否进入推送口径。
- `status` 必须先确认正式来源,否则不能直接做字段级配置。
## 4. 待修改项清单
1. 明确 `kit` 是否需要单独迁成字段配置。
2. 明确 `part` 是否继续保留自由文本。
3. 明确 `material_detail.status` 在 backend 的正式来源。
4.`approval_status` 与通用审批状态定义彻底对齐。
+105
View File
@@ -0,0 +1,105 @@
# Personnel 领域重构指南
## 1. 范围
当前仓库里没有独立的 `personnel` 项目业务模块。
最接近的本地实现是:
- `app/modules/safety/models/safety_personnel_qualification.py`
- `app/modules/safety/schemas/personnel_qualification.py`
因此本文档先按“人员资质”这一真实落点梳理,而不是假设仓库里已经有独立 `personnel` 主表。
当前优先关注:
- `personnel_type`
- `task_type`
- `is_duty`
## 2. 字段盘点
### 2.1 `personnel_type`
当前实现:
- 模型里通过类常量定义两个值:`safe``special`
- 模型字段本身是 `String`
- schema 里仍是 `str`
项目侧取值范围:
- `safe`
- `special`
集团侧差异:
- 集团侧 `enum_config.Personnel` 里并没有 `personnel_type`
- 集团侧更像是在描述“人员/吊装设备”等资源配置编码,而不是人员资质类型
- 当前仓库里也没有 standalone 的 sync schema 对这个领域建模
结论:
- 这是本地代码级 enum 字段
- 可保留为代码 enum
### 2.2 `task_type`
当前实现:
- 模型里通过 `PERSONNEL_TASK_TYPE` 类常量给出候选项
- 字段本身是 `String`
- schema 里仍是 `str`
项目侧取值范围:
- `电工`
- `焊工`
- `高空作业人员`
- `无人机操作员`
- `其他`
集团侧差异:
- 集团侧 `enum_config.Personnel` 没有这个字段
- 当前仓库里也没有 sync schema 对应
结论:
- 这是本地代码级候选项字段
- 可以保留为代码常量,但要补 schema 校验
### 2.3 `is_duty`
当前实现:
- 模型里通过类常量定义:`1` 在场,`2` 退场
- 字段本身是 `SmallInteger`
- schema 里是 `int`
项目侧取值范围:
- `1`
- `2`
集团侧差异:
- 集团侧 `enum_config.Personnel.status` 给的是 `-1``0``1`
- 这更像资源进度状态,不是本地 `is_duty` 语义
- 两边不是同一字段,不应强行对齐
结论:
- 保留为本地数值常量字段
## 3. 重点结论
- 当前所谓 `personnel` 领域,在本地真实落点是“人员资质”,不是集团侧 `Personnel` 那套资源配置模型。
- 因此这里最重要的不是照抄集团侧,而是先承认两个系统的领域边界不一致。
## 4. 待修改项清单
1. 明确 `personnel` 在本地的正式领域名是否就是 `safety_personnel_qualification`
2.`personnel_type` 补正式 enum/schema 校验。
3.`task_type` 补统一白名单校验。
4. 不要把集团侧 `Personnel.code/status` 直接映射到本地 `personnel_type/is_duty`
+29
View File
@@ -0,0 +1,29 @@
# Personnel Detail 领域重构指南
## 1. 范围
本文档对应用户要求中的 `personnel_detail` 领域。
## 2. 当前状态
当前仓库里没有独立的 `personnel_detail` backend 模型,也没有对应的 sync schema。
本地目前只有:
- `safety_personnel_qualification` 单表实现
也就是说,当前系统没有“人员主表 + 人员明细表”的正式拆分。
## 3. 重点结论
- 现阶段不建议凭空定义 `personnel_detail` 的取值域重构方案。
- 如果后续业务真的需要这一层,应先明确它到底对应:
- 人员证书明细
- 进退场记录
- 还是资源配置明细
## 4. 待修改项清单
1. 先确认 `personnel_detail` 是否真的是一个独立领域。
2. 如果是,先补正式模型与 sync schema,再讨论 enum/field_config。
+44 -11
View File
@@ -344,26 +344,58 @@ async def validate_field_value(
主计划只定义系统级方案。具体领域的梳理应拆到独立文件,例如:
- [construction.md](/Users/zyl/my_projects/ecm_sync_system/docs/enum_refactor/construction.md)
- [project.md](/Users/zyl/my_projects/ecm_sync_system/docs/enum_refactor/project.md)
后续 project / contract / material 等领域也应按同样方式分别整理。
后续 contract / material 等领域也应按同样方式分别整理。
每个领域文档都不是只看“集团侧已有字段”或者“准备迁到 `field_config` 的字段”。
每个领域都必须同时覆盖两部分字段:
- depm 中所有已经使用以下来源之一的字段:代码 enum、代码中的初始化列表、硬编码 dict、类 enum、`config` 表、`dict`
- 集团侧 `enum_config` 中该领域涉及的全部字段
两部分做并集,不做交集。
也就是说:
- `enum_config` 中出现的字段,必须全部纳入领域文档
- 即使某字段暂时没有出现在 `enum_config` 中,只要 depm 已经在用代码 enum / 类 enum / 初始化列表 / 硬编码 dict / `config` 表 / `dict` 表承载它,并且它影响初始化、手动创建、编辑、校验、展示,也必须纳入领域文档
这里要特别避免一种错误写法:
- 不能把领域范围写成“只讨论和集团侧 `enum_config` 直接对应的字段”
- 不能因为某字段暂时只有 depm 本地 enum / 类 enum,而集团侧还没有对应项,就把它排除在领域文档之外
每个领域文档都应至少覆盖以下内容:
### 8.1 整理不查表的 enum 类数据
### 8.1 先做字段总表
每个领域文档开头都应先列出字段总表,至少回答:
- 集团侧 `enum_config` 覆盖了哪些字段
- depm 侧当前还额外维护了哪些相关字段
- 每个字段当前使用的来源是什么:代码 enum、初始化列表、硬编码 dict、类 enum、`config` 表、`dict` 表,或它们的混用
- 每个字段分别影响哪些链路:项目初始化、手动创建、手动编辑、接口展示、历史数据兼容、业务校验
如果同一个字段在多个来源重复定义,也必须明确记出来,而不是只记录“最终准备保留哪个”。
### 8.2 整理不查表的 enum 类数据
不是只有查表型数据才需要整理。
如果某领域存在不依赖字典表、也不依赖 config 表的纯 enum / 纯硬编码候选项,同样要梳理:
如果某领域存在不依赖字典表、也不依赖 `config` 表的纯 enum / 纯硬编码候选项,同样要梳理:
- 当前定义位置在哪
- 是否重复定义
- 是否和集团侧 `enum_config` 对应字段有关
- 是否参与初始化、手动创建、手动编辑、展示翻译或历史校验
- 是否需要继续保留为代码 enum
- 是否应该迁到新的 `field_config`
也就是说,纯 enum 数据如果和初始化字段、手动创建字段有关,也在本轮视野内。
### 8.2 梳理哪些功能需要迁移到新的 `field_config`
### 8.3 梳理哪些功能需要迁移到新的 `field_config`
每个领域都需要明确列出:
@@ -371,6 +403,7 @@ async def validate_field_value(
- 哪些手动创建 / 编辑功能依赖字段候选项
- 哪些历史白名单校验需要迁移到 `validate_field_value()`
- 哪些直接遍历旧 JSON 的逻辑需要迁移到 `get_field_options()` / `get_field_option_map()`
- 哪些字段虽然目前由 `dict` 表或代码 enum 承载,但实际上已经在承担“按项目类型变化的候选项字段”职责
并且必须给出示例。
@@ -380,17 +413,17 @@ async def validate_field_value(
- 手动创建时从硬编码 dict 判断合法值,改为调用 `validate_field_value()`
- 展示名称时从字段选项里直接拿 `label`
### 8.3 重点关注集团侧 `enum_config` 对应字段
### 8.4 必须完整对齐集团侧 `enum_config`
领域梳理时,应优先关注集团侧 `enum_config` 中已有对应关系的字段。
领域梳理时,不能只挑 depm 里已经处理过的字段,也不能只挑“看起来最容易改”的字段。
因为这类字段本身就属于
每个领域都必须把集团侧 `enum_config` 中该领域涉及的字段逐一对齐到 depm,明确说明它现在处于哪一种状态
- 按项目类型变化
- 会参与初始化
- 通常也会参与手动创建与校验
- depm 已有同名或同语义字段,并且来源清晰
- depm 有近似字段,但命名、语义、来源或取值范围不完全一致
- depm 还没有正式落点,只能先记录缺口
因此,每个领域都应围绕这类字段检查两条链路:
对齐 `enum_config` 时,每个字段都应继续检查两条链路:
- 项目初始化时,取值从哪里来,如何展开
- 手动创建 / 更新时,取值如何校验,是否和初始化使用同一来源
+89
View File
@@ -0,0 +1,89 @@
# Preparation 领域重构指南
## 1. 范围
本文档对应 backend 的 `preparation` 里程碑节点表。
当前优先关注:
- `preparation.code`
- `preparation.approval_status`
- `preparation.is_exist`
## 2. 字段盘点
### 2.1 `code`
当前实现:
- 模型里是 `String`
- 没有本地 enum 类
- 项目初始化时,节点集合来自 `preparation_{project_type}` 字典数据
- 同步 schema `project_extensions/preparation.py` 里也是 `str`
项目侧取值范围:
- 当前无法从单一代码 enum 列出完整范围
- 已知典型值包括:`JSZB``HZBA``KYNS``TZJC``YDYS``LCPF``YDPF``JRPF``HPPF``SGXK``SBPF`
集团侧差异:
- 集团侧 `enum_config.Preparation.code` 已明确把该字段作为按项目类型变化的正式候选项
- 本地当前仍主要靠初始化字典/字符串承载
结论:
- 更适合迁到 `field_config`
- 不应继续只靠初始化字典和自由字符串
### 2.2 `approval_status`
当前实现:
- backend 依赖 `ApprovalMixin`
- 本地 `PreparationApproval` schema 仍使用 int
- 同步 schema `PreparationDetail` 里是 `Optional[str]`
项目侧取值范围:
- 当前本地未在 preparation 模块中沉成独立 enum
集团侧差异:
- 同步 schema 有字段,但没有正式 enum
结论:
- 应统一接入通用审批状态体系
### 2.3 `is_exist`
当前实现:
- 模型里是 `Boolean`
- backend 和 sync schema 均有该字段
项目侧取值范围:
- `true`
- `false`
集团侧差异:
- 当前没看到 enum_config 对这个字段给出候选项
结论:
- 保持布尔字段即可
## 3. 重点结论
- `preparation.code` 是标准的初始化候选项字段,最适合迁到 `field_config`
- `approval_status` 不需要在本领域单独发明枚举,应直接接入通用审批体系。
- `is_exist` 是布尔存在性字段,不在本轮字段级配置重点内。
## 4. 待修改项清单
1.`preparation.code` 正式迁到 `field_config`
2. 区分“节点编码范围”与“审批状态/存在性”这两类字段,不要混在一个配置源里。
3.`approval_status` 接入通用审批状态定义。
+88
View File
@@ -0,0 +1,88 @@
# Production 领域重构指南
## 1. 范围
本文档对应 backend 的 `production` 投产节点表。
当前优先关注:
- `production.code`
- `production.approval_status`
- `production.is_exist`
## 2. 字段盘点
### 2.1 `code`
当前实现:
- 模型里是 `String`
- 没有本地 enum 类
- 项目初始化时,节点集合来自 `production_{project_type}` 字典数据
- 同步 schema `project_extensions/production.py` 里也是 `str`
项目侧取值范围:
- 当前无法从单一 enum 文件列出完整范围
- 已知典型值包括:`SYZDSD``SPBW``QBBW``KHWC240``YJSC``DBTC``CQZS``WGJS``JGJS`
集团侧差异:
- 集团侧 `enum_config.Production.code` 已把该字段按项目类型列成正式候选项
- 本地仍主要靠初始化字典和自由字符串
结论:
- 更适合迁到 `field_config`
### 2.2 `approval_status`
当前实现:
- backend 依赖 `ApprovalMixin`
- 本地 `ProductionApproval` schema 仍使用 int
- 同步 schema `ProductionDetail` 里是 `Optional[str]`
项目侧取值范围:
- 当前本地未在 production 模块中沉成独立 enum
集团侧差异:
- 同步 schema 有字段,但没有正式 enum
结论:
- 应统一接入通用审批状态体系
### 2.3 `is_exist`
当前实现:
- 模型里是 `Boolean`
- backend 和 sync schema 都有
项目侧取值范围:
- `true`
- `false`
集团侧差异:
- 当前没看到 enum_config 对该字段给候选项
结论:
- 保持布尔字段即可
## 3. 重点结论
- `production.code``preparation.code` 一样,属于典型的初始化节点编码字段,应迁到 `field_config`
- `approval_status` 仍应走通用审批体系,而不是 production 自己维护一套值域。
- `is_exist` 不属于本轮需要抽成字段候选表的重点字段。
## 4. 待修改项清单
1.`production.code` 正式迁到 `field_config`
2. 将项目初始化里对 `production_{project_type}` 的依赖逐步收敛到统一字段配置入口。
3.`approval_status` 接入通用审批状态定义。
+352
View File
@@ -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`,因为它依赖正式状态集合先收敛。
+69
View File
@@ -0,0 +1,69 @@
# Project Detail Data 领域重构指南
## 1. 范围
本文档对应 backend 的 `project_detail_data` 聚合明细表。
当前优先关注:
- `project_detail_data.key`
## 2. 字段盘点
### 2.1 `key`
当前实现:
- backend 模型里是 `String`
- backend schema 里也是 `str`
- 没有本地正式 enum
- 实际取值由 `ProjectDetailDataService` 和业务逻辑共同决定
项目侧取值范围:
- 当前代码里明确出现的 key 至少包括:
- `authorized_capacity`
- `investment_decision_capacity`
- `plan_construction_capacity`
- `actual_construction_capacity`
- `key_constraints`
- `constructing_capacity`
- `production_capacity`
- `ensure_production_capacity`
- `climb_production_capacity`
- `challenge_production_capacity`
- `dynamic_total_investment_price`
- `complete_investment_price`
- `complete_investment_rate`
- `qualified_production_score`
集团侧差异:
- 同步 schema `project_extensions/project_detail.py` 已定义了 `ProjectDetailKey` enum
- 同步 schema 当前只有 7 个 key
- `plan_construction`
- `actual_construction`
- `production`
- `ensure_production`
- `climb_production`
- `challenge_production`
- `complete_investment`
- 项目侧和同步侧当前不仅数量不一致,命名也不一致
结论:
- 这是当前差异最大的领域之一
- 不能直接把 backend `key` 当成已经对齐的枚举字段
## 3. 重点结论
- backend `project_detail_data.key` 当前是开放字符串集合。
- 同步侧已经有一套更收敛的 `ProjectDetailKey` enum。
- 两边差异不只是“少几个值”,而是命名体系都还没统一。
## 4. 待修改项清单
1.`project_detail_data.key` 建立正式定义表,不再继续开放字符串。
2. 明确 backend key 与同步 `ProjectDetailKey` 的映射关系。
3. 区分哪些 key 应继续保留在 `project_detail_data`,哪些应回归 Project 主表或扩展表。
4. 先统一命名,再决定是否直接迁成代码 enum 或 `field_config`