Archived
A2-A7 全部补齐到验收线;顺手把几处「门拦住却不给路」的坑填了
活动:A2 选型 / A3 寻源 / A4 定价 / A6 议价 / A7 归档五件各补成真活动包 —— 契约宽进(input.required 空,归一在活动内)、台账必填声明(含行级 requiredWhen)、 入场哨兵与 L1/L2 判据一律读基座数、两份件(在办可编辑 + 办结静态快照)、 三案例常备、包内自测。e2e 各三案例 released、行动被拒 0、发口正确、提交闸每单真拦。 基座(共享面,改一处影响所有活动,故每处都带回归): · 重发判断走在站上场之前 —— 人答完那步常已收掉,readyToWork 先抛「不能再往它上面挂活」, 于是「重发已答过的卡 = 无事发生」这条唯一活路在最需要时够不着,A1 基线当场熔断; · 决策卡补幂等兜底(与执行工单同一把尺):头两次无事发生,第三次起才算被拒; · 输出没成形先就地重问一次,原话进工作日志、不再摆上卡面; · 工具调用读数 tool_<名>_calls —— 「机检只读基座数」这条纪律第一次覆盖到工具; · 执行卡 steps/standard 补进出参 schema(从前能到卡面全靠厂商 JSON 模式宽松); · 件的就地更新改逐节点 morph,保存先把新值镜像进只读那份 —— 不闪、不等回声。 A1(基线,全程守住):措辞三档对齐(必填/建议/选填)、禁止拿历史价当客户目标价、 卡骨架从步骤剧本搬进说明书(压成一拍连做时剧本没摊开,会发出没有指导书的裸卡)。 契约两处**新增可选字段**(非破坏):FieldDeclaration.requiredWhen、工单 finalHtml; api-report 同批更新。docs/adr 与 docs/archive 的 13 份文件在工作树里不见了, 本次予以恢复而非提交删除。 门禁:typecheck / lint / depcruise / test(1366)全绿。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,138 +1,339 @@
|
||||
/**
|
||||
* A2 替代选型的案例模型 —— **一张执行单办完**(2026-07-31 用户定,大幅简化)。
|
||||
* A2 替代选型的案例模型 —— **双表示同版本**:CMMN XML(机器面)与案例说明书(叙事面)。
|
||||
*
|
||||
* 上一版把 SOP 上的每一小步都建成了计划项(查规格、判品牌、查沉淀、撒网初筛、
|
||||
* 逐条核验、确认主推、收规格书、参数对比、风险评估…… 九个 humanTask)。
|
||||
* 那是把「FAE 脑子里怎么想」当成了「系统要管几步」——
|
||||
* 而这一整段在业务上是**一件事**:拿着原型号去选一个替代料,选完给出对标结论。
|
||||
* 系统该做的不是替他把这件事切成九块,是**把该填的表摆好、把结果收进台账**。
|
||||
* 业务出处:`docs/MVP示例工作流.html` §1.5,但按 **MVP 简化口径**建模
|
||||
* (2026-08-02 用户定:A2 是复杂活动,MVP 期间不展开大规模业务建模):
|
||||
*
|
||||
* 现在只有两项:
|
||||
* T_select —— 派一张执行单给 FAE(卡面两张可编辑表),他填完提交;
|
||||
* T_release —— 放行(触达世界,人工激活)。
|
||||
* A1 带着询价受理记录转进来 → 挑出 C 类 → **一张执行单**让 FAE 在系统外完成选型、
|
||||
* 把替代料填回来 → 判替代料在库里行情稳不稳:稳转 A、不稳转 B →
|
||||
* 询价受理记录就此转换成**询价受理清单**,传给下游(有 B 类去寻源,全 A 直通定价)。
|
||||
*
|
||||
* 与 A1 的分工:A1 是**受理归一**,活多、判据多、有确定性规则可依(两张判定表),
|
||||
* 值得逐步建模;A2 是**一次专家判断**,建模建得再细也换不来业务上的好处,
|
||||
* 只会让 Agent 全程跟 harness 较劲(A1 上一版 12 项的教训就在这儿)。
|
||||
* SOP 里初选核险 / 圈选替代 / 对比评估那三段的**实质工作在 FAE 脑子里与系统外**
|
||||
* (撒网、读规格书、参数对比 —— 本系统没有那些数据源);系统的本分是归一、组卡、
|
||||
* 判稳、留痕。所以图上只有四项:归一 → 交人填回 → 判稳定标 → 放行。
|
||||
*
|
||||
* ── 建模纪律(照 A1 的账)──────────────────────────────────────────────
|
||||
* 图上有几步就是几项,不多建一件;触达世界的项 manualActivation 且不给 doneWhen;
|
||||
* 哨兵必须有 ifPart 且读基座数、认「办完了没有」;案卷项 id 就是任务视图键名。
|
||||
*
|
||||
* 上一版(@2.0.0)只有「派单 + 放行」两项,归一与判稳整个不存在 ——
|
||||
* C 类怎么来的、去向旗从哪儿出,全靠模型临场发挥;E5 那条边(needSourcing)
|
||||
* 因为台账里没有承载列,**从来没有成立过**。这一版把这两步补成真的。
|
||||
*/
|
||||
|
||||
export const CMMN_XML = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definitions xmlns="http://www.omg.org/spec/CMMN/20151109/MODEL">
|
||||
<case id="alternative">
|
||||
<!--
|
||||
案卷项的 id **就是任务视图里的键名**。这里只认两样:
|
||||
起单入参(altRequests —— A1 发过来的那批替代评估请求)与「对标表写了几行」(benchmark_total)——
|
||||
后者既是放行前提,也是这一单唯一的机检判据。
|
||||
案卷项的 id **就是任务视图里的键名** —— 前提的 onPart 认的是「这个键有值了」。
|
||||
流内起单时上游载荷(records 等)与本活动台账列都会摊平到任务视图顶层,照它们命名。
|
||||
|
||||
开案即有的只有上游载荷(或单飞的自由入参)。rfq_ref 是归一那一步认出来
|
||||
(或造出来)的:本活动所有台账对象都以它为主键。
|
||||
-->
|
||||
<caseFileModel>
|
||||
<caseFileItem id="altRequests" name="替代评估请求(开案即有,一条料一行)"/>
|
||||
<caseFileItem id="benchmark_total" name="对标表条数"/>
|
||||
<caseFileItem id="records" name="上游受理记录(流内开案即有)"/>
|
||||
<caseFileItem id="alt_line_total" name="清单条目数(自报)"/>
|
||||
<caseFileItem id="quote_alternative_list_rows" name="清单行数(基座现数)"/>
|
||||
<caseFileItem id="c_total" name="待选型条数"/>
|
||||
<caseFileItem id="filled_total" name="已填回替代料条数"/>
|
||||
<caseFileItem id="quote_alternative_list_type_tag_c" name="仍为 C 类的行数(基座现数)"/>
|
||||
<caseFileItem id="route_decided_total" name="已定去向"/>
|
||||
<caseFileItem id="need_sourcing" name="去向旗"/>
|
||||
</caseFileModel>
|
||||
<casePlanModel id="plan" name="替代选型" autoComplete="true">
|
||||
<sentry id="s_benchmarked">
|
||||
<onPart id="op_bm" caseFileItemRef="benchmark_total"><standardEvent>update</standardEvent></onPart>
|
||||
<ifPart id="if_bm"><condition>benchmark_total > 0</condition></ifPart>
|
||||
<!--
|
||||
① 归一完了 —— 交 FAE 那一步的入场前提。
|
||||
两边对上才算:alt_line_total 是活动自报的条数,quote_alternative_list_rows
|
||||
是基座数出来的本单行数 —— 少拆一行、多写一行都进不了下一步
|
||||
(同一个错,在第 2 拍发现比在第 10 拍便宜得多,A1 的账)。
|
||||
-->
|
||||
<sentry id="s_normalized">
|
||||
<onPart id="op_nm" caseFileItemRef="alt_line_total"><standardEvent>update</standardEvent></onPart>
|
||||
<ifPart id="if_nm"><condition>alt_line_total > 0 and quote_alternative_list_rows = alt_line_total</condition></ifPart>
|
||||
</sentry>
|
||||
<!--
|
||||
② FAE 的答复处理过了 —— 判稳那一步的入场前提。
|
||||
filled_total 是「人交回执行单之后」由 AI 清点写下的数(填回替代料的条数)——
|
||||
它只在人环走完才存在,所以它就是「经过人了」的凭据(照 A1 confirmed_total 的路子)。
|
||||
全部替代未果时它是 0:「大于等于 0」对「写过的 0」为真、对「没写过」为假
|
||||
(S-FEEL 未绑定的名字参与比较为假)。
|
||||
-->
|
||||
<sentry id="s_filled">
|
||||
<onPart id="op_fl" caseFileItemRef="filled_total"><standardEvent>update</standardEvent></onPart>
|
||||
<ifPart id="if_fl"><condition>filled_total >= 0</condition></ifPart>
|
||||
</sentry>
|
||||
<!--
|
||||
── 放行门的入场条件:**认「办完了没有」,且读基座数**(A1 s_routed 的账)────
|
||||
· 清单上不再有 C 类(quote_alternative_list_type_tag_c 由基座按值现数)——
|
||||
FAE 漏填一行替代料,那一行转不了 A/B,这道门就不开;
|
||||
· 定标守恒:A + B = 行数(两边都是基座出的数);
|
||||
· 去向定过了(route_decided_total 是判稳那一步显式写下的记账数 ——
|
||||
旗是布尔,分不清「没写」与「写了 false」)。
|
||||
-->
|
||||
<sentry id="s_routed">
|
||||
<onPart id="op_rt" caseFileItemRef="route_decided_total"><standardEvent>update</standardEvent></onPart>
|
||||
<ifPart id="if_rt"><condition>route_decided_total > 0 and quote_alternative_list_rows > 0 and quote_alternative_list_type_tag_c = 0 and quote_alternative_list_type_tag_a + quote_alternative_list_type_tag_b = quote_alternative_list_rows</condition></ifPart>
|
||||
</sentry>
|
||||
|
||||
<!-- 唯一的活:派一张执行单给 FAE,他填完提交 -->
|
||||
<humanTask id="T_select" name="替代选型:派执行单给 FAE,收回初筛与对标结论">
|
||||
<itemControl><repetitionRule id="r_sel"/></itemControl>
|
||||
<!--
|
||||
① 归一询价受理清单 —— 上游受理记录(或单飞来件)整份落成本活动的清单,
|
||||
C 类行就是本单要办的对象。**整份都落**:A/B 行原样承继 ——
|
||||
这份清单最终要整份交给下游,不是只有 C 类那几行。
|
||||
-->
|
||||
<humanTask id="S1_normalize" name="归一询价受理清单:整份落表,C 类标待选型">
|
||||
<itemControl><repetitionRule id="r_s1"/></itemControl>
|
||||
</humanTask>
|
||||
|
||||
<!-- 放行:触达世界,必须人工激活 -->
|
||||
<humanTask id="T_release" name="替代选型结论验收放行">
|
||||
<entryCriterion id="ec_rel" sentryRef="s_benchmarked"/>
|
||||
<!--
|
||||
② 替代选型交 FAE —— **一张执行单**(MVP 简化口径:选型的实质工作在系统外)。
|
||||
manualActivation + 不给 doneWhen:发卡触达真人,引擎不替你按;
|
||||
「人看过、选完、填回来了」也不是台账里任何一个数能自己变出来的。
|
||||
-->
|
||||
<humanTask id="S2_fill" name="替代选型交FAE:执行单上把 C 类行的替代料填回来">
|
||||
<entryCriterion id="ec_s2" sentryRef="s_normalized"/>
|
||||
<itemControl><manualActivationRule id="m_s2"/></itemControl>
|
||||
</humanTask>
|
||||
|
||||
<!--
|
||||
③ 判稳定标 —— 替代料查历史行情,稳转 A、不稳转 B(规则写死,零裁量);
|
||||
清单就此从「受理记录」转成「受理清单」,去向旗随之立起。
|
||||
-->
|
||||
<humanTask id="S3_reclass" name="判稳定标:替代料查行情,稳转A不稳转B,立去向旗">
|
||||
<entryCriterion id="ec_s3" sentryRef="s_filled"/>
|
||||
</humanTask>
|
||||
|
||||
<!-- 清单放行:终局唯放行 —— 触达世界,必须人工激活 -->
|
||||
<humanTask id="T_release" name="询价受理清单验收放行">
|
||||
<entryCriterion id="ec_rel" sentryRef="s_routed"/>
|
||||
<itemControl><manualActivationRule id="m_rl"/></itemControl>
|
||||
</humanTask>
|
||||
</casePlanModel>
|
||||
</case>
|
||||
</definitions>`;
|
||||
|
||||
export const NARRATIVE = `§0 开案:A1 判出一条料要替代(原型号 EOL / 缺货 / 客户点名),这一单就到你手上。
|
||||
成品只有一样:**一份能让 BD 拿去跟客户讲的替代对标结论** ——
|
||||
哪几个候选、推荐哪一个、参数差在哪、有什么风险、要不要打样验证。
|
||||
/**
|
||||
* 案例说明书 —— **只写整单一以贯之的事**(逐步做法归剧本,两处不重复写同一件事)。
|
||||
*/
|
||||
export const NARRATIVE = `§0 开案:**一份带 C 类料的询价受理记录要过替代选型**。来路有两种,形状都收(宽进):
|
||||
· **流内**:上游受理活动放行后带着它的落地事实进来 —— 顶层有单号 / 客户名 / 三类条数等
|
||||
摊平字段,\`records\` 数组里是上游全部落地行**混在一起**(带年用量与制造商的是受理记录行、
|
||||
带分级依据与历史天数的是分类表行、带各种总数的是结论行 —— 按 PN 归并自辨,别当成三张表);
|
||||
· **单飞**:没有上游,只有一段需求(型号或芯片类型 + 参数 + 场景)—— 照来件归一,
|
||||
没给的照实留空。
|
||||
|
||||
**这一单只有一步**:把选型这件事派给 FAE(执行工单),他填完你收进台账,然后提交放行。
|
||||
别把它拆成「先查规格、再判品牌、再撒网、再核验……」—— 那是他脑子里的过程,
|
||||
不是系统要管的步。你替他把表摆好就够了。
|
||||
**这个活动是复杂活动的 MVP 简化形**:替代选型的实质工作(查规格、撒网、参数对比)
|
||||
由 FAE 在**系统外**完成,系统只负责三件事 —— 把清单归一好、把执行单组好交给他、
|
||||
把他填回的替代料**判稳定标**(在库行情稳转 A,不稳转 B)。
|
||||
|
||||
【T_select 派执行单】发 human 行动(workOrder="execution"),卡面 blocks 放**两张可编辑表**:
|
||||
· 初筛清单:列 = 原型号 / 候选型号 / 品牌 / 生命周期;
|
||||
· 替代对标表:列 = 候选型号 / 替代等级 / 参数差异项 / 差异风险 / 验证建议 / FAE签字。
|
||||
两张都 editable:true;没有的值给空字符串 —— 空格子界面会自己标红「待填写」。
|
||||
ask 一句话说清要他做什么;basis 摆上原型号、芯片类型、客户的特殊要求(裸卡基座拒发)。
|
||||
**成品只有一样**:一份**询价受理清单** —— 整份行都在、C 类已全部转成 A 或 B、
|
||||
去向旗立了(还有 B 类就去寻源补价,全 A 直通定价)。判稳的尺与三分类 P-03 的 A/B
|
||||
两行同一把:**历史价 ≤ 90 天且行情稳 → A,否则 → B**。
|
||||
FAE 的定案不只是一个型号:**替代等级(P2P 直换 / FUNC 功能兼容 / OTHER 须验证)、
|
||||
参数差异、风险与验证建议一并落表** —— 那是他的专业产出,逐颗可溯。
|
||||
|
||||
他提交后,回传值出现在你的轨迹里:表格那一份的键是 **table:0 / table:1**(块序号),
|
||||
值是整张表的 JSON —— **第一行是列名**,其余每行一条,列序与你派出去时一致。
|
||||
照它 write 进 \`quote_alternative.shortlist\` 与 \`quote_alternative.benchmark\`,
|
||||
并把对标表条数记进 benchmark_total。**写完就 finish T_select,别再发第二张单** —— 他已经答过了。
|
||||
**人环两次,不多不少**:FAE 交回**一张选型执行单**(工作单里一颗待选型芯片一页,
|
||||
右上角翻页逐颗定案,必填缺着按不下提交)、放行时 FAE 签字。
|
||||
|
||||
【提交放行】对标表有行了 —— **先 start T_release**(人工激活:放行触达世界,必须按一下),
|
||||
然后 submit,BD 验收。终局唯放行:你不能自己宣布完成。
|
||||
【一路上要说话】负责人正看着这一单。**每一拍都带一句 say** —— 说业务的话:
|
||||
哪几颗料要替代、替代料查出来什么行情、这单接下来往哪走;
|
||||
不说「归一化」「写草稿 N 行」这类系统词。到了要找人的那一拍,先说清这一轮办完了什么、
|
||||
为什么现在需要他。别每拍一个腔调复读。
|
||||
|
||||
【一路上要说话】负责人正看着这一单。每一拍带一句 say,说**业务的话**:
|
||||
哪颗料要替代、你打算怎么办、FAE 回了什么结论、这一单往哪走。
|
||||
一两句、口语,像同事扭头说一声。别报「写草稿 2 行」这种系统词 ——
|
||||
他明天要拿这些话去跟客户讲。`;
|
||||
【怎么把一项干完 · 一拍连做】一个计划项常要两三个动作才交得出成果。write 和 tool
|
||||
都**不会**自动把那一项收掉 —— 都做完了,用 finish 宣告完成。动作排进同一拍的 actions
|
||||
串里一口气给,别拆拍。只有两处必须停拍:调工具要看出参(tool 放串尾),
|
||||
发卡 / 提交会挂起(只能是串尾)。**常路 6-9 拍就该收口** —— 选型只有一张卡,颗数多不多不加拍。
|
||||
|
||||
§Z 结案:FAE 在验收单上签字,系统把草稿合并成正式清单并发出 roster 口的载荷 ——
|
||||
清单整份交给下游,下游按自己的口径归一需要的数据。`;
|
||||
|
||||
/**
|
||||
* 步骤剧本 —— 与 A1 同一套机制:`doneWhen` 为真,引擎自己收步、**不问模型**。
|
||||
*
|
||||
* 只有一条真活。放行那一项不给 `doneWhen` —— 它触达世界,必须人按一下(铁律③)。
|
||||
* 步骤剧本 —— 一个计划项一条;`doneWhen` 是「成果已存在」的判据,不是「该不该做」。
|
||||
*/
|
||||
export const ALTERNATIVE_STEPS = [
|
||||
{
|
||||
item: 'T_select',
|
||||
intent: '派一张执行单给 FAE,收回初筛清单与替代对标结论,并结算汇总数',
|
||||
writes: ['quote_alternative.shortlist', 'quote_alternative.benchmark', 'quote_alternative.verdict'],
|
||||
reads: [],
|
||||
item: 'S1_normalize',
|
||||
intent: '把上游受理记录(或单飞来件)整份归一成选型底表,C 类行标待选型',
|
||||
writes: ['quote_alternative.list', 'quote_alternative.verdict'],
|
||||
/*
|
||||
* `records` 是上游整包落地行 —— 不声明的话它会被整表段的截断刀砍掉
|
||||
* (那一段按字符数截,上游一单的落地行远超刀口,砍掉的恰是 C 类行)。
|
||||
* 声明了的键**置前且不参与截断**。单飞起单没有这个键,声明也无副作用。
|
||||
*/
|
||||
reads: ['records'],
|
||||
/* 归一与 FAE 选型期间摆**选型工作单**;判稳转正后才换收口那张清单 */
|
||||
view: 'alt-worksheet',
|
||||
tools: [],
|
||||
/*
|
||||
* 对标表有行了才算办完。**不能写 `benchmark_total != null`** ——
|
||||
* S-FEEL 里未绑定的名字 `!= null` 求值为 true,那一步开局即被收掉(A1 踩过,测里拦下的)。
|
||||
* 归一完才算办完:两边对上 —— alt_line_total 自报、rows 基座现数。
|
||||
* **不能写 `records != null`**:S-FEEL 未绑定名字 `!= null` 为 true,开局即收(A1 踩过)。
|
||||
*/
|
||||
doneWhen: 'benchmark_total > 0',
|
||||
guide: `**照这个骨架发,一个字段都别少**(prose 描述不管用,直接抄):
|
||||
{"kind":"human","itemId":"T_select","workOrder":"execution","card":{
|
||||
"title":"…","ask":"这颗料原型号停产,请挑替代并给对标结论",
|
||||
"basis":[{"k":"…","v":"…"}],
|
||||
"blocks":[
|
||||
{"t":"table","title":"初筛清单","cols":["原型号","候选型号","品牌","生命周期"],"editable":true,
|
||||
"rows":[["LM358DR","LM358BIDR","",""],["LM358DR","TLV9062IDR","",""]]},
|
||||
{"t":"table","title":"替代对标表","cols":["候选型号","替代等级","参数差异项","差异风险","验证建议","FAE签字"],"editable":true,
|
||||
"rows":[["","","","","",""]]}
|
||||
]}}
|
||||
**rows 必须有行**:一条料一行,不知道的值给空字符串(界面自己标红「待填写」)。
|
||||
只给 cols 不给 rows,人看到的是一排表头加一片空白,一个格子都填不了(实测栽过)。
|
||||
**blocks 少了整张卡就废了** —— 基座会用当下局面兜底成一句「需要你判断下一步」,
|
||||
人拿到一张没有表的空卡,这一步等于没派(实测栽过)。
|
||||
doneWhen: 'alt_line_total > 0 and quote_alternative_list_rows = alt_line_total',
|
||||
guide: `第一件事:把这一单的**选型底表**落出来 —— 整份承继,不是只有 C 类。
|
||||
工作区这一步摆的是**替代选型工作单**(逐颗料的选型档案与填回区),你落的行就是它的血肉。
|
||||
|
||||
**候选是你提的,不是让 FAE 从零想** —— 初筛清单每个原型号先摆 **2~3 行候选**
|
||||
(原型号 + 候选型号两列你填,你认得这些料;品牌与生命周期留空让他核)。
|
||||
判据「2~3 颗分级候选经确认」机检的就是候选条数,只给一行**过不了门**。
|
||||
替代对标表照候选逐行起,basis 摆上原型号、芯片类型、客户特殊要求(**裸卡基座拒发**)。
|
||||
【料从哪儿来】
|
||||
· 流内(任务数据里有 \`records\` 数组):那是上游全部落地行**混在一起**的一份 ——
|
||||
同一颗料会出现两三次:带 eau/brand/target_price 的是**受理记录行**(以它为准),
|
||||
带 basis/history_days/market_stable 的是分类表行(它的 type_tag 与受理记录一致),
|
||||
带 line_total/type_a_total 这类总数的是结论行(不是料,别落进清单)。
|
||||
**按 pn 归并**:一颗料归一成清单里的一行,列取受理记录行的值;
|
||||
type_tag 照抄成本清单的 **orig_type(原标)与 type_tag(现标)两列同一个值**。
|
||||
· 单飞(没有 \`records\`):照入参与正文归一 —— 有型号落型号;只给芯片类型与参数、
|
||||
没有具体 PN 的,\`pn\` 写「类型-场景」需求代号(如「运放-车规-01」),
|
||||
这类需求本来就是来选型的,orig_type 与 type_tag 都写 C。
|
||||
|
||||
他提交后回传值进你的轨迹:表格的键是 **table:0 / table:1**,值是整张表的 JSON,
|
||||
**第一行是列名**。照它 write 进 \`shortlist\` 与 \`benchmark\`,
|
||||
**同一拍再写一行 \`quote_alternative.verdict\`**(验收机检读的就是它):
|
||||
· candidate_total = 初筛清单条数(要 ≥2);
|
||||
· benchmark_total = 对标表条数;
|
||||
· undocumented_total = 对标表里「参数差异项」或「差异风险」还空着的条数(要 = 0);
|
||||
· recommend_pn 主推候选、summary 一句人话结论。
|
||||
这三个数写不对,submit 会被门挡回来 —— **它们不是台账装饰,是判据本身**。
|
||||
**写完就 finish,别再发第二张单** —— 他已经答过了。
|
||||
**每一行都要带 \`rfq_ref\`** —— 它是这一单的单标识(起单入参里就有,原样抄进去)。
|
||||
台账主键第一列就是它:不写,这一行会和**别的单**同料号的那一行撞主键,把人家覆盖掉
|
||||
(实测栽过:A4 的报价草案主键只有 pn,跑四轮只剩最后一轮的 3 行)。`,
|
||||
【单号 rfq_ref】入参有 \`rfqRef\` 就**原样照抄**;没有就从主题/正文里认(RFQ-xxxx);
|
||||
认不出才造一个稳定案号「ALT-<型号或类型>」—— 它是本活动所有台账行的主键,
|
||||
造完这一单从头用到尾,**不许中途换写法**(换一个写法就是新开一行)。
|
||||
造号**只从本单来件取材,不许从台账里已有的别单单号里挑** —— 正式表里躺着的
|
||||
单号是别人的单,借它的号等于把两单的行混进同一个案卷。
|
||||
|
||||
【逐列怎么落】写 \`quote_alternative.list\`,一颗料一行,一拍写完(rows 收数组):
|
||||
pn(**一个字符不许改**)、customer_pn、category、brand、eau、target_price、lead_time、
|
||||
**remark(客户备注:预授权替代、认证要求、禁用约束 —— 选型的第一手依据,一个字别丢)**
|
||||
照上游值抄,没有的留空字符串(**绝不写 0 顶空**);orig_type / type_tag 照抄原标
|
||||
(**只写 A、B、C 三个大写字母之一**,写别的基座数不出来);
|
||||
C 类行把「为什么是 C」写进 basis(从分类表行的 basis 抄,或客户点名替代的原话);
|
||||
alt_pn / alt_brand / alt_grade / alt_diff / alt_risk / alt_verify / alt_note
|
||||
**全部留空** —— 那是 FAE 的定案,你不许编。
|
||||
|
||||
【同一拍记账】写 \`quote_alternative.verdict\`(一单一行):
|
||||
rfq_ref、customer_code / customer_name(顶层摊平字段里有就抄,没有留空)、
|
||||
**alt_line_total** = 清单行数、**c_total** = C 类条数。
|
||||
写完 finish 这一项 —— 引擎按「自报条数 = 基座行数」收步,少拆多写都过不去。`,
|
||||
},
|
||||
{
|
||||
item: 'S2_fill',
|
||||
intent: '一张选型执行单交 FAE:工作单一颗一页,定案(型号/品牌/等级)逐页填回',
|
||||
writes: ['quote_alternative.verdict'],
|
||||
reads: ['quote_alternative.list'],
|
||||
view: 'alt-worksheet',
|
||||
tools: [],
|
||||
/*
|
||||
* 不给 doneWhen —— 发卡触达真人(manualActivation),引擎不替人按;
|
||||
* 「FAE 选完填回来了」也判不出来:它是人环,不是台账里能自己变出来的数。
|
||||
*/
|
||||
guide: `底表归一好了,**该 FAE 出场了**。规矩(2026-08-02 用户定):
|
||||
**一张执行单,工作单里一颗待选型芯片一页** —— 他在右上角翻页逐颗定案,
|
||||
定案三格(型号/品牌/等级)是每页的必填,缺着按不下提交(系统的闸看着)。
|
||||
|
||||
【怎么发】照这个骨架发一张卡(它标了人工激活:发卡就算启动,不必单发 start;
|
||||
引擎也不会替你收 —— 人交回后要你自己 finish)。卡面是纯文本,
|
||||
steps/standard 里**别写星号记号**:
|
||||
{"kind":"human","itemId":"S2_fill","workOrder":"execution","card":{
|
||||
"title":"替代选型:<单号> 待选型 <N> 颗",
|
||||
"ask":"这几颗料要替代:请照工作单逐页的选型档案在系统外完成选型,把定案填进各页右栏的「替代定案」(型号/品牌/等级是必填,缺着按不下提交),填完保存,回这张卡提交;确实找不到替代的,在那一页的选型备注写明缘由后交回。",
|
||||
"steps":["工作单一颗一页,右上角翻页;每页「替代定案」栏里给出替代料型号与品牌,替代等级点三档之一:P2P(同封装同引脚可直换)/ FUNC(功能兼容,需外围电路或 layout 调整)/ OTHER(部分兼容,须打样验证)",
|
||||
"P2P 必须逐项核对过五样:封装尺寸、引脚定义、电气参数、温度等级、认证 —— 以原厂官网规格书为准,同封装不等于同引脚;核对过哪几项写进参数差异项",
|
||||
"FUNC 或 OTHER 的,参数差异项与差异风险写清差在哪、要动什么;验证建议写明要不要打样、验什么",
|
||||
"客户备注里已预授权的替代优先采信;点名禁用的品牌不得作候选;确实找不到替代:在那一页的选型备注写明缘由(那也是一个答案);填完保存,回这张卡提交"],
|
||||
"standard":"每一颗:型号、品牌、等级都有且来源可溯(三格必填,闸看着);或备注写明替代未果的缘由。交回后判稳定标由系统接着办。",
|
||||
"basis":[{"k":"<待选型 PN 之一>","v":"<为什么是 C + 客户约束(预授权/认证/禁用)>"}]}}
|
||||
· \`basis\` 逐颗列待选型的料(几颗写几条);标题带单号与颗数。
|
||||
· **卡上不摆格子**(填写全在工作区):定案填在工作单各页的「替代定案」栏里,
|
||||
不往卡里塞 \`fields\` 或 \`blocks\`。
|
||||
发完卡挂起,这一拍到此为止。**这张卡一单只发一次** —— 必填有提交闸兜着,
|
||||
卡回来时每颗要么三格齐、要么备注写明未果。
|
||||
|
||||
【人交回之后】**他的定案已经在台账里了** —— 他在工作单上按「保存」那一刻,
|
||||
基座就把那几格落进了草稿层(该由人亲手落下的,不经你的手)。
|
||||
**不许再把那几格 write 一遍** —— 值相同的写入被「写了等于没写」拒(实测)。
|
||||
这一拍只做两件事,然后 finish:
|
||||
① 清点 alt_pn 有值的颗数写 **filled_total** 进 verdict(全部未果就是 0,照实写);
|
||||
② finish 这一项,**这一拍到此为止** —— 判稳、转标、提交都不是这一拍的活:
|
||||
转标还没做,submit 排进这一串必被「判据没过」拒回(实测白挨一次)。
|
||||
**这一拍也不许调 crm.history-price-read** —— 查行情是判稳那一步(下一步)开头的活;
|
||||
实测提前查过一次:查完没处落,连着四拍把同一行原样重写、四次被
|
||||
「写了等于没写」拒回,白烧四拍才想起该 finish。`,
|
||||
},
|
||||
{
|
||||
item: 'S3_reclass',
|
||||
intent: '替代料批量查历史行情:稳转 A、不稳转 B;清单转正,立去向旗',
|
||||
writes: ['quote_alternative.list', 'quote_alternative.verdict'],
|
||||
reads: ['quote_alternative.list'],
|
||||
view: 'alt-roster',
|
||||
tools: ['crm.history-price-read'],
|
||||
/*
|
||||
* **收步判据与验收判据同源**:C 类清零(基座按值现数)才算这一步办完 ——
|
||||
* 收步比验收松,松出来的那一截就是返工(A1 的账)。
|
||||
* route_decided_total 是本步显式写下的记账数(布尔旗分不清「没写」与「写了 false」)。
|
||||
*/
|
||||
doneWhen: 'quote_alternative_list_type_tag_c = 0 and route_decided_total > 0',
|
||||
guide: `FAE 填回来了,现在把清单**转正**:每颗替代料判稳、定标,清单从「受理记录」
|
||||
变成「询价受理清单」。
|
||||
|
||||
【第一拍:查行情】把所有原标 C 行的 **\`alt_pn\` 那一列的值**(替代料的料号)收进
|
||||
一个数组,调 \`crm.history-price-read\` 一次传完(参数 pns 收数组)。
|
||||
**判稳的行情只有这一条来路 —— 这一拍亲自查 alt_pn。**两条近路都不许走:
|
||||
· **不许传原 PN**(pn 列是被替代的旧料,查它查到的是旧料的行情);
|
||||
· **不许拿上游带进来的数顶替**:入参里若躺着 history_days / market_stable /
|
||||
lifecycle,那是 A1 当时查**原 PN** 得的账 —— 跟这颗**替代料**稳不稳没有关系。
|
||||
实测抄过一次近路:上游写着 9999,模型没调工具就把替代料判成 B,
|
||||
而那颗替代料库里明明有 43 天的稳定历史,整单去向就此走岔。
|
||||
调完这一拍就结束(工具出参要下一拍才看得见)。
|
||||
|
||||
【第二拍:定标 + 记账 + 收步,一拍连做】
|
||||
① **规则写死,不留裁量**(与三分类 P-03 的 A/B 两行同一把尺):
|
||||
historyDays ≤ 90 且 marketStable = true → **type_tag 转 A**;否则 → **转 B**。
|
||||
工具回的 lifecycle 若是 EOL/缺货/要求替代 —— 那说明替代料选错了,**不转标**,
|
||||
当成替代未果处置(见③)。
|
||||
② 逐行写回 \`quote_alternative.list\`(按 rfq_ref + pn 对行,主键一个字符不许改):
|
||||
type_tag(A 或 B,**照规则写,不许臆断**)、history_days(工具出参照抄)、
|
||||
basis(一句依据:「替代料 <alt_pn> 历史价 <N> 天·行情稳 → 转 A」这样)。
|
||||
**先对号再用**:工具出参每行带着查询的 pn —— 那个 pn 必须等于这一行的 alt_pn,
|
||||
对不上就是第一拍传错了列,回去重查,别把别人的行情安到这颗替代料头上。
|
||||
orig_type **不动** —— 原标是留痕,转的是现标。
|
||||
③ **替代料留空(FAE 判未果)的 C 行**:
|
||||
· 选型备注写了缘由 → 用 \`drop\` 把那一行撤出本单草稿(主键照 \`_keys\` 名单**原样粘**),
|
||||
把撤了哪几颗、为什么写进 verdict.skipped_note,并把 alt_line_total 改成撤后的行数
|
||||
(清单条数跟着改对,别让「条数 5 而表里 4 行」把归一那步的判据顶翻);
|
||||
· 备注也空着 → 发一张**决策卡(decide)**问负责人:「这颗料替代未果,剔出本轮
|
||||
还是退回整单」两个选项摆出来,人点哪个照哪个办。**只问这一次**
|
||||
(补全卡已退役 —— 二选一是处置,本就该用决策卡)。
|
||||
④ 写 verdict:converted_a_total / converted_b_total(转成 A/B 各几条,照②的实数)、
|
||||
**need_sourcing**(清单里还有 B 类 → true,全 A → false;照基座读数
|
||||
quote_alternative_list_type_tag_b 的正负写,别凭记忆)、**route_decided_total 记 1**、
|
||||
summary 一句人话(几颗替代、转成什么、往哪走)。
|
||||
⑤ finish 这一项,**这一拍到此为止**。引擎按「C 类清零 + 去向定过」收步 ——
|
||||
有一颗 C 没处置,这一步收不掉,出路只有三条:转标(填了替代料)、
|
||||
剔除(未果且有说明)、问人(未果且没说明)。
|
||||
**别把 submit 排进这一串**:放行那一步要先把 L3 裁量裁过才轮得到 submit,
|
||||
跳过它会被当场拒回(实测白挨过一次)。
|
||||
|
||||
**去向不用你选,也不用人选**:契约给两个出口各写了判据(还有没有 B 类),
|
||||
放行那一刻基座按序求值自己定;need_sourcing 那枚旗是给流程包的边读的,
|
||||
两处读的都是同一个事实 —— 你只负责把标转对。`,
|
||||
},
|
||||
{
|
||||
item: 'T_release',
|
||||
intent: '对标结论已齐,提交放行交 BD 验收',
|
||||
view: 'alt-roster',
|
||||
intent: '清单已转正,提交放行交 FAE 验收',
|
||||
writes: [],
|
||||
reads: [],
|
||||
tools: [],
|
||||
// 放行触达世界 —— 引擎不自动收它(所以这里不给 doneWhen)
|
||||
guide: `对标表有行了 —— **先 start T_release**(它标了人工激活),然后 submit,BD 验收。
|
||||
/* 放行触达世界,必须人按一下 —— 引擎不自动收它(剧本里也不给 doneWhen) */
|
||||
guide: `清单整份转正、去向已定 —— 可以走放行了(T_release 人工激活:
|
||||
动它就算启动,不必单发 start)。先把裁量判据裁掉,然后 submit,同一拍连做:
|
||||
|
||||
· judge criterion="替代料来源可溯且选型说明已留:以原厂官网规格书或客户预授权为准,每颗替代写明凭什么" ——
|
||||
看清单里每颗替代料的 basis 与选型备注:都写了依据就 satisfied=true;
|
||||
有替代料说不出来源的,satisfied=**false**,rationale 逐颗写清哪几颗没依据,
|
||||
交签字的人定。**裁成不满足照样能提交** —— 理由连着卡一起交给他,那正是这条判据的用处。
|
||||
criterion 照判据名**整句原样抄**,写别的名字对不上。
|
||||
|
||||
**去向不用你裁**:两个出口各写了判据,放行那一刻基座按序求值、首个命中即出。
|
||||
终局唯放行:你不能自己宣布完成。`,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 阶段 —— 进度条的刻度,只给人看。除放行外每个计划项恰属一个阶段;
|
||||
* 放行那一格由基座统一加(CLOSING_PHASE),人看到的是 x/4。
|
||||
*/
|
||||
export const ALTERNATIVE_PHASES = [
|
||||
{ name: '归一清单', items: ['S1_normalize'] },
|
||||
{ name: '选型填回', items: ['S2_fill'] },
|
||||
{ name: '判稳定标', items: ['S3_reclass'] },
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user