Archived
基线:鉴权会话+工作组+工作台三区修复+编排工作区+产品设计文档
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
This commit is contained in:
@@ -27,6 +27,7 @@ describe('planConsumption —— 三级消费', () => {
|
||||
listenerHits: [{ taskId: 't1' }],
|
||||
triggerHits: ['tr1'],
|
||||
ownedTaskId: 't1',
|
||||
hasOwner: true,
|
||||
});
|
||||
expect(plan.taskTargets).toEqual(['t1']);
|
||||
expect(plan.triggerTargets).toEqual(['tr1']);
|
||||
@@ -34,24 +35,42 @@ describe('planConsumption —— 三级消费', () => {
|
||||
});
|
||||
|
||||
it('皆未命中且无主 → 消息兜底', () => {
|
||||
const plan = planConsumption({ listenerHits: [], triggerHits: [], ownedTaskId: undefined });
|
||||
const plan = planConsumption({ listenerHits: [], triggerHits: [], ownedTaskId: undefined, hasOwner: false });
|
||||
expect(plan.messageFallback).toBe(true);
|
||||
});
|
||||
|
||||
it('有主但零监听命中 → 仅记录,不兜底、不降级为无主', () => {
|
||||
const plan = planConsumption({ listenerHits: [], triggerHits: [], ownedTaskId: 't7' });
|
||||
const plan = planConsumption({ listenerHits: [], triggerHits: [], ownedTaskId: 't7', hasOwner: true });
|
||||
expect(plan.messageFallback).toBe(false);
|
||||
expect(plan.recordOnlyTask).toBe('t7');
|
||||
expect(plan.taskTargets).toEqual([]);
|
||||
});
|
||||
|
||||
it('主不是任务也算有主 —— 引擎发的工作流事件不得被当成无主件塞进收件箱', () => {
|
||||
// 起单 / 解析负责人 / 起任务这些事件的 target 是 workflow,不是 task。
|
||||
// 只认 ownedTaskId 的话,每起一单都会给人推一条「无主入站待认领」。
|
||||
const plan = planConsumption({
|
||||
listenerHits: [],
|
||||
triggerHits: [],
|
||||
ownedTaskId: undefined,
|
||||
hasOwner: true,
|
||||
});
|
||||
expect(plan.messageFallback).toBe(false);
|
||||
expect(plan.recordOnlyTask).toBeUndefined();
|
||||
});
|
||||
|
||||
it('有主且监听命中 → 不是仅记录', () => {
|
||||
const plan = planConsumption({ listenerHits: [{ taskId: 't7' }], triggerHits: [], ownedTaskId: 't7' });
|
||||
const plan = planConsumption({
|
||||
listenerHits: [{ taskId: 't7' }],
|
||||
triggerHits: [],
|
||||
ownedTaskId: 't7',
|
||||
hasOwner: true,
|
||||
});
|
||||
expect(plan.recordOnlyTask).toBeUndefined();
|
||||
});
|
||||
|
||||
it('无主但触发命中 → 不兜底', () => {
|
||||
const plan = planConsumption({ listenerHits: [], triggerHits: ['tr1'], ownedTaskId: undefined });
|
||||
const plan = planConsumption({ listenerHits: [], triggerHits: ['tr1'], ownedTaskId: undefined, hasOwner: false });
|
||||
expect(plan.messageFallback).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -58,6 +58,14 @@ export function planConsumption(input: {
|
||||
readonly listenerHits: ReadonlyArray<{ taskId: string }>;
|
||||
readonly triggerHits: readonly string[];
|
||||
readonly ownedTaskId: string | undefined;
|
||||
/**
|
||||
* 信封是否**有主** —— 关联里指了目标就算有主,不限于任务。
|
||||
*
|
||||
* 不能拿「有没有 ownedTaskId」当有主:引擎自己发的工作流事件
|
||||
* (`target: { kind: 'workflow' }`)照样是有主的,只是主不是任务。
|
||||
* 把它们判成无主,等于把每次起单都当成「没人认领的入站件」塞进别人收件箱。
|
||||
*/
|
||||
readonly hasOwner: boolean;
|
||||
}): ConsumptionPlan {
|
||||
const taskTargets = fanOutTargets(input.listenerHits);
|
||||
const triggerTargets = [...new Set(input.triggerHits)];
|
||||
@@ -65,8 +73,8 @@ export function planConsumption(input: {
|
||||
return {
|
||||
taskTargets,
|
||||
triggerTargets,
|
||||
// 有主但零监听命中 → 仅记录,不兜底
|
||||
messageFallback: nothingHit && input.ownedTaskId === undefined,
|
||||
// 有主但零监听命中 → 仅记录,不兜底;消息只兜**真正无主**的件(OS 6.3)
|
||||
messageFallback: nothingHit && !input.hasOwner,
|
||||
recordOnlyTask:
|
||||
input.ownedTaskId !== undefined && !taskTargets.includes(input.ownedTaskId)
|
||||
? input.ownedTaskId
|
||||
|
||||
@@ -46,7 +46,12 @@ export function createEventService(deps: EventServiceDeps): EventService {
|
||||
const ownedTaskId =
|
||||
envelope.correlation.target?.kind === 'task' ? String(envelope.correlation.target.id) : undefined;
|
||||
|
||||
const plan = planConsumption({ listenerHits: hits, triggerHits, ownedTaskId });
|
||||
const plan = planConsumption({
|
||||
listenerHits: hits,
|
||||
triggerHits,
|
||||
ownedTaskId,
|
||||
hasOwner: envelope.correlation.target !== undefined,
|
||||
});
|
||||
|
||||
// 扇出:每个命中目标一份独立投递,信封「关联 = 单目标」保持单目标
|
||||
const deliveries: Delivery[] = [
|
||||
|
||||
Reference in New Issue
Block a user