Archived
feat(desk): 件上保存之后叫醒任务 —— auto 步的配方才有机会按最新草稿铺格
从前只有两条回传路由调 wake;保存不是回传,于是「保存即铺格」永远等不到那一拍。 叫不醒不抬手:保存本身是成功的,不该因为叫不醒把 200 变成 500。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LKMZDwMbyKzjw6Hembwvet
This commit is contained in:
@@ -0,0 +1,40 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import { taskIdSchema } from '@contracts';
|
||||||
|
import { afterSave } from '../save-wake.ts';
|
||||||
|
|
||||||
|
const TASK = taskIdSchema.parse('11111111-1111-4111-8111-111111111111');
|
||||||
|
|
||||||
|
function spy() {
|
||||||
|
const calls: string[] = [];
|
||||||
|
return {
|
||||||
|
calls,
|
||||||
|
deps: {
|
||||||
|
views: { repush: () => { calls.push('repush'); return Promise.resolve(true); } },
|
||||||
|
task: { wake: () => { calls.push('wake'); return Promise.resolve(true); } },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('件上保存之后', () => {
|
||||||
|
it('真落下了行:先重推件,再叫醒任务 —— 配方这才有机会按最新的草稿铺格', async () => {
|
||||||
|
const { calls, deps } = spy();
|
||||||
|
await afterSave(deps, TASK, 3);
|
||||||
|
expect(calls).toEqual(['repush', 'wake']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('一行都没落下:什么也不做 —— 没变的东西不值得叫醒谁', async () => {
|
||||||
|
const { calls, deps } = spy();
|
||||||
|
await afterSave(deps, TASK, 0);
|
||||||
|
expect(calls).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('叫醒失败不抬手:保存本身是成功的,别因为叫不醒把 200 变成 500', async () => {
|
||||||
|
const calls: string[] = [];
|
||||||
|
const deps = {
|
||||||
|
views: { repush: () => { calls.push('repush'); return Promise.resolve(true); } },
|
||||||
|
task: { wake: () => Promise.reject(new Error('库连不上')) },
|
||||||
|
};
|
||||||
|
await expect(afterSave(deps, TASK, 1)).resolves.toBeUndefined();
|
||||||
|
expect(calls).toEqual(['repush']);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -32,6 +32,7 @@ import { assetRowsOf, keyText, listArchived, readArchived } from '../asset-archi
|
|||||||
import { landDataOrder } from '../data-order-landing.ts';
|
import { landDataOrder } from '../data-order-landing.ts';
|
||||||
import { composeFile, isFileFormat, MIME_OF, safeFileName, type FileFormat } from '../file-compose.ts';
|
import { composeFile, isFileFormat, MIME_OF, safeFileName, type FileFormat } from '../file-compose.ts';
|
||||||
import { toFileDoc } from '../file-doc.ts';
|
import { toFileDoc } from '../file-doc.ts';
|
||||||
|
import { afterSave } from '../save-wake.ts';
|
||||||
import { displayLog } from './log-lines.ts';
|
import { displayLog } from './log-lines.ts';
|
||||||
import { pulse } from '../workers/pulse.ts';
|
import { pulse } from '../workers/pulse.ts';
|
||||||
import type { Container } from '../container.ts';
|
import type { Container } from '../container.ts';
|
||||||
@@ -1361,8 +1362,8 @@ export function registerDeskRoutes(app: Hono<AppEnv>, container: Container): voi
|
|||||||
return c.json(body, 409);
|
return c.json(body, 409);
|
||||||
}
|
}
|
||||||
const saved = await applyViewTableEdits(container, taskId, parsed.data);
|
const saved = await applyViewTableEdits(container, taskId, parsed.data);
|
||||||
// 数据变了,件跟着变 —— 算出来的那些(类徽 / 分布条 / 去向)由这一次重渲重新求值
|
// 数据变了,件跟着变;并叫醒任务 —— auto 步的配方这才有机会按最新的草稿铺格
|
||||||
if (saved.rows > 0) await container.views.repush(taskId);
|
await afterSave(container, taskId, saved.rows);
|
||||||
/*
|
/*
|
||||||
* **有行没落下就如实说** —— 保存说成功、东西却不在,是这一屏最伤人的一种谎
|
* **有行没落下就如实说** —— 保存说成功、东西却不在,是这一屏最伤人的一种谎
|
||||||
* (2026-08-24 用户实测:件上加的那个客户推到下一步就不见了)。
|
* (2026-08-24 用户实测:件上加的那个客户推到下一步就不见了)。
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* **件上按了保存之后**(2026-08-29,spec §5.4)。
|
||||||
|
*
|
||||||
|
* 两件事按序:
|
||||||
|
* ① 重推件 —— 数据变了,算出来的那些(红带缺几格 / 分布条 / 去向)得重新求值;
|
||||||
|
* ② **叫醒任务** —— auto 步的配方这才有机会按最新的草稿把该铺的行铺出来。
|
||||||
|
* 人挑了芯片类型、按了保存,参数格就在这一下之后出现。
|
||||||
|
*
|
||||||
|
* 从前只有两条回传路由调 `wake`;保存不是回传,于是「保存即铺格」永远等不到那一拍。
|
||||||
|
* **叫不醒不抬手**:保存本身是成功的,不该因为叫不醒把 200 变成 500 ——
|
||||||
|
* 下一次推进器扫到它照样会跑。
|
||||||
|
*/
|
||||||
|
import type { TaskId } from '@contracts';
|
||||||
|
|
||||||
|
export async function afterSave(
|
||||||
|
deps: {
|
||||||
|
readonly views: { repush(taskId: TaskId): Promise<unknown> };
|
||||||
|
readonly task: { wake(taskId: TaskId): Promise<unknown> };
|
||||||
|
},
|
||||||
|
taskId: TaskId,
|
||||||
|
rows: number,
|
||||||
|
): Promise<void> {
|
||||||
|
if (rows <= 0) return;
|
||||||
|
await deps.views.repush(taskId);
|
||||||
|
await deps.task.wake(taskId).catch(() => false);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user