进度条补回漏掉的那一格;删掉一条已经不存在的路
用户送来一条实测日志:中间被拒四次,卡片进度条也走得不对。两处都不是模型跑偏。 **进度条漏了一格** —— `INTAKE_PHASES` 里没有 `S3_confirm`(它是 08-01 才补回成一项的): 计划项六个、名单里五个。于是 S2 一收,前两格全过,条当场跳到「判定去向」; 而人这会儿正对着受理需求审定那张卡 —— **他手上办的那件事在条上没有格子**, 条却已经走过去了。那不是走快了一格,是它在说一件没发生的事。 补成四格(定位客户 / 归一受理 / 交你审定 / 判定去向)+ 基座统一加的放行收口; 包内自测钉死「除放行外每一项恰好属于一个阶段」「一项不进两个阶段」。 **那四次拒回是一条已经不存在的路** —— 说明书里还留着「人交回来还缺必填,就再发一张卡」。 提交闸上线后那条路没有了:缺必填根本按不下提交。模型照它办,每次都撞在 「这件事刚问过,人也答过了」上,白烧四拍。改成「这张卡一单只发一次」。 同批把提交闸补到**服务端**(收下回传之前把住):说明书向模型承诺 「卡回来时必填一定是齐的」,那句承诺只有服务端拦得住才算数。 A1 三案例复跑:9 拍 / 10 拍 / 14 拍,前两个**被拒 0**(修前是 12 拍被拒 1), 进度条五格逐格走对。五道门禁全绿(975 passed)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JsTDjoHovERXyy6Wmw1ALp
This commit is contained in:
@@ -391,6 +391,16 @@
|
|||||||
那不是渲染毛病,是**真的中间态**(合并 / 发口 / 落终态还在跑)。从前它落在通用四态里 ——
|
那不是渲染毛病,是**真的中间态**(合并 / 发口 / 落终态还在跑)。从前它落在通用四态里 ——
|
||||||
待办清零先闪一句「都办完了」再跳「已收尾」;那句话在那一刻是对的,可它说的是另一件事。
|
待办清零先闪一句「都办完了」再跳「已收尾」;那句话在那一刻是对的,可它说的是另一件事。
|
||||||
现在这一段说「字已签下,正在落地」。**中间态本来就该说出来,只是要说对。**
|
现在这一段说「字已签下,正在落地」。**中间态本来就该说出来,只是要说对。**
|
||||||
|
- **进度条漏了一格,和一条已经不存在的路**(2026-08-02 用户送来一条实测日志):
|
||||||
|
①`INTAKE_PHASES` 漏了 `S3_confirm`(它是 08-01 才补回成一项的)—— 计划项六个、名单里五个,
|
||||||
|
于是 S2 一收进度条当场跳到「判定去向」,而人这会儿正对着受理需求审定那张卡:
|
||||||
|
**他手上办的那件事在条上没有格子**,条却已经走过去了。补成四格
|
||||||
|
(定位客户 / 归一受理 / 交你审定 / 判定去向 + 基座统一加的放行收口),
|
||||||
|
包内自测钉死「除放行外每一项恰好属于一个阶段」。
|
||||||
|
②说明书里还留着「人交回来还缺必填,就再发一张卡」—— **提交闸上线后那条路已经不存在**
|
||||||
|
(缺必填按不下提交),模型照它办,每次都撞在「这件事刚问过,人也答过了」上,连烧四拍。
|
||||||
|
改成「这张卡一单只发一次」;同时把提交闸补到**服务端**(收下回传之前把住)——
|
||||||
|
说明书向模型承诺「卡回来时必填一定是齐的」,那句承诺只有服务端拦得住才算数。
|
||||||
- 后端 19 模块 + 6 活动包 + 前端 features;五道门禁全绿(2026-08-02)。
|
- 后端 19 模块 + 6 活动包 + 前端 features;五道门禁全绿(2026-08-02)。
|
||||||
- **别用 `db:seed` 当装活动的手段**:它会重写整套治理台配置。装活动用 `pnpm activities:install`。
|
- **别用 `db:seed` 当装活动的手段**:它会重写整套治理台配置。装活动用 `pnpm activities:install`。
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vitest';
|
||||||
import { evaluateCondition } from '@sfeel';
|
import { evaluateCondition } from '@sfeel';
|
||||||
import { INTAKE_STEPS } from '../src/case-model.ts';
|
import { INTAKE_PHASES, INTAKE_STEPS } from '../src/case-model.ts';
|
||||||
import { CMMN_XML } from '../src/case-model.ts';
|
import { CMMN_XML } from '../src/case-model.ts';
|
||||||
import { manifest } from '../src/manifest.ts';
|
import { manifest } from '../src/manifest.ts';
|
||||||
|
|
||||||
@@ -250,3 +250,34 @@ function safeEval(expression: string, scope: Record<string, unknown>): boolean {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **每个计划项都得有格可待**(2026-08-02 用户:「卡片的进度条走的不对」)。
|
||||||
|
*
|
||||||
|
* 从前 `INTAKE_PHASES` 漏了 `S3_confirm`:计划项六个、名单里五个。
|
||||||
|
* 于是 S2 一收,前两格全过,进度条当场跳到「判定去向」—— 而人这会儿正对着
|
||||||
|
* 受理需求审定那张卡。**他手上办的那件事在条上没有格子**,条却已经走过去了:
|
||||||
|
* 那不是走快了一格,是它在说一件没发生的事。
|
||||||
|
*/
|
||||||
|
describe('阶段刻度:每一项都有格可待', () => {
|
||||||
|
const inPhase = new Set(INTAKE_PHASES.flatMap((p) => p.items));
|
||||||
|
|
||||||
|
it('**除放行外每一项恰好属于一个阶段** —— 漏一项,进度条就会在它办着的时候跳过去', () => {
|
||||||
|
const planned = INTAKE_STEPS.map((s) => s.item).filter((id) => id !== 'T_release');
|
||||||
|
expect(planned.filter((id) => !inPhase.has(id))).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('一项不进两个阶段 —— 进了两个,「这一格过没过」就有两种答案', () => {
|
||||||
|
const all = INTAKE_PHASES.flatMap((p) => p.items);
|
||||||
|
expect(all.length).toBe(new Set(all).size);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('**放行不在名单里** —— 收口那一格由基座统一加,活动自己起名会各叫各的', () => {
|
||||||
|
expect(inPhase.has('T_release')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('阶段里不许出现案例模型没有的项 —— 那一格永远过不去', () => {
|
||||||
|
const ids = new Set(INTAKE_STEPS.map((s) => s.item));
|
||||||
|
expect([...inPhase].filter((id) => !ids.has(id))).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -531,9 +531,12 @@ export const INTAKE_STEPS = [
|
|||||||
条目数说 9 而表里躺着 10)。真发现第一次的 PN 抄错了,在 say 里说明并交给人,
|
条目数说 9 而表里躺着 10)。真发现第一次的 PN 抄错了,在 say 里说明并交给人,
|
||||||
别自己用新 PN 再写一行。
|
别自己用新 PN 再写一行。
|
||||||
|
|
||||||
【**必填还缺就不能收**】confirmed_total 记了也没用:必填(PN / 年用量)缺一条,
|
【**这张卡一单只发一次**】人交回来之后,不论还缺什么,**都不许再发同一张卡**。
|
||||||
下一步就是进不去 —— 这是验收标准。人交回来还缺必填,就再发一张卡说清还差哪几条。
|
必填(PN / 年用量)有提交闸兜着:缺一条他根本按不下提交,所以卡交回来时必填一定是齐的;
|
||||||
选填缺则不拦:问过就够了,别为它反复发第二张卡。
|
选填缺口不拦单,留着交放行的人定。
|
||||||
|
实测栽过多次(2026-08-02 那一单连撞四拍):从前这儿写着「人交回来还缺必填,就再发一张卡」——
|
||||||
|
而提交闸上线后那条路已经不存在了,模型照它办,每次都撞在
|
||||||
|
「这件事刚问过,人也答过了」上,白烧四拍。
|
||||||
|
|
||||||
【人把格子留空交回来 = **客户给不了**,那也是一个答案】
|
【人把格子留空交回来 = **客户给不了**,那也是一个答案】
|
||||||
这时候要做的**不是再问一遍**(基座会当场拒:同一件事不许问第二遍),而是:
|
这时候要做的**不是再问一遍**(基座会当场拒:同一件事不许问第二遍),而是:
|
||||||
@@ -709,8 +712,21 @@ C 类开没开替代评估请求、B 类开没开询价请求,由两条机检判
|
|||||||
* 只列**激活态**的三段。放行不在这儿:每个活动都以放行收口(铁律③),
|
* 只列**激活态**的三段。放行不在这儿:每个活动都以放行收口(铁律③),
|
||||||
* 那是系统的规矩不是 A1 的阶段;进度条自己在末尾加那一格,所以人看到的是 x/4。
|
* 那是系统的规矩不是 A1 的阶段;进度条自己在末尾加那一格,所以人看到的是 x/4。
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
* 给人看的刻度 —— **每个计划项都得有格可待**(2026-08-02 用户:「卡片的进度条走的不对」)。
|
||||||
|
*
|
||||||
|
* 从前这份名单漏了 `S3_confirm`(它是 2026-08-01 才补回成一项的):
|
||||||
|
* 计划项有六个,名单里只有五个。于是 S2 一收,前两格全过,进度条当场跳到「判定去向」——
|
||||||
|
* 而人这会儿正对着受理需求审定那张卡。**他手上办的那件事在条上没有格子**,
|
||||||
|
* 条却已经走过去了:那不是走快了一格,是它在说一件没发生的事。
|
||||||
|
*
|
||||||
|
* `T_release` 不在名单里是**对的**:每个活动都以放行收口,那一格由基座统一加
|
||||||
|
* (`CLOSING_PHASE`)—— 活动自己给它起名反而会各叫各的。
|
||||||
|
* 包内自测钉死这条:除放行外每一项恰好属于一个阶段。
|
||||||
|
*/
|
||||||
export const INTAKE_PHASES = [
|
export const INTAKE_PHASES = [
|
||||||
{ name: '定位客户', items: ['S1_customer'] },
|
{ name: '定位客户', items: ['S1_customer'] },
|
||||||
{ name: '归一受理', items: ['S2_normalize'] },
|
{ name: '归一受理', items: ['S2_normalize'] },
|
||||||
|
{ name: '交你审定', items: ['S3_confirm'] },
|
||||||
{ name: '判定去向', items: ['S4_history', 'S5_classify', 'S6_route'] },
|
{ name: '判定去向', items: ['S4_history', 'S5_classify', 'S6_route'] },
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ export const manifest: ActivityManifest = {
|
|||||||
identity: {
|
identity: {
|
||||||
activityId: ACTIVITY_ID,
|
activityId: ACTIVITY_ID,
|
||||||
name: 'A1 · 询价受理',
|
name: 'A1 · 询价受理',
|
||||||
packageVersion: '40.0.0',
|
packageVersion: '41.0.0',
|
||||||
category: '统一报价',
|
category: '统一报价',
|
||||||
sdkVersion: '0.1.0-m5',
|
sdkVersion: '0.1.0-m5',
|
||||||
checksum: 'dev-checksum-quote-intake',
|
checksum: 'dev-checksum-quote-intake',
|
||||||
|
|||||||
@@ -884,6 +884,34 @@ export function registerDeskRoutes(app: Hono<AppEnv>, container: Container): voi
|
|||||||
return c.json(body, 400);
|
return c.json(body, 400);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
/*
|
||||||
|
* **提交闸在服务端也得成立**(2026-08-02)。
|
||||||
|
*
|
||||||
|
* 前端把按钮灰掉是给人看的;而**说明书里向模型承诺了**「卡交回来时必填一定是齐的,
|
||||||
|
* 所以不许再发同一张卡」——那句承诺只有服务端拦得住才算数。
|
||||||
|
* 拦不住的话:一次直调 API 就能把缺必填的卡交回来,模型照承诺不再追问,
|
||||||
|
* 这一单一路走到放行门才被 L1 拦住 —— 而那时缺的是哪一格早已翻篇。
|
||||||
|
* 与卡面那道闸同一段(`submitGate`),同一个数、同一套算法。
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* **闸要在收下回传之前把住**:收下之后再拒,那张单已经记成办结了。
|
||||||
|
* 这一单归哪个任务只有库里知道(回传载荷里只有工单号),所以先问一句。
|
||||||
|
*/
|
||||||
|
const owner = rowsOf<{ task_id: string }>(
|
||||||
|
await container.db.execute(sql`select task_id from sys.work_order where id = ${parsed.data.workOrderId} limit 1`),
|
||||||
|
)[0];
|
||||||
|
if (owner !== undefined) {
|
||||||
|
const held = taskIdSchema.parse(owner.task_id);
|
||||||
|
const order = (await container.humanTool.allWorkOrders(held)).find((o) => o.id === parsed.data.workOrderId);
|
||||||
|
const gate = order === undefined ? undefined : await submitGate(container, held, order);
|
||||||
|
if (gate !== undefined && !gate.ready) {
|
||||||
|
const body: ApiError = {
|
||||||
|
code: 'validation-failed',
|
||||||
|
message: `${gate.why}${gate.blanks.length === 0 ? '' : ` —— ${gate.blanks.slice(0, 5).join(';')}`}`,
|
||||||
|
};
|
||||||
|
return c.json(body, 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
const outcome = await container.humanTool.replyWorkOrder(parsed.data, staff.id);
|
const outcome = await container.humanTool.replyWorkOrder(parsed.data, staff.id);
|
||||||
/*
|
/*
|
||||||
* **绑台账的可编辑表:人改了什么,基座当场写回草稿层**(2026-08-01)。
|
* **绑台账的可编辑表:人改了什么,基座当场写回草稿层**(2026-08-01)。
|
||||||
|
|||||||
Reference in New Issue
Block a user