Skip to content

finding(fields): MasterDetailField 是公开导出但表单路径到不了的孤儿 —— master_detail 键指向 LookupField,仓内唯一消费者是它自己的测试 #4811

Description

@yinlianghui

观察类(observation-class):今天没有用户会撞上,只是一份记录 —— 在 #4788 的 32 个 widget 形态扫描里,这个 widget 的读数怎么量都对不上「表单里能渲染出来的东西」,查下去发现表单路径根本到不了它。

实测

packages/fields/src/index.tsxfieldWidgetMap:

'master_detail': () => import('./widgets/LookupField').then(m => ({ default: m.LookupField })),

master_detail 这个键指向的是 LookupField,不是 MasterDetailField(map 上方的注释把原因写清楚了:子侧的 FK 在创建/编辑表单里必须渲染成单值 lookup picker,旧的一对多列表模型不正确)。所以:

  • registerField('master_detail') / registerAllFields() 注册进 field:master_detail 的是 LookupField;
  • fieldWidgetMap没有任何键指向 MasterDetailField;
  • 仓内 grep,MasterDetailField 的消费者只有两处:packages/fields/src/index.tsx 末尾的 export * from './widgets/MasterDetailField'(公开导出),和 packages/fields/src/complex-widgets.test.tsx(它自己的测试,直接 render(...),不经表单)。

即:它是一个公开 API 面上仍然存在、但本仓任何渲染路径都到不了的 widget,且其测试只证明它自己能渲染,不证明任何人会渲染它。

为什么现在只是记录,不是缺陷

没有用户可见的失效:master_detail 字段今天渲染 LookupField,这是有意为之且正确。真正的成本是下一个读代码的人——它带 readonly 分支、带 ...props、长得和别的 widget 一模一样,任何按 packages/fields/src/widgets/** 做全量审计的人(#3291 的 DOM leak sweep、#3318 的 aria-invalid 账本、#4788 的只读 plumbing 扫描)都会把它算进分母,然后为一个渲染不到的面写钉子。#4788 的扫描就是这么撞上的。

可能的处置(留给分诊,不预设)

  1. 按 ADR-0049 enforce-or-remove 的精神删掉 widget 与其导出(公开导出面的破坏性变更,需 changeset 说明);
  2. 或者留着,但在文件头写一行「不在 fieldWidgetMap 内,表单路径不可达,master_detail 走 LookupField」的墓碑注释,让审计者一眼跳过。

参考


备注:由 os-dev 在 #4788 的实施中实测发现并按 Prime Directive #10 立单(不认领、不扩围)。observation-class,未加 pm:queue

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions