forked from ChaiHao/BPOS-MVP
判据 ⑥ 跑通:A4 成本定价全链 —— 补齐取价基准这一环
A4 卡在 S3 底价自检要 `deviation`,而 S1「取价基准」调的是历史价工具,
那个工具**根本不回价格**:声明说出 deviation,工具给不出,于是永远缺一环。
按业务本意补齐:
· `crm.history-price-read` 增回 `lastPrice`(上次成交单价)—— 一个不回价的
「历史价工具」取不出价格基准;无历史的新料号回 0,由下游按「无基准」处置,
不凭空编一个偏离率。
· 新增纯工具 `quote-pricing.basis`:基准价 ↔ 拟报价 → 偏离率。
偏离率要等 S2 定出拟报价才算得出来,所以落在 S2 之后(新步 S2B)。
· A4 声明:S1 改落 `last_price`,新增 S2B,台账加 `last_price` 列。
顺带修:样例集一份喂所有工具,`quote-pricing.basis` 的必填 `quotedPrice` 不在其中,
新工具过不了两审 → 活动包安装被拒 → 旧资产继续生效,现象是「改了没反应」。
样例改为各家必填的并集。
现在 A4 跑完整条:取价基准 → DMN 定价(利润模型 P-01)→ 算偏离率 →
DMN 底价自检(底价门禁 P-02,处置=直接放行)→ 条件跳步 → 报价草案验收放行。
gates: tsc / eslint / depcruise / 397 测试 全绿
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
This commit is contained in:
@@ -13,19 +13,36 @@ import type { ToolHandler } from '@modules/toolbox';
|
||||
const historyPriceRead: ToolHandler = async ({ input }) => {
|
||||
const pn = String(input['pn'] ?? '');
|
||||
// 录制样本:演示用的历史价情报(真 CRM 接入时换 endpoint,契约不变)
|
||||
const table: Record<string, { historyDays: number; marketStable: boolean; lifecycle: string }> = {
|
||||
LM358DR: { historyDays: 30, marketStable: true, lifecycle: '在产' },
|
||||
NE555P: { historyDays: 240, marketStable: false, lifecycle: '在产' },
|
||||
TL072CDR: { historyDays: 15, marketStable: true, lifecycle: 'EOL' },
|
||||
// 历史价情报含**上次成交单价** —— 没有价的「历史价工具」是取不出价格基准的
|
||||
const table: Record<string, { historyDays: number; marketStable: boolean; lifecycle: string; lastPrice: number }> = {
|
||||
LM358DR: { historyDays: 30, marketStable: true, lifecycle: '在产', lastPrice: 8.4 },
|
||||
NE555P: { historyDays: 240, marketStable: false, lifecycle: '在产', lastPrice: 3.25 },
|
||||
TL072CDR: { historyDays: 15, marketStable: true, lifecycle: 'EOL', lastPrice: 21.6 },
|
||||
};
|
||||
const hit = table[pn];
|
||||
if (hit === undefined) {
|
||||
// 无历史 → 走 B(重估后报);这不是错误
|
||||
return { ok: true, output: { historyDays: 9999, marketStable: false, lifecycle: '未知', hit: false } };
|
||||
// 无历史 → 走 B(重估后报);没有价格基准,基准价回 0 由下游按「无基准」处置
|
||||
return { ok: true, output: { historyDays: 9999, marketStable: false, lifecycle: '未知', hit: false, lastPrice: 0 } };
|
||||
}
|
||||
return { ok: true, output: { ...hit, hit: true } };
|
||||
};
|
||||
|
||||
/**
|
||||
* 取价基准 —— **纯工具**:报价相对基准价的偏离率。
|
||||
* 「能算的不问 LLM」:同输入必同结论。无基准价(新料号)时偏离率记 0,
|
||||
* 由底价门禁 P-02 按「无基准」放行 —— 不能凭空编一个偏离率出来。
|
||||
*/
|
||||
const basis: ToolHandler = async ({ input }) => {
|
||||
const lastPrice = Number(input['lastPrice'] ?? 0);
|
||||
const quotedPrice = Number(input['quotedPrice'] ?? 0);
|
||||
if (!Number.isFinite(lastPrice) || lastPrice <= 0) {
|
||||
return { ok: true, output: { deviation: 0, basis: 'none', lastPrice: 0 } };
|
||||
}
|
||||
const deviation = (quotedPrice - lastPrice) / lastPrice;
|
||||
return { ok: true, output: { deviation: Math.round(deviation * 10_000) / 10_000, basis: 'history', lastPrice } };
|
||||
};
|
||||
|
||||
/** 三分类规则 P-03 的决策表 —— 与活动包里的资产同一份规则 */
|
||||
const P03_RULES = [
|
||||
{ id: 'p03-c', when: ['-', '-', '"EOL","缺货","要求替代"'], then: { type: 'C', play: '转案处理' } },
|
||||
@@ -109,6 +126,7 @@ const mailSend: ToolHandler = async ({ input, connection }) => {
|
||||
export const FIRST_PARTY_TOOLS: ReadonlyArray<readonly [string, ToolHandler]> = [
|
||||
['crm.history-price-read', historyPriceRead],
|
||||
['quote-intake.classify', classify],
|
||||
['quote-pricing.basis', basis],
|
||||
['quote-pricing.margin', margin],
|
||||
['quote-pricing.floor-gate', floorGate],
|
||||
['quote-archive.profile', profile],
|
||||
|
||||
Reference in New Issue
Block a user