fix(w05): 三份件的机械抽样式补齐缺失 class —— 落账件同款会炸,提前拦下

浏览器走查实测:差异评估结论审核件里三个 <svg class="zic"> 撑成 946×946,
整份文档拉到 4625px 高,正文全被挤走 —— 人打开只见灰色巨块,没法逐条核四态。

根因:.zic{width:14px;height:14px} 只在 P08_CSS(数据工单那一段),而
difference-review 用的是 ACC1_CSS。ACC1_CSS / ACC2_CSS 是从目标件机械抽出来的,
report.ts:538 那句既有注释早已承认漏过一批(.jc-vcell/.jc-cell/…),补了几个,
这几个漏了。

按「一次查干净」逐个核三份件用到的每个 class,补齐:
· .zic —— ACC1_CSS **与 ACC2_CSS**(后者即 landing-confirm,同款会炸,走查下一步就会撞上)
· .note .done / .note .need —— ACC1_CSS 与 ACC2_CSS
· .kv-box —— BIND_LANDING
· .risk-badge 缺基座形状(只有配色没有胶囊盒子)—— 人工核对徽标家族一致性时发现,机械扫描漏网

新增自测:三份件用到的 class 必须都能在它自己那段 CSS 里找到定义 ——
将来谁再加一个没定义的 class 就变红。变异验证:删掉 .zic 那条真红,补回真绿。

另:嵌套 data-by 的「只读态显示了并不存在的值」已坐实为渲染器侧机制
(递归合并时行内没有该字段会落回外层同名字段),加 it.fails 钉住,平台修法另议。

包版本 2.1.7。pnpm gates 退出码 0(164 文件 / 2450 测)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LKMZDwMbyKzjw6Hembwvet
This commit is contained in:
xcs
2026-08-30 12:51:14 +08:00
co-authored by Claude Opus 5
parent 9e2f7387b2
commit 764dab342d
5 changed files with 149 additions and 2 deletions
@@ -434,6 +434,41 @@ describe('嵌套行模版与 data-by —— 一个候选一张表', () => {
const all = renderView(html.replace(' data-by="rel_id"', ''), scope);
expect(all.split('使能逻辑').length - 1).toBe(2);
});
/*
* **已知问题,尚未修 —— 2026-08-30(ACT-WORK-05 task-12,缺陷①,浏览器真人走查逮到)**。
* 现场报的是「候选料一行的芯片类型只读态显示着一个值,而那一格实际是空的,编辑态与 SQL
* 双重核实过是空串」。原本怀疑是 `byParent` 对空父键的处理退化成显示第一行 —— 查下来这
* 个猜测是错的:上面「父值缺席一行不留」那条已经钉死了"这一行自己把父键显式写成空字符串"
* 这个场景(`rel_id: ''`),`byParent` 的 `parent === ''` 守卫恒定正确,不是这次的病根。
*
* 真正能复现的是**另一种缺席**:这一行压根**没有**这个字段(不是空字符串,是键都不存在)——
* 常见于必填但还没填的草稿行(如 ACT-WORK-05 的 input-supplement 件:候选料还没定型号时,
* `sub_eval.part` 那一行不会带 `chip_type_id` 这个键)。`renderRows` 递归处理嵌套
* `data-rows` 时用 `{ ...scope, ...one }` 合并外层与本行 —— `one` 缺席的键会**悄悄落回
* 外层 scope 里同名的字段**。而外层 scope 常常真的有一个同名字段:`engines.ts` 的
* `taskData.view()` 会把「各对象最新一行的字段名」铺到顶层(`task.data`),
* `part-substitution-assessment` 的 `case-model.ts` 就因为撞过这同一个坑,自己的 `auto`
* 配方特地避免用 `{in:'chip_type_id'}`(该文件 134 行注释:「这个名字在三张表上都有,
* 顶层同名以后写的赢」)—— 但那条护栏只保护了 case-model 自己的 S-FEEL 求值,没有覆盖到
* 这里的 `data-by` 嵌套查表,于是同一类撞名在 `view-render.ts` 这一侧原样重演。
*
* 用 `it.fails`:这条断言此刻确实会失败(已用最小复现核对过,不是这条测试自己写错)——
* 先把复现钉进套件,不在这一轮改 `view-render.ts`(共享面,E04/I01 也用 `data-by`,
* 改动需要先报给设计者裁定修法);等修完翻正、去掉 `.fails`,它就是永久回归测试。
*/
it.fails('父键在本行里压根缺席(不是空字符串)时,不该被外层作用域里恰好同名的字段顶替', () => {
const withNestedLookup =
'<tbody data-rows="parts"><tr><td data-slot="pn"></td>' +
'<span data-rows="dict" data-by="id=type_id"><i data-slot="name"></i></span>' +
'</tr></tbody>';
const out = renderView(withNestedLookup, {
type_id: '5', // 页面顶层恰好有个同名字段(如 sub_eval.case.chip_type_id 铺到顶层的产物)
parts: [{ pn: 'XL2596S-5.0' /* 这一行没有 type_id 这个键 —— 该型号还没定型 */ }],
dict: [{ id: '5', name: 'DC-DC 降压稳压器' }],
});
expect(out).not.toContain('DC-DC 降压稳压器');
});
});
describe('data-options:下拉的选项从台账现读', () => {