Files
zkxw/docs/dev-field-consistency.md
T
zlwu b220298f89 chore: 清理历史资料并规范工程目录与开发规则
为减少仓库噪声和重复规则,整理当前开发入口并移除已废弃资料。

- 精简根 AGENTS,补充四个应用规则与 README,统一规范入口
- 归整部署文件、SOP 原稿和参考资源,修正迁移后的脚本路径
- 取消虚拟环境、工具状态、业务导出及备份的跟踪,本机所需原件保留
- 移除停用的 graphify 配置、脚本与产物
- 删除历史业务文档、执行计划、OpenSpec 业务变更和移动 UI 原型
- 清理失效引用,历史细胞产品导入改为必须显式指定 --file

验证:git diff --cached --check、OpenSpec 严格校验、导入参数隔离检查 3/3 通过;
迁移文件完整性和现行链接已核对。未执行部署、业务数据导入或服务启停。
2026-10-29 23:08:29 +08:00

3.9 KiB
Raw Blame History

字段一致性开发指南

问题背景

在前后端全链路开发中,一个字段需要同时出现在 5 个位置 才能完整打通:

前端 formData → API Schema (Pydantic) → API Handler 传参 → CRUD 函数签名 → ORM 赋值

任何一层遗漏都会导致字段静默丢失(Pydantic 默认忽略未定义字段,不报错),产生难以发现的 bug。

历史问题

时间 问题 根因
2026-05 耗材/试剂新增时 warning_qty 未保存 Schema 缺字段 → Handler 没传 → CRUD 没接
2026-05 耗材/试剂新增时 status 未保存 同上
2026-05 变动记录筛选"出库"无效 前端 value 与后端期望值不匹配

开发纪律(MUST)

1. _row_to_dict 是单一真相源

CRUD 文件中的 _row_to_dict 函数定义了实体返回给前端的所有可读字段。它是字段一致性的基准。

2. 先写 _row_to_dict,再写 create/update

新增实体时:

  1. 先定义 _row_to_dict,列出所有字段的读取逻辑
  2. 根据 _row_to_dict 的字段列表,逐字段编写 CreateBody/UpdateBody
  3. 根据 Schema 字段,逐字段编写 create/update 函数签名和 ORM 赋值
  4. 根据后端字段列表,编写前端 formData

3. 排除只读字段

以下字段出现在 _row_to_dict 中但不需要出现在 CreateBody/UpdateBody 或 formData 中:

  • id — 自动生成
  • createTime / updateTime — 自动维护
  • stockQty — 通过出入库操作维护,不可直接设置
  • tenantNo — 从认证上下文获取

4. 每个字段必须检查的 5 个位置

以 warningQty 为例:

位置 代码 必须
_row_to_dict "warningQty": _dec(c.warning_qty) ✅ 读取
CreateBody warning_qty: Optional[float] = Field(0, alias="warningQty") ✅ 接收
Handler warning_qty=body.warning_qty ✅ 传递
create 函数签名 warning_qty: Optional[float] = None ✅ 接收
create ORM 赋值 warning_qty=warning_qty if warning_qty is not None else 0 ✅ 写入

5. 实现后验证

每个实体完成后运行:

python backend/scripts/check_field_consistency.py

检查项:

  • _row_to_dict 中的可写字段是否都在 CreateBody/UpdateBody 中
  • _row_to_dict 中的可写字段是否都在前端 formData 中
  • 前后端字段值映射是否一致(如筛选条件 value 对应关系)

校验脚本

backend/scripts/check_field_consistency.py 自动扫描以下三层,输出 diff 报告:

  1. CRUD 层:提取 _row_to_dict 的所有 camelCase key
  2. API 层:提取 CreateBody/UpdateBody 的所有字段(含 alias)
  3. 前端层:提取 formData 的所有 key

使用方式

# 检查所有注册实体
python backend/scripts/check_field_consistency.py

# 检查单个实体
python backend/scripts/check_field_consistency.py --entity consumable

# JSON 格式输出
python backend/scripts/check_field_consistency.py --json

退出码

  • 0:所有检查通过
  • 1:发现字段不一致

常见陷阱

  1. alias 遗漏:Schema 字段有 alias="warningQty" 但忘记写,Pydantic 只接受 snake_case 键名
  2. Handler 传参遗漏:Schema 有字段但 Handler 没传给 CRUD,字段在 Schema 层就被丢弃
  3. CRUD 签名遗漏:Handler 传了但 CRUD 函数签名没接收,Python 会报 unexpected keyword argument(运行时错误)
  4. 前端 value 与后端不匹配:如筛选条件下拉框的 value 是 "use" 但后端期望 "out"

当前检查器覆盖限制

检查器仅覆盖注册实体。material (market) 注册的 web-admin/src/views/market/material/index.vue 和 qc_material 注册的 web-admin/src/views/quality/material/index.vue 已失效;执行结果必须区分既有路径问题与本次改动,不能据检查器通过认定所有实体均已覆盖。