Archived
Task 12 的非走查部分(浏览器走查卡在登录、归人工,不在本次范围)。 ① index.ts 头注仍写着旧的「三条技能 + 五张模版」,重写后是 0 技能 3 张件,核正 (Ruling H25);包内其余「三条技能/五张/两枚工具/九步」等提法逐处核过,均为带日期的 「从…改成…」历史叙述,不是失实断言,未动。 ② docs/数据域字段说明-W05.md 整篇重写(不是打补丁)。旧文档写的是重写前的十张表 (customer.profile/parts.document/demand.request 与 sub_eval 三张旧单据,本活动这次 重写已不再声明),现按 manifest.ts 的 declarations.ledger 逐表核对重写:9 张表、66 列、 20 人填列。写入者词表另定一套(人(件上)/AI(S2 唯一一次 analyze)/配方(project 算出来 的)/基座)——E04/I01 那套多轮 agent 编排的词表在这里说不清楚。逐个 data-edit 核对过 report.ts 才确认写入者归属:S3 的四态等列改成人在件上直接编辑(不再是「人写意见→AI 改」), sub_eval.part/case、substitution.relation、validation.record 四张表没有任何人工编辑 入口、全部配方算。顺手核了 seed-mvp-data.ts 的基线物理列,注了每张表里这次重写不再 声明的旧列(旧九步版本留下的痕迹),并记下 type_id 这条身份链路是本仓唯一一处 integer→text 加宽声明。 ③ docs/活动开发规范.md §4.6 补四条纪律(六条→十条):jsonb 会重排 fields 键序、字段 求值改按依赖拓扑排序不能拿书写顺序当依赖顺序;跨笔顺序仍要自己排(一笔读的是另一笔 写出来的数就要排后面);两笔方向相反的依赖拆两笔写中间夹子表;gateLedgers 同时管 「闸要求非空」与「确认时并进正式表」两件事,漏想一半会悬空引用或永久卡死。§6.5 补第 9 条「测试要能咬住」(镜像测试与读真文件测试证明的是两件事;变异测试本身可能是空的; 能 import 真东西就别手抄)。§7 补两行排障(reset-runs 前先捞证据;dev 进程可能在跑 几小时前的代码,连 tsup --watch 监视进程本身都可能已死)。八条内容逐条去任务报告核过 原始事故与提交号,没有凭印象转述。 ④ CLAUDE.md 现状快照追加一条:四步全 auto、两张类型字典、三张件、退役清单;e2e 三例 released 被拒 0(候选缺库/都在库/原PN缺库,模型调用恰 1 次);类型不一致那例撞上已记 debt.md 的 prune 死锁,两颗都缺库那例卡在「答完卡不推进」、真因未定位如实记录; judgement_class 7/7 逐行核对通过;jsonb 键序地基缺陷的发现与修法(拓扑排序,6636abf)。 顺手核正文档地图里 W05 那一行的旧字段数(十张/110列→九张/66列,与②同步)。 pnpm gates 退出码 0(2447 passed | 34 skipped),与 Task 11 最后一轮记录一致,无回归。 未碰 manifest.ts 里那处与本任务无关的未提交版本号改动(2.1.5→2.1.6,疑似上一个卡在 登录的浏览器走查会话留下)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LKMZDwMbyKzjw6Hembwvet
473 lines
35 KiB
Markdown
473 lines
35 KiB
Markdown
# 数据域字段说明 —— ACT-WORK-05 差异评估
|
||
|
||
> 对应设计中心 → 数据域「ACT-WORK-05 · 差异评估」分组。字段以活动清单的台账声明为准
|
||
> (`activities/part-substitution-assessment/src/manifest.ts` 的 `declarations.ledger`)。
|
||
> **2026-08-29 整体重写**(design spec `docs/superpowers/specs/2026-08-29-act-work-05-rewrite-design.md`)
|
||
> 把九步案例模型砍成四步、全程零 `guide`(行为改由 `PlanStep.auto` 声明式配方接管,ADR-014),
|
||
> 台账从旧的十张收成**九张**:两张原有的三单据(`sub_eval.pn_check` / `sub_eval.input_gap` /
|
||
> `sub_eval.verdict`)与三张外域表(`customer.profile` / `demand.request` / `parts.document`)
|
||
> 一并退役 —— **本活动这次重写不再声明、不再碰这五张表**;它们的存在性核对与录入不再是
|
||
> 这个活动的事(manifest.ts 头注原话)。老文档(见 git 历史)里那几张表的段落已随重写整篇撤下,
|
||
> 不是遗漏。
|
||
>
|
||
> 九张里有七张(除 `sub_eval.part` / `sub_eval.case` 两张本活动自持的工作台账外)的**物理结构**
|
||
> 由平台基线 `apps/api/src/app/seed-mvp-data.ts` 的 `MASTER_OBJECTS` 物化,声明合并对基线
|
||
> 基本是**纯 add-column**:活动只追加自己要用的列与标记(required / expect / tally / refersTo /
|
||
> requiredWhen / distinct / auto),不改基线已有列的语义。**唯一的例外是 `type_id` 这条身份链路**
|
||
> (`parts.chip_type.type_id` / `parts.type_param.type_id` / `parts.profile.chip_type_id` /
|
||
> `sub_eval.part.chip_type_id` / `sub_eval.case.chip_type_id` / `substitution.relation.chip_type_id`
|
||
> 六列同源同改)——声明把基线原本 `integer` 的这几列**加宽**成了 `text`,理由与 PG 类型转换
|
||
> 细节见 manifest.ts 该处的大注释与本文「怎么读这份文档」倒数第二条。那份声明同时是
|
||
> **授权面**:没声明的列写不进去,也不会出现在件上、判据里、数据域的活动分组里。
|
||
|
||
## 怎么读这份文档
|
||
|
||
- **★ = 重点字段**。每张表挑 5–8 个,在「重点字段」小节里**按重要程度从高到低**排;
|
||
数据结构表里在列名后打 ★。字段少于 5 个的表(字典、案卷)全部列入重点。
|
||
- **【人填】= 人在活动过程中亲手填、提交后入库的字段**(数据工单的件上编辑)。这类字段
|
||
**一律进重点**:它们是这一单里唯一不能靠配方补出来的事实。**S3 审核卡的四态/影响说明/
|
||
判断依据/UNKNOWN 去向不带这个标记**——那四格的初值是 AI 判出来的,人只是「审核时可以
|
||
就地改」,不是「唯一不能靠 AI 补出来的事实」;两者含义不同,详见各自表格的写入者说明。
|
||
- **这个活动的「写入者」词表与 `docs/数据域字段说明-E04-I01.md` 不同,单独在这里定义**——
|
||
E04/I01 全程多轮 agent 编排,W05 重写后**全程零 `guide`、AI 只在 S2 出场恰好一次**,
|
||
中间没有「模型每拍决定写什么」这件事,套用旧词表反而说不清楚:
|
||
- **人(件上)** —— 工作区那份 HTML 上点「编辑」改的格子,保存即落草稿层(与 E04/I01 同义)
|
||
- **AI** —— 整个活动**唯一一次**模型调用(S2 的 `analyze`)的出参,系统按 `lookup: result:items`
|
||
原样抄进台账;S3 人可在件上就地改
|
||
- **配方** —— `auto.do` 里 `project` 动作按声明(遍历 / `lookup` 现值 / `when` 链 / 字面量)
|
||
算出来的值,**不经模型**,每一拍都会重新求值一遍(幂等,值不变则不产生写入痕迹)
|
||
- **基座** —— 平台自己生成,不问人也不经模型(自增序号等)
|
||
- 没有「人(录入卡)」「AI(据人的意见改)」「承继」—— 本活动没有录入卡,也没有
|
||
「人写自由文本意见 → AI 读意见改具体行」这一步:S3 要改结论,人直接在件上改那一行;
|
||
T_release 全只读,打回重做要改的只有 `sub_eval.case`(且它也是配方算的,不是人填的)。
|
||
- 「约束」一栏的词表与 `docs/数据域字段说明-E04-I01.md`「怎么读这份文档」是**同一套**
|
||
(主键 / 自增 / 必填 / 建议填 / 取值域 / 引用 / 去重计数 / 脱敏),不重复抄一遍。
|
||
`requiredWhen` 类字段统一写「条件必填 · `<字段>=<值>` 时」。
|
||
- **`refersTo` 拒得很硬**:值必须在目标表里真实存在,查无此值 `draftWrite` 当场拒
|
||
(不是留到验收才发现)。装包时静态审核也会核 `refersTo` 目标地址本身是否存在。
|
||
|
||
### 一览
|
||
|
||
| 全景 | 台账地址 | 人读名 | 性质 | 本活动用到的列 | 人填列 |
|
||
|---|---|---|---|---|---|
|
||
| — | `parts.chip_type` | 芯片类型字典 | 主数据 · W05 唯一读写者 | 3 | 2(新建类型时,件上) |
|
||
| — | `parts.type_param` | 芯片类型核心参数字段 | 主数据 · W05 唯一读写者 | 5 | 5(新建类型 / 追加字段时,件上) |
|
||
| P-08 | `parts.profile` | 芯片主数据 | 主数据 · W05 唯一读写者 | 8 | 7(在库回填现值 · 缺库从零填,件上) |
|
||
| P-08 子 | `parts.parameter` | 标准化参数集 | 主数据 · W05 唯一读写者 | 5 | 2(值 · 说明,件上;主键两列虽挂 `data-col` 但由配方铺,人正常操作不改) |
|
||
| — | `sub_eval.part` | 本单两颗料(存在性与类型核对) | 本活动工作台账 | 6 | 0(配方每拍按入参与 `parts.profile` 现查重算,件上没有它的编辑入口) |
|
||
| — | `sub_eval.case` | 本单案卷 | 本活动工作台账 | 4 | 0(全部配方算) |
|
||
| P-11 | `substitution.relation` | 替代关系主记录 | 主数据 · W05 唯一读写者 | 13 | 0(配方按规则算,人不直接改) |
|
||
| P-11 子 | `substitution.difference_item` | 差异明细 | 主数据 · W05 唯一读写者 | 15 | 4(S3 就地改四态/影响说明/判断依据/UNKNOWN 去向;AI 先判,人可改) |
|
||
| P-06 | `validation.record` | 芯片验证记录 | 主数据 · W05 唯一读写者 | 7 | 0(配方按四态分布算) |
|
||
|
||
**四步**(全 `auto`,零 `guide`,AI 只在 S2 出场恰好一次):
|
||
`S1_inputs`(核对两颗料在不在库 / 是否归了同一芯片类型 / 参数是否齐,**缺什么才发一张
|
||
数据工单**——五条样例里「都在库·同型·齐备」那一条走的是零卡直通,不是特例)→
|
||
`S2_assess`(**整个活动唯一一次模型调用**:逐条核心参数判 MATCH/MISMATCH/UNKNOWN/CONDITIONAL
|
||
四态;推荐等级 / 风险 / 摘要 / 验证要求全部由配方按规则算,AI 不参与、不改一字)→
|
||
`S3_review`(结论审核,人工激活,件上就地改四态与三个自由文本格,可循环打回重做)→
|
||
`T_release`(落账放行,人工激活,全只读,签字后正式落账并发口 `assessment-released`,
|
||
可循环打回重做)。三道入场哨兵全读基座数(`sub_eval_part_*` / `substitution_*_rows` /
|
||
`_missing`),**案例模型里一面记账旗都没有**——「机检只读基座数」这条纪律在本仓被违反过
|
||
六次,W05 重写从设计上就不给它第七次机会。
|
||
|
||
---
|
||
|
||
## 一、`parts.chip_type` 芯片类型字典
|
||
|
||
按芯片类型(而不是按料号)标一次「这一类芯片要比哪几个核心参数、每个参数的说明与硬软
|
||
约束」——同一类型下两颗料从此**结构上**共用同一套参数名与约束档,不必再靠说明书措辞去
|
||
硬逼「两颗料对齐同一套参数名」(旧设计靠 `parts.parameter.param_name` 自指引用墙撑着,
|
||
测三次都没拦住,这次直接把墙的存在理由从结构上抹掉了)。件①型下拉里没有合适的,人在
|
||
`input-supplement` 的件②a 块现造一个;S1 配方选中之后**原样自投影一遍**(不论新建还是
|
||
挑既有类型都投,幂等、不产生多余写入),保证这一单的草稿层里**恒有这一行**——这既是
|
||
「保存即铺格」的前提,也是数据工单确认落地时不留悬空引用的前提(见 `docs/活动开发规范.md`
|
||
§4.6 关于 `gateLedgers` 的那条纪律)。
|
||
|
||
**重点字段(按重要程度)**
|
||
|
||
1. `type_id` ★ 主键 · 自增 —— 声明成 `text` 而不是 `integer`(见文档头注),写入时按
|
||
「现有最大 + 1」续号,不进表单、只读态摆「系统生成」
|
||
2. `type_name` ★【人填】必填 —— 新建类型时件上现填,已有类型从下拉挑
|
||
3. `description` ★【人填】建议填 —— 这个类型是什么(供选型参考)
|
||
|
||
**数据结构**
|
||
|
||
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|
||
|---|---|---|---|---|---|
|
||
| `type_id` ★ | 类型编号 | text | 主键 · 自增 | 基座(续号)| 基线原为 `integer`,声明加宽为 `text`(见头注) |
|
||
| `type_name` ★ | 类型名称 | text | 必填 | **人(件上)** | 新建类型时填 |
|
||
| `description` ★ | 类型说明 | text | 建议填 | **人(件上)** | |
|
||
|
||
---
|
||
|
||
## 二、`parts.type_param` 芯片类型核心参数字段
|
||
|
||
一类芯片一套字段清单,复合主键 `type_id + param_name`。新建类型(或给已有类型追加字段)时,
|
||
人在 `input-supplement` 的件②b 块逐条定下字段名 / 说明 / 硬软约束 / 参考单位;S1 配方同样
|
||
把选中类型此刻的字段清单**原样自投影一遍**(与 `parts.chip_type` 同一条道理、同一次修正 ——
|
||
挑已有类型时这张表天然可能零行,不投一遍会被「零行 = 没干完」的闸误判)。**这张表是 S2
|
||
唯一一次 AI 调用的入参来源**:逐条参数连同 `param_desc`(为什么要紧)一起交给模型判四态。
|
||
|
||
**重点字段(按重要程度)**
|
||
|
||
1. `type_id` ★【人填,选择】主键之一 · 引用 `parts.chip_type.type_id`
|
||
2. `param_name` ★【人填】主键之一 —— 参数名
|
||
3. `param_desc` ★【人填】必填 —— **AI 分析时读的就是它**:参数名本身说不清「它为什么要紧」,
|
||
写成参数名的复述等于没写
|
||
4. `constraint_type` ★【人填,选择】必填 · 取值域 `hard`/`soft` —— 硬约束 = 不满足就不能用
|
||
(烧芯片 / 超温域 / 装不上);软约束 = 影响表现但可权衡(功耗 / 噪声)
|
||
5. `param_unit` ★【人填】建议填 —— 参考单位;**S1 铺参数骨架、S2 判定都直接抄它**
|
||
(不是回填每颗料自己记的单位)——同一类型下两颗料必须按同一个单位比,这是这次比对的基准
|
||
|
||
**数据结构**
|
||
|
||
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|
||
|---|---|---|---|---|---|
|
||
| `type_id` ★ | 所属类型 | text | 主键之一 · 引用 `parts.chip_type.type_id` | **人(件上,下拉选)** | 基线原为 `integer`,声明加宽为 `text` |
|
||
| `param_name` ★ | 参数名 | text | 主键之一 | **人(件上)** | |
|
||
| `param_desc` ★ | 参数说明 | text | 必填 | **人(件上)** | AI 判定时读它 |
|
||
| `constraint_type` ★ | 约束类型 | text | 必填 · 取值域 | **人(件上,下拉选)** | 从 `parts.parameter` 搬到这里按类型标一次(旧设计每颗料各标一次,同一参数两颗料标法不一致就成了可能) |
|
||
| `param_unit` ★ | 参考单位 | text | 建议填 | **人(件上)** | `parts.parameter` 铺骨架 / S2 判定均直接抄它 |
|
||
|
||
---
|
||
|
||
## 三、`parts.profile` 芯片主数据(P-08)
|
||
|
||
一颗料一行。S1 配方按启动参数(`originalInternalPn` / `candidateInternalPn`)给两颗料各铺
|
||
一行骨架:**在库的那颗回填此刻的现值**(人不必重填,但看得到、能改),**要建的那颗全空**
|
||
等人填。`chip_type_id` 必填意味着「在库但还没归类型的老料」也会被拦住——那一格回填出来是
|
||
空的,人得先给它选一个类型。人不必在件上「加一行」:要建哪两颗料是启动参数定死的事,
|
||
行由配方摆好,他只填格子。
|
||
|
||
**重点字段(按重要程度)**
|
||
|
||
1. `internal_pn` ★ 主键 —— 全链路只认它;值随两颗料由启动参数定,件上虽挂 `data-col`
|
||
(行的钥匙)但人正常操作不改它
|
||
2. `chip_type_id` ★【人填,选择】必填 · 引用 `parts.chip_type.type_id` —— 两颗料**必须**
|
||
归到同一个类型,`sub_eval.part.chip_type_id` 的 `distinct` 判据钉着这一条
|
||
3. `brand_name` ★【人填】必填
|
||
4. `lifecycle_status` ★【人填,选择】必填 · 取值域 `active`/`nrnd`/`eol`/`discontinued`/`risk`
|
||
5. `manufacturer_name` ★【人填】建议填
|
||
6. `specification_description` ★【人填】建议填
|
||
7. `datasheet_ref` / `datasheet_version` ★【人填】建议填(成对)—— 证据回链
|
||
|
||
**数据结构**
|
||
|
||
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|
||
|---|---|---|---|---|---|
|
||
| `internal_pn` ★ | 内部料号 | text | 主键 | 配方(按入参铺行)| 在库的沿用现值,不在库的等人填别的格子后自然成立 |
|
||
| `chip_type_id` ★ | 芯片类型 | text | 必填 · 引用 `parts.chip_type.type_id` | 配方(在库回填现值)/ **人(件上,下拉选)** | 基线原为 `integer`,声明加宽为 `text` |
|
||
| `brand_name` ★ | 品牌名称 | text | 必填 | 配方(在库回填现值)/ **人(件上)** | |
|
||
| `lifecycle_status` ★ | 生命周期状态 | text | 必填 · 取值域 | 配方(在库回填现值)/ **人(件上,下拉选)** | |
|
||
| `manufacturer_name` ★ | 制造商名称 | text | 建议填 | 配方(在库回填现值)/ **人(件上)** | |
|
||
| `specification_description` ★ | 规格描述 | text | 建议填 | 配方(在库回填现值)/ **人(件上)** | |
|
||
| `datasheet_ref` ★ | Datasheet 引用 | text | 建议填 | 配方(在库回填现值)/ **人(件上)** | |
|
||
| `datasheet_version` ★ | Datasheet 版本 | text | 建议填 | 配方(在库回填现值)/ **人(件上)** | |
|
||
|
||
> 基线物理表里还留着这次重写不再声明的旧列(`customer_pn` / `normalized_parameter_set` /
|
||
> `package` / `process_technology` / `eol_pcn_status` / `application_scenarios` /
|
||
> `pin_to_pin_relation_ref`)——那是**同一张表被本活动更早的旧九步版本用过**的痕迹
|
||
> (封装/工艺这次已经变成按类型标在字典里,不再是主记录上单独一列),不是别的活动在共享它;
|
||
> add-column 合并不删旧列,记录浏览里看到它们空着是正常的,判断一列还算不算数,以
|
||
> **当前这份声明**为准。
|
||
|
||
---
|
||
|
||
## 四、`parts.parameter` 标准化参数集(P-08 子表)
|
||
|
||
一颗料一个核心参数一行,复合主键 `internal_pn + param_name`。S1 配方按「这两颗料 ×
|
||
选中类型的字段清单」铺骨架(`prune:true`,换类型会把不再相关的陈旧参数行清掉):
|
||
`param_value`/`param_note` 若在库已有记录就回填现值,没有就留空等人填;`param_unit`
|
||
**永远**从 `parts.type_param` 字典直接复制,不回填每颗料自己记的单位、也不可编辑
|
||
(与块①/②b 不同,这一列连孪生输入框都不给)——同一类型下两颗料必须按同一个基准单位比,
|
||
S2 判定用的 `unit` 与件上摆的是同一处来源,不允许分叉。
|
||
|
||
**重点字段(按重要程度)**
|
||
|
||
1. `internal_pn` ★ 主键之一 · 引用 `parts.profile.internal_pn` —— 挂 `data-col` 是因为它是
|
||
行的钥匙,不是人正常操作会去改的格子
|
||
2. `param_name` ★ 主键之一 —— 同上,由配方按字典铺,不是人填的自由文本
|
||
3. `param_value` ★【人填】必填 —— 差异评估逐项比对的唯一输入;原厂规格书查不到就留空,
|
||
**留空会被红带点名,但编一个值比留空坏得多**(说明书明写的禁令)
|
||
4. `param_unit` ★ 建议填 —— **恒等于字典值**,配方每拍覆盖,手改也会在下一拍被盖回去
|
||
5. `param_note` ★【人填】建议填 —— 值的说明
|
||
|
||
**数据结构**
|
||
|
||
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|
||
|---|---|---|---|---|---|
|
||
| `internal_pn` ★ | 所属料号 | text | 主键之一 · 引用 `parts.profile.internal_pn` | 配方(按字典 × 两颗料铺骨架) | 挂 `data-col` 只为行的钥匙 |
|
||
| `param_name` ★ | 参数名 | text | 主键之一 | 配方 | 同上 |
|
||
| `param_value` ★ | 值 | text | 必填 | 配方(在库回填现值)/ **人(件上)** | 查不到留空,不许估、不许拿别的参数的值顶替 |
|
||
| `param_unit` ★ | 单位 | text | 建议填 | 配方(恒抄 `parts.type_param` 字典) | 只读,连孪生输入框都不给 |
|
||
| `param_note` ★ | 说明 | text | 建议填 | 配方(在库回填现值)/ **人(件上)** | |
|
||
|
||
> 基线物理表里还留着一列这次重写不再声明的 `constraint_type`(旧设计每颗料各标一次约束,
|
||
> 这次已搬到 `parts.type_param` 按类型标一次)——同一条「add-column 不删旧列」的道理。
|
||
|
||
---
|
||
|
||
## 五、`sub_eval.part` 本单两颗料(存在性与类型核对,本活动工作台账)
|
||
|
||
S1 配方**每一拍都重算**的一张表(不是「写一次就不再动」):按启动参数铺两行(`role`
|
||
恰有 `original`/`candidate` 各一行),`found_pn_ref` 现查 `parts.profile` 是否已有这个
|
||
`internal_pn`、`exists_status` 据此判 `found`/`absent`、`chip_type_id` 现查在库现值。
|
||
**这张表没有任何人工编辑入口**——它是「要评估什么」那张件的**行来源**
|
||
(`data-rows="mine:sub_eval.part" data-edit="parts.profile"`),人在件上改的是
|
||
`parts.profile`,行会在下一拍被这张表原样重铺。
|
||
|
||
**重点字段(按重要程度)**
|
||
|
||
1. `exists_status` ★ 必填 · 取值域 `found`/`absent` —— 存在性核对的核心结论,S1 收步与
|
||
S2 入场哨兵都读它(`sub_eval_part_exists_status_found = 2` 才算「两颗都在库」)
|
||
2. `internal_pn` ★ 主键之一
|
||
3. `eval_ref` ★ 主键之一 —— 本单案号,`W05-` + 开案时刻 14 位数字,串联本活动自持的两张
|
||
工作台账
|
||
4. `role` ★ 必填 · 取值域 `original`/`candidate`
|
||
5. `chip_type_id` ★ 必填 · **去重计数**(`distinct`)—— 「两颗料是不是同一个类型」从此是
|
||
基座数得出来的数(`sub_eval_part_distinct_chip_type_id`),S1 收步与 S2 入场的硬门
|
||
6. `found_pn_ref` ★ **条件必填**(`exists_status=found` 时)· 引用 `parts.profile.internal_pn` ——
|
||
「在库」是一次 `lookup` 的结果,不是一句断言;判 `found` 就必须拿得出一个基座查得到
|
||
的料号
|
||
|
||
**数据结构**
|
||
|
||
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|
||
|---|---|---|---|---|---|
|
||
| `eval_ref` ★ | 评估案号 | text | 主键之一 | 配方 | |
|
||
| `internal_pn` ★ | 内部料号 | text | 主键之一 | 配方(按启动参数铺) | |
|
||
| `role` ★ | 角色 | text | 必填 · 取值域 | 配方 | `original` 恰一行 / `candidate` 恰一行 |
|
||
| `found_pn_ref` ★ | 在库核对依据 | text | 条件必填 · `exists_status=found` · 引用 `parts.profile.internal_pn` | 配方(现查 `parts.profile`) | 查无此值 `exists_status` 判 `absent` |
|
||
| `exists_status` ★ | 在库状态 | text | 必填 · 取值域 `found`/`absent` | 配方 | 每拍现算,不设 `created` 档、不靠谁记账 |
|
||
| `chip_type_id` ★ | 芯片类型 | text | 必填 · 去重计数 | 配方(现查 `parts.profile`) | 基线原为 `integer`,声明加宽为 `text` |
|
||
|
||
---
|
||
|
||
## 六、`sub_eval.case` 本单案卷(本活动工作台账)
|
||
|
||
一单一行的案卷,挂着摆给人看的一句话(`gate_reason`)与收口摘要(`summary`)。**没有一面
|
||
记账旗**——完成与否全部由别处的基座读数(`sub_eval_part_*` / `substitution_*_rows` /
|
||
`_missing`)判定,这张表只是「说清此刻是什么状况」的一处落点。由两步接力写:S1 每拍
|
||
写 `eval_ref`/`chip_type_id`/`gate_reason`(供数据工单卡面的「还差什么」摆),T_release
|
||
再补一笔 `summary`(供落账确认页的结论卡摘要)。
|
||
|
||
**重点字段**
|
||
|
||
1. `eval_ref` ★ 主键 —— `W05-` + 开案时刻 14 位数字(与引擎注给模型铸主键用的
|
||
`case:openedAt` 同一函数,跨单唯一)
|
||
2. `gate_reason` ★ —— **摆在数据工单件上给人看的那句话**;`when` 链逐级判断此刻缺什么
|
||
(两颗料没填全 / 有料号查无记录 / 有料号没归类型 / 两颗料类型不一致 / 还有必填格空着),
|
||
都不缺时是空串。**这一笔排在铺骨架那两笔(`parts.profile`/`parts.parameter`)之后
|
||
不是随手写的次序**——它读的 `parts_profile_missing`/`parts_parameter_missing`
|
||
是骨架刚建出来的基座读数,排前面会读到刷新之前的旧数(详见 `docs/活动开发规范.md`
|
||
§4.6 新增纪律)
|
||
3. `chip_type_id` ★ —— 本单锁定的芯片类型(原料那一颗的),供 S2 组装入参时 `lookup`
|
||
4. `summary` ★ —— T_release 写的收口一句话(`<候选PN> 替代 <原PN>:<差异摘要>`),落账
|
||
确认页「结论卡」的摘要来源
|
||
|
||
**数据结构**
|
||
|
||
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|
||
|---|---|---|---|---|---|
|
||
| `eval_ref` ★ | 评估案号 | text | 主键 | 配方(S1,按开案时刻铸) | |
|
||
| `chip_type_id` ★ | 本单锁定的芯片类型 | text | — | 配方(S1) | 供 S2 `lookup` 用 |
|
||
| `gate_reason` ★ | 入参未就绪原因(件上摆的就是它) | text | — | 配方(S1,`when` 链) | 都不缺时是空串;S1 发卡条件读的正是「非空」 |
|
||
| `summary` ★ | 结论摘要 | text | — | 配方(T_release) | `<候选PN> 替代 <原PN>:<差异摘要>` |
|
||
|
||
---
|
||
|
||
## 七、`substitution.relation` 替代关系主记录(P-11)
|
||
|
||
一单一行(旧设计是「一个未放弃的候选一条」,新设计**一次评估恰一对一候选**,不再有
|
||
「多候选、部分放弃」)。S2 与 S3 共用**同一份**投影(`RELATION_PROJECTION`):S2 首算,
|
||
人在 S3 就地改了差异明细的某条四态之后,同一份投影重算一遍——两处各写一份早晚分叉,
|
||
分叉的那一刻屏上会同时摆着两个互相矛盾的等级。**推荐等级 / 风险 / 摘要 / 理由 / 验证
|
||
要求全部由规则与模板拼,不让 AI 编**——于是不会出现「有硬约束不符却写着推荐」这种事;
|
||
人在 S3 改的是差异明细的四态,这一行跟着重算,人**不直接改**这张表本身。
|
||
|
||
**重点字段(按重要程度)**
|
||
|
||
1. `substitution_relation_id` ★ 主键 —— `SUB-<案号>`
|
||
2. `eval_ref` ★ 必填 —— **本活动新增列(基线没有)**,串联本单
|
||
3. `recommendation_level` ★ 必填 · 取值域 `recommended`/`conditional`/`not_recommended`
|
||
(旧设计还有 `alternate` 档,新设计的判定分类三分,这一档随之退役)—— 配方按 §3.5 的
|
||
规则算:有硬约束不符必 `not_recommended`,否则有 UNKNOWN/CONDITIONAL/软约束不符任一
|
||
即 `conditional`,全一致才 `recommended`
|
||
4. `original_internal_pn` / `candidate_internal_pn` ★ 必填 · 引用 `parts.profile.internal_pn`
|
||
5. `risk_level` ★ 必填 · 取值域 `low`/`medium`/`high` —— 随 `recommendation_level` 联动算
|
||
6. `verification_requirement` ★ **条件必填**(`recommendation_level=conditional` 时)
|
||
7. `rule_version` ★ 必填 —— 随结论落账,锁定 `R-2026.07`
|
||
8. `validation_id` ★ —— 关联验证ID(`VAL-<案号>`)
|
||
|
||
**数据结构**
|
||
|
||
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|
||
|---|---|---|---|---|---|
|
||
| `substitution_relation_id` ★ | 替代关系ID | text | 主键 | 配方 | `SUB-<案号>` |
|
||
| `eval_ref` ★ | 评估案号 | text | 必填 | 配方 | 本活动新增列(基线没有) |
|
||
| `original_internal_pn` ★ | 原内部料号 | text | 必填 · 引用 `parts.profile.internal_pn` | 配方 | |
|
||
| `candidate_internal_pn` ★ | 候选内部料号 | text | 必填 · 引用 `parts.profile.internal_pn` | 配方 | |
|
||
| `chip_type_id` ★ | 芯片类型 | text | 必填 | 配方 | 基线原为 `integer`,声明加宽为 `text` |
|
||
| `recommendation_level` ★ | 推荐等级 | text | 必填 · 取值域 | 配方(按规则算) | 不让 AI 编 |
|
||
| `recommendation_reason` | 推荐理由 | text | 必填 | 配方(按规则拼句) | |
|
||
| `difference_summary` | 差异摘要 | text | 必填 | 配方(按规则拼句) | 「共 N 项核心参数:X 项一致 / … 」句式 |
|
||
| `risk_level` ★ | 替代风险等级 | text | 必填 · 取值域 | 配方(按规则算) | |
|
||
| `verification_requirement` ★ | 验证要求 | text | 条件必填 · `recommendation_level=conditional` | 配方 | |
|
||
| `validation_id` | 关联验证ID | text | — | 配方 | `VAL-<案号>` |
|
||
| `analysis_status` ★ | 分析状态 | text | 必填 | 配方 | 恒 `fae_confirmed`(基线其余档位本活动不写) |
|
||
| `rule_version` ★ | 差异规则版本 | text | 必填 | 配方 | 锁定 `R-2026.07` |
|
||
|
||
> **只读边界**:基线在这张表上还建了 `customer_approval_status` / `customer_approval_at` /
|
||
> `customer_approval_ref` / `customer_feedback` 四列,由**独立审批流**维护;本活动的声明
|
||
> 里没有这四列的写权(禁令 `no-customer-approval-write`)。基线物理表里还留着这次重写
|
||
> 不再声明的 `request_id` / `project_code` / `bom_position` / `substitution_type` /
|
||
> `analysis_report_ref` / `confidence_score`——那是旧九步版本用过的列,同一条
|
||
> 「add-column 不删旧列」的道理。
|
||
|
||
---
|
||
|
||
## 八、`substitution.difference_item` 差异明细(P-11 子表)
|
||
|
||
一颗料的一条核心参数一行,主键 `substitution_relation_id + difference_item_id`;行由
|
||
`parts.type_param` 字典 `each` 出来(`prune:true`)——**字段清单由字典给,AI 的出参只是
|
||
拿 `param_name` 去 `lookup` 的一张查表**,它漏一条,那一行的四态就是空,`required` 立刻
|
||
变成 `_missing > 0`,提交闸与放行门当场拦住(不会像「AI 出参驱动行」那样漏两条就少两行、
|
||
每一行看着都合规)。**S3 是这张表唯一的人工编辑入口**:四态 / 影响说明 / 判断依据 /
|
||
UNKNOWN 去向可就地改,其余(参数项 / 说明 / 约束 / 原值 / 候选值 / 单位)只读。
|
||
|
||
**重点字段(按重要程度)**
|
||
|
||
1. `substitution_relation_id` ★ 主键之一 · **去重计数** · 引用 `substitution.relation.substitution_relation_id` ——
|
||
「几条关系已经有明细」就是数它的不同值(恰应为 1)
|
||
2. `difference_item_id` ★ 主键之一
|
||
3. `difference_status` ★ 必填 · 取值域 `match`/`mismatch`/`unknown`/`conditional` ——
|
||
**S2 那一次 AI 判定的核心出参**
|
||
4. `judgement_class` ★ 必填 · 取值域 `match`/`soft_mismatch`/`hard_mismatch`/`unknown`/`conditional` ——
|
||
**合成列**(先认 `difference_status`,`mismatch` 再按 `constraint_type` 分硬/软):
|
||
「硬约束不符有几条」不是任何单列 `tally` 数得出来的数,`recommendation_level` 的判据
|
||
全靠这一列
|
||
5. `impact_statement` ★ 必填 —— MATCH 写「无」,其余写「换上去会不会比现在差、差在哪儿」
|
||
(不复述参数值)
|
||
6. `evidence_note` ★ 必填 —— 判断依据
|
||
7. `unknown_disposition` ★ **条件必填**(`difference_status=unknown` 时)—— UNKNOWN 的去向
|
||
8. `constraint_type` ★ 必填 · 取值域 `hard`/`soft` —— 承自 `parts.type_param` 字典这一行本身
|
||
|
||
**数据结构**
|
||
|
||
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|
||
|---|---|---|---|---|---|
|
||
| `substitution_relation_id` ★ | 替代关系ID | text | 主键之一 · 去重计数 · 引用 `substitution.relation.substitution_relation_id` | 配方 | 隐藏在件上(`.rowkey`),仅供 `resolveRowKey` 凑主键 |
|
||
| `difference_item_id` ★ | 差异明细ID | text | 主键之一 | 配方 | `<关系id>-<参数名>` |
|
||
| `parameter_name` | 标准参数名 | text | 必填 | 配方(抄字典) | |
|
||
| `parameter_desc` | 参数说明 | text | 建议填 | 配方(抄字典) | 归档件不必回查字典,快照一份 |
|
||
| `constraint_type` | 约束类型 | text | 必填 · 取值域 | 配方(抄字典) | |
|
||
| `original_value` | 原物料参数值 | text | 必填 | 配方(`lookup` `parts.parameter`) | |
|
||
| `candidate_value` | 候选物料参数值 | text | 必填 | 配方(`lookup` `parts.parameter`) | |
|
||
| `parameter_unit` | 参数单位 | text | 建议填 | 配方(抄字典) | |
|
||
| `difference_status` ★ | 差异状态 | text | 必填 · 取值域 | **AI**(S2 `analyze` 出参) | |
|
||
| `judgement_class` ★ | 判定分类 | text | 必填 · 取值域 | 配方(合成列) | 由 `difference_status` × `constraint_type` 算 |
|
||
| `impact_statement` ★ | 影响说明(MATCH 写「无」) | text | 必填 | **AI** / **人(件上,S3 可改)** | |
|
||
| `evidence_note` ★ | 判断依据 | text | 必填 | **AI** / **人(件上,S3 可改)** | 基线里这一列旧名是 `evidence_ref`,本活动改用新名 `evidence_note`(不写 P-10 了,AI 能给的是依据不是文件引用) |
|
||
| `unknown_disposition` ★ | UNKNOWN 去向(验证任务号 / 补来源动作) | text | 条件必填 · `difference_status=unknown` | **AI** / **人(件上,S3 可改)** | |
|
||
| `risk_level` | 风险等级 | text | 必填 · 取值域 | 配方 | `hard_mismatch`→high,`match`→low,其余 medium |
|
||
| `rule_version` | 差异规则版本 | text | 必填 | 配方 | 锁定 `R-2026.07` |
|
||
|
||
> 基线物理表里还留着两列这次重写不再声明的旧列:`evidence_ref`(已被 `evidence_note`
|
||
> 取代,不是同一列改名,是新声明了一列、旧列作废不写)与 `confidence`(AI 置信度,旧设计
|
||
> 的工具出参字段,新设计没有这个概念)。
|
||
|
||
---
|
||
|
||
## 九、`validation.record` 芯片验证记录(P-06)
|
||
|
||
事实类表:本活动只在 S2/S3 给每单挂**一行固定的**「验证要求」占位
|
||
(`validation_status` 恒 `not_started`,`validation_type` 恒 `parametric`)——它不是实测
|
||
结果,**不许虚构实测**;真正测完、写测试结果是另一件事(下游或线下流程的事)。**一单固定
|
||
一条**,即使全部参数都 MATCH、没有待验项,也要写「本轮无待验项」而不是不写这一行
|
||
(验收判据 `validation-landed` 钉着 `validation_record_rows = 1`)。
|
||
|
||
**重点字段(按重要程度)**
|
||
|
||
1. `validation_id` ★ 主键 —— `VAL-<案号>`
|
||
2. `eval_ref` ★ 必填 —— **本活动新增列(基线没有)**
|
||
3. `validation_internal_pn` ★ 必填 · 引用 `parts.profile.internal_pn` —— 恒为候选料号
|
||
4. `validation_status` ★ 必填 —— 恒 `not_started`
|
||
5. `next_validation_action` ★ 必填 —— 要测什么、什么条件;没有待验项写「本轮无待验项」
|
||
6. `validation_type` ★ 必填 · 取值域(基线六档,本活动只写 `parametric`)
|
||
7. `test_condition` ★ 建议填 —— 有待验项才写测试条件,否则「无」
|
||
|
||
**数据结构**
|
||
|
||
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|
||
|---|---|---|---|---|---|
|
||
| `validation_id` ★ | 验证ID | text | 主键 | 配方 | `VAL-<案号>` |
|
||
| `eval_ref` ★ | 评估案号 | text | 必填 | 配方 | 本活动新增列(基线没有) |
|
||
| `validation_internal_pn` ★ | 验证内部料号 | text | 必填 · 引用 `parts.profile.internal_pn` | 配方 | 恒为候选料号 |
|
||
| `validation_type` ★ | 验证类型 | text | 必填 · 取值域 | 配方 | 恒 `parametric`(本活动只挂这一种) |
|
||
| `validation_status` ★ | 验证状态 | text | 必填 | 配方 | 恒 `not_started` |
|
||
| `test_condition` | 测试条件 | text | 建议填 | 配方 | 有 UNKNOWN/CONDITIONAL 才写,否则「无」 |
|
||
| `next_validation_action` ★ | 后续验证动作 | text | 必填 | 配方 | 没有待验项写「本轮无待验项」 |
|
||
|
||
> 基线物理表里还留着这次重写不再声明的一批旧列(`request_id` / `customer_code` /
|
||
> `test_parameters` / `test_result` / `issue_risk` / `sample_version` / `sample_lot` /
|
||
> `evidence_ref`)——那批列是「真验证发生后才有的事实」(测试参数、测试结果、样品批次),
|
||
> 本活动只写「验证要求」占位阶段,不写实测结果,同一条「add-column 不删旧列」的道理。
|
||
|
||
---
|
||
|
||
## 十、人填字段总表(按人办事的那一屏)
|
||
|
||
| 活动 · 屏 | 卡的形式 | 落进哪张表 | 人亲手填的列 |
|
||
|---|---|---|---|
|
||
| `S1_inputs` · 数据工单「差异评估的输入还差几格」(条件发卡,零卡直通是常态路径之一) | 执行工单(零输入卡,件上编辑 + 增删行) | `parts.chip_type`(新建类型时)/ `parts.type_param`(新建类型 / 追加字段时)/ `parts.profile` / `parts.parameter` | chip_type:`type_name`/`description`;type_param:`type_id`(选)/`param_name`/`param_desc`/`constraint_type`(选)/`param_unit`;profile:`chip_type_id`(选)/`brand_name`/`lifecycle_status`(选)/`manufacturer_name`/`specification_description`/`datasheet_ref`/`datasheet_version`;parameter:`param_value`/`param_note` |
|
||
| `S3_review` · 差异评估结论审核(可循环打回重做) | 决策卡(`decide`,`variant:'review'`)+ 件上就地改 | `substitution.difference_item` | `difference_status`(选)/`impact_statement`/`evidence_note`/`unknown_disposition`(AI 先判,人核对后可改) |
|
||
| `T_release` · 落账放行(可循环打回重做) | 终局验收工单(签字,人工验收清单五条) | 无(全只读) | 无 —— 人只签字或打回重做。**这一步本身不提供改内容的手段**(`writes` 只声明了 `sub_eval.case`,且这张表没有人工编辑入口、全由配方算);要改结论内容,退回 `S3_review` 的件上直接改 |
|
||
|
||
---
|
||
|
||
## 十一、在数据域里看这些表时的几条提醒
|
||
|
||
1. **`sub_eval.part` / `sub_eval.case` 是本活动自持的工作台账**(domain `sub_eval`,与 E04
|
||
`crm_coverage.*`、I01 `content_brand.*` 同一类地位),其余七张是共享主数据的物理表 ——
|
||
但截至这次重写,**只有 W05 声明并读写它们**(全仓 grep `domain: 'parts'` /
|
||
`'substitution'` / `'validation'` 唯一命中处就是这个包),称「共享」容易让人以为另有
|
||
活动在用,这份文档统一改称「W05 唯一读写者」。
|
||
|
||
2. **`type_id` 这条身份链路是本仓唯一一处「integer 加宽成 text」的声明**(六列同源:
|
||
`parts.chip_type.type_id` / `parts.type_param.type_id` / `parts.profile.chip_type_id` /
|
||
`sub_eval.part.chip_type_id` / `sub_eval.case.chip_type_id` /
|
||
`substitution.relation.chip_type_id`)。原因是平台的自增续号器只认「整数型主键走一条路、
|
||
字符串型主键走另一条路」,而「`auto:true` 又是 `integer` 的主键」这个组合会撞上两处
|
||
平台级坑(`resolveRowKey` 抢跑续号 / `coerceToColumn` 按 `Number()` 解析掉前导零导致
|
||
`refersTo` 比对失配)——声明层加宽成 `text` 绕开,不是修复那两处平台代码(它们仍带着
|
||
坑,见 `docs/debt.md`)。字段说明详见 `parts.chip_type.type_id` 那一行与
|
||
manifest.ts 对应大注释。
|
||
|
||
3. **基线物理表里普遍还留着旧九步版本的列**(见各表小节末尾的提醒框)——`add-column`
|
||
合并不删旧列,记录浏览里看到它们空着是正常的;判断一列还算不算数,**以活动清单当前
|
||
这份声明为准**,不以物理表结构为准。
|
||
|
||
4. **`substitution.relation.customer_approval_status` 等四列是只读边界,不是本活动没做完**——
|
||
由**独立审批流**维护,本活动的声明里没有写权(禁令 `no-customer-approval-write`)。
|
||
|
||
5. **试跑单默认也落真库**:与 E04 / I01 同一个开关(`sys.task.land_master`,测试台起单
|
||
默认打开)——跑一遍活动,新建的芯片类型 / 料号 / 参数都会真的进正式表;要它不落,
|
||
起单时显式关掉(脚本化 e2e 要求自己传 `false`)。
|
||
|
||
6. **本活动全程无 agent 多轮编排,零技能、零工具**——`contract.resources.tools` 与
|
||
`declarations.tools` 都是 `[]`,`assets.skills` 也是 `[]`(旧两枚工具、两张 DMN、三条
|
||
技能戳已随重写整体退役)。全部行为写在 `PlanStep.auto` 声明式配方里,详见
|
||
`docs/活动开发规范.md` §4.6。
|
||
|
||
---
|
||
|
||
*字段口径以 `activities/part-substitution-assessment/src/manifest.ts` 的
|
||
`declarations.ledger` 为准;七张共享主数据的基线物理结构见
|
||
`apps/api/src/app/seed-mvp-data.ts` 的 `MASTER_OBJECTS`;四步剧本与配方见
|
||
`activities/part-substitution-assessment/src/case-model.ts` 的 `ASSESSMENT_STEPS` 与
|
||
`NARRATIVE`;确定性步骤(`auto` 五动词)的通用机制见 `docs/adr/ADR-014-deterministic-steps.md`
|
||
与 `docs/活动开发规范.md` §4.6;业务设计源见 `docs/SS02-ACT-WORK-05-html/`
|
||
(活动流程与工单说明)、`docs/superpowers/specs/2026-08-29-act-work-05-rewrite-design.md`
|
||
与《SS02-SS03-SS04_Demo台账字段细化与统一方案》。*
|