@yss123/cage-approval 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +77 -9
  2. package/dist/ai.d.ts +55 -0
  3. package/dist/ai.js +51 -0
  4. package/dist/ai.js.map +1 -0
  5. package/dist/bridge.d.ts +7 -1
  6. package/dist/bridge.js +29 -8
  7. package/dist/bridge.js.map +1 -1
  8. package/dist/deadlines.d.ts +29 -0
  9. package/dist/deadlines.js +72 -0
  10. package/dist/deadlines.js.map +1 -0
  11. package/dist/engine.d.ts +138 -4
  12. package/dist/engine.js +306 -99
  13. package/dist/engine.js.map +1 -1
  14. package/dist/execution.d.ts +41 -0
  15. package/dist/execution.js +85 -0
  16. package/dist/execution.js.map +1 -0
  17. package/dist/http.d.ts +6 -0
  18. package/dist/http.js +83 -12
  19. package/dist/http.js.map +1 -1
  20. package/dist/index.d.ts +11 -1
  21. package/dist/index.js +9 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/openapi.d.ts +17 -0
  24. package/dist/openapi.js +71 -0
  25. package/dist/openapi.js.map +1 -0
  26. package/dist/operations-schema.d.ts +20 -0
  27. package/dist/operations-schema.js +20 -0
  28. package/dist/operations-schema.js.map +1 -0
  29. package/dist/operations.d.ts +118 -0
  30. package/dist/operations.js +349 -0
  31. package/dist/operations.js.map +1 -0
  32. package/dist/route.d.ts +85 -7
  33. package/dist/route.js +100 -23
  34. package/dist/route.js.map +1 -1
  35. package/dist/selectors.d.ts +8 -0
  36. package/dist/selectors.js +53 -0
  37. package/dist/selectors.js.map +1 -0
  38. package/dist/task-actions.d.ts +94 -0
  39. package/dist/task-actions.js +198 -0
  40. package/dist/task-actions.js.map +1 -0
  41. package/dist/task-stages.d.ts +17 -0
  42. package/dist/task-stages.js +47 -0
  43. package/dist/task-stages.js.map +1 -0
  44. package/dist/types.d.ts +6 -2
  45. package/package.json +2 -2
package/dist/route.js CHANGED
@@ -1,7 +1,16 @@
1
- // 代码内封闭路由:一小组固定的组合子(step、when、gt、approver.*),和范围组合子一样只能从里面选,
2
- // 所以抽取器能读懂:改 amount 的口径时,影响分析会把这条路由列出来。
3
- import { ROUTE, SYSTEM_DDL, declError } from '@yss123/cage-kernel';
1
+ /**
2
+ * 代码内封闭审批声明:组合子保存条件、选人、分配与任务政策,由注册表/CLI 抽取、引擎创建实例。
3
+ * 字段选人与条件进入 fieldsUsed 依赖;运行实例保存步骤快照,后来改代码不会改写在途规则。
4
+ * 这里不授予业务权限或执行任意脚本;新结构只追加迁移,历史 FLOW_DDL 内容保持不变。
5
+ */
6
+ import { ROUTE, SYSTEM_DDL, MIGRATIONS, declError, stableStringify } from '@yss123/cage-kernel';
7
+ import { createHash } from 'node:crypto';
8
+ import { compileSteps, inspectRoute } from './execution.js';
4
9
  import { InCodeEngine } from './engine.js';
10
+ import { APPROVAL_AI_MIGRATION } from './ai.js';
11
+ import { APPROVAL_TASK_ACTIONS_MIGRATION } from './task-actions.js';
12
+ import { APPROVAL_TASK_STAGES_MIGRATION } from './task-stages.js';
13
+ import { APPROVAL_DEADLINES_MIGRATION, approvalSla, approvalReminderPolicy } from './deadlines.js';
5
14
  /** 审批人组合子 */
6
15
  export const approver = {
7
16
  /** 单据某个部门字段对应部门的负责人 */
@@ -10,7 +19,10 @@ export const approver = {
10
19
  role: (code) => ({ kind: 'role', code }),
11
20
  /** 指定用户 */
12
21
  user: (userId) => ({ kind: 'user', userId }),
22
+ /** 从 routable 单据字段读取 UUID 或 UUID 数组;值随实例冻结,仍须业务授权,不接受任意 JS。 */
23
+ field: (field) => ({ kind: 'field', field }),
13
24
  };
25
+ /** 数值比较组合子将业务字段和阈值保留在声明中,金额字符串在 evalCondition 中转换比较。 */
14
26
  export const gt = (field, value) => ({ op: 'gt', field, value });
15
27
  export const gte = (field, value) => ({ op: 'gte', field, value });
16
28
  export const lt = (field, value) => ({ op: 'lt', field, value });
@@ -18,12 +30,33 @@ export const lte = (field, value) => ({ op: 'lte', field, value });
18
30
  export const eq = (field, value) => ({ op: 'eq', field, value });
19
31
  export const ne = (field, value) => ({ op: 'ne', field, value });
20
32
  export const isIn = (field, value) => ({ op: 'in', field, value });
33
+ /** 创建具名分支,内部可顺序执行多步;只保存声明,结构预算在 route 构建时统一验证。 */
34
+ export function branch(title, ...nodes) { return { kind: 'branch', title, nodes }; }
35
+ /** 声明 AND 分支与汇合;一条分支拒绝/退回时结束整轮,全部通过才继续,选人不授予权限。 */
36
+ export function parallel(title, ...branches) { return { kind: 'parallel', title, branches }; }
21
37
  export function step(title, who, opts = {}) {
22
- return { kind: 'step', title, approver: who, mode: opts.mode ?? 'any' };
38
+ if (who.kind === 'ai') {
39
+ if (!who.model?.trim() || !who.instructions?.trim() || !who.handoff || !who.context?.fields.length)
40
+ throw declError('CAGE-APPR-006', 'AI 步骤需要模型、审核要求、上下文字段和接管规则');
41
+ for (const value of Object.values(who.limits ?? {}))
42
+ if (!Number.isSafeInteger(value) || value <= 0)
43
+ throw declError('CAGE-APPR-006', 'AI 步骤运行预算必须是正整数');
44
+ return Object.freeze({ ...who, title, context: { fields: [...who.context.fields], queries: [...(who.context.queries ?? [])] } });
45
+ }
46
+ if (opts.actions && Object.entries(opts.actions).some(([name, value]) => !['transfer', 'delegate', 'addSign'].includes(name) || typeof value !== 'boolean'))
47
+ throw declError('CAGE-APPR-006', '人工步骤的 actions 只接受 transfer/delegate/addSign 布尔值');
48
+ if ((opts.assignment !== undefined && !['direct', 'candidate'].includes(opts.assignment)) || (opts.assignment === 'candidate' && opts.mode === 'all'))
49
+ throw declError('CAGE-APPR-006', '候选领取只支持 any;逐人会签请使用默认 direct');
50
+ return { kind: 'step', title, approver: who, mode: opts.mode ?? 'any', ...(opts.assignment ? { assignment: opts.assignment } : {}),
51
+ ...(opts.sla ? { sla: approvalSla(opts.sla) } : {}),
52
+ ...(opts.actions?.addSign ? { signPositions: Object.freeze(['parallel', 'before', 'after']) } : {}),
53
+ ...(opts.actions ? { actions: Object.freeze({ ...opts.actions }) } : {}) };
23
54
  }
55
+ /** 将一组顺序步骤置于同一个条件下,条件求值发生在实例创建时。 */
24
56
  export function when(cond, ...steps) {
25
57
  return { kind: 'when', cond, steps };
26
58
  }
59
+ /** 使用封闭运算符求值,不执行任意表达式;比较转换规则固定,业务阈值边界应另有回归用例。 */
27
60
  export function evalCondition(c, vars) {
28
61
  const v = vars[c.field];
29
62
  switch (c.op) {
@@ -37,36 +70,46 @@ export function evalCondition(c, vars) {
37
70
  default: return false;
38
71
  }
39
72
  }
40
- /** 按流程变量展开出实际要走的步骤 */
73
+ /** 按提交变量展开节点并携带冻结的依赖;返回顺序是节点索引顺序,实际执行以 execution.dependsOn 为准。 */
41
74
  export function resolveSteps(nodes, vars) {
42
- const out = [];
43
- for (const n of nodes) {
44
- if (n.kind === 'step')
45
- out.push(n);
46
- else if (evalCondition(n.cond, vars))
47
- out.push(...n.steps);
48
- }
49
- return out;
75
+ inspectRoute(nodes);
76
+ return compileSteps(nodes, vars, createHash('sha256').update(stableStringify(nodes)).digest('hex'));
50
77
  }
51
78
  const engines = new WeakMap();
52
- export function route(process, nodes) {
79
+ /**
80
+ * 构造流程声明并收集条件/部门选人字段,用于图谱依赖检查;按 kernel 与 process 缓存引擎实例。
81
+ * 注册表完成后 validate 继续核对 AI 运行时、自动角色、退回命令和取证字段/查询,尽早暴露缺失声明。
82
+ * nodes 保存原有步骤顺序,业务实例创建时会冻结展开后的步骤,后续不会随代码分支重新求值。
83
+ */
84
+ export function route(process, nodes, options = {}) {
53
85
  if (!/^[a-z][a-z0-9-]*$/.test(process))
54
86
  throw declError('CAGE-APPR-005', `流程名 ${process} 必须是小写短横线`);
55
87
  if (nodes.length === 0)
56
88
  throw declError('CAGE-APPR-006', `流程 ${process} 至少需要一个步骤`);
57
- const fields = new Set();
58
- for (const n of nodes) {
59
- const steps = n.kind === 'step' ? [n] : n.steps;
60
- if (n.kind === 'when')
61
- fields.add(n.cond.field);
62
- for (const s of steps)
63
- if (s.approver.kind === 'deptLeader')
64
- fields.add(s.approver.field);
89
+ const inspection = inspectRoute(nodes);
90
+ const fields = new Set(inspection.fields);
91
+ const reminders = options.reminders === undefined ? undefined : approvalReminderPolicy(options.reminders);
92
+ if (reminders)
93
+ fields.add(reminders.requesterField);
94
+ for (const s of inspection.steps) {
95
+ const selector = s.kind === 'ai' ? s.handoff : s.approver;
96
+ if (selector.kind === 'deptLeader' || selector.kind === 'field')
97
+ fields.add(selector.field);
65
98
  }
99
+ // 声明必须与指纹同时冻结;拷贝调用者的对象,避免其后修改数组让注册表与实例版本不一致。
100
+ const frozenNodes = JSON.parse(JSON.stringify(nodes));
101
+ const freeze = (value) => { if (value && typeof value === 'object') {
102
+ Object.values(value).forEach(freeze);
103
+ Object.freeze(value);
104
+ } };
105
+ freeze(frozenNodes);
106
+ const definitionVersion = createHash('sha256').update(stableStringify({ schema: 1, process, nodes: frozenNodes, reminders })).digest('hex');
66
107
  const r = Object.freeze({
67
108
  [ROUTE]: true,
68
109
  process,
69
- nodes: Object.freeze([...nodes]),
110
+ nodes: frozenNodes,
111
+ definitionVersion,
112
+ ...(reminders ? { reminders } : {}),
70
113
  fieldsUsed: Object.freeze([...fields]),
71
114
  engine: (k) => {
72
115
  let m = engines.get(k);
@@ -78,10 +121,44 @@ export function route(process, nodes) {
78
121
  return e;
79
122
  },
80
123
  [SYSTEM_DDL]: () => FLOW_DDL,
124
+ [MIGRATIONS]: () => [APPROVAL_AI_MIGRATION, APPROVAL_TASK_ACTIONS_MIGRATION, APPROVAL_TASK_STAGES_MIGRATION, APPROVAL_DEADLINES_MIGRATION],
125
+ validate: (registry) => {
126
+ const routeBinding = registry.approvalByProcess(process)?.a;
127
+ // 时限和申请人催办都依赖独立后台运行时,声明遗漏必须在构建阶段报错,不能部署后悄悄无提醒。
128
+ const declaredSteps = inspectRoute(frozenNodes).steps;
129
+ const hasSla = declaredSteps.some(node => node.kind !== 'ai' && node.sla);
130
+ if ((reminders || hasSla) && !registry.extensions.some(ext => ext.kind === 'RUNTIME' && ext.value.name === 'approval-operations'))
131
+ throw declError('CAGE-APPR-006', '审批 SLA 或 reminders 必须显式导出 approvalOperations()');
132
+ if (reminders && (!routeBinding?.routable.includes(reminders.requesterField) || !routeBinding.agg.fields[reminders.requesterField] || routeBinding.agg.fields[reminders.requesterField].isHidden))
133
+ throw declError('CAGE-APPR-001', `申请人字段 ${reminders.requesterField} 必须存在、可公开且进入 routable`);
134
+ for (const node of declaredSteps) {
135
+ const selector = node.kind === 'ai' ? node.handoff : node.approver;
136
+ // 新字段选择器必须能从 routable 快照取值;不追溯改变历史部门选人的声明校验行为。
137
+ if (selector.kind === 'field' && (!routeBinding?.routable.includes(selector.field) || !routeBinding.agg.fields[selector.field] || routeBinding.agg.fields[selector.field].isHidden))
138
+ throw declError('CAGE-APPR-001', `审批人员字段 ${selector.field} 必须存在、可公开且进入 routable`);
139
+ }
140
+ const aiSteps = declaredSteps.filter((s) => s.kind === 'ai');
141
+ if (!aiSteps.length)
142
+ return;
143
+ if (!registry.extensions.some(e => e.kind === 'RUNTIME' && e.value.name === 'ai'))
144
+ throw declError('CAGE-APPR-006', 'AI 审批必须启用 cage-ai 运行时');
145
+ const binding = registry.approvalByProcess(process)?.a;
146
+ if (!binding?.onReturned || !binding.automatedBy)
147
+ throw declError('CAGE-APPR-006', `AI 审批 ${process} 必须绑定 onReturned 和 automatedBy`);
148
+ for (const s of aiSteps) {
149
+ for (const field of s.context.fields)
150
+ if (!binding.agg.fields[field] || binding.agg.fields[field].isHidden)
151
+ throw declError('CAGE-APPR-001', `AI 上下文字段 ${field} 不存在或不可公开`);
152
+ for (const query of s.context.queries ?? [])
153
+ if (!registry.queries.some(q => q.name === query))
154
+ throw declError('CAGE-REG-001', `AI 步骤引用的查询 ${query} 未导出`);
155
+ }
156
+ },
81
157
  });
82
158
  return r;
83
159
  }
84
160
  /** 代码内引擎自己的表,放在 flow 模式;引擎没有业务表的写权限 */
161
+ /** 此 SQL 是已发布扩展 DDL 的内容摘要来源;新增字段通过独立 MIGRATIONS 追加,不能改写历史字符串。 */
85
162
  export const FLOW_DDL = `
86
163
  CREATE TABLE IF NOT EXISTS flow.approval_instance (
87
164
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
package/dist/route.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","sourceRoot":"","sources":["../src/route.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../src/route.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { type Kysely } from 'kysely';
2
+ import type { Approver } from './route.js';
3
+ /**
4
+ * 解析单人、角色、部门负责人或单据人员字段;支持普通连接及已持锁事务,避免再次占用写连接池。
5
+ * 字段值允许单个 UUID 或 1–200 个 UUID,重复人员归并;null/缺失返回空,非法类型明确拒绝。
6
+ * 空候选由开启节点时报告配置错误;列表/领取时代表当前无人符合,不扩大候选范围。
7
+ */
8
+ export declare function resolveApprovers(db: Kysely<any>, selector: Approver, vars: Record<string, unknown>, tenantId: string): Promise<string[]>;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * 封闭审批选人规则的数据库解析,由节点开启与候选任务查询/领取共同调用。
3
+ * 组织规则每次按当前租户数据解析,字段规则只读取实例保存的 routable 变量;本文件不授予能力,也不写任务。
4
+ * 领取仍需另查 active、业务批准能力和安全视图范围,选人成功不能替代最终领域命令约束。
5
+ */
6
+ import { cageError } from '@yss123/cage-kernel';
7
+ import { sql } from 'kysely';
8
+ import { z } from 'zod';
9
+ /**
10
+ * 解析单人、角色、部门负责人或单据人员字段;支持普通连接及已持锁事务,避免再次占用写连接池。
11
+ * 字段值允许单个 UUID 或 1–200 个 UUID,重复人员归并;null/缺失返回空,非法类型明确拒绝。
12
+ * 空候选由开启节点时报告配置错误;列表/领取时代表当前无人符合,不扩大候选范围。
13
+ */
14
+ export async function resolveApprovers(db, selector, vars, tenantId) {
15
+ switch (selector.kind) {
16
+ case 'user': return [selector.userId];
17
+ case 'field': {
18
+ const value = vars[selector.field];
19
+ if (value == null)
20
+ return [];
21
+ const parsed = z.array(z.uuid()).min(1).max(200).safeParse(typeof value === 'string' ? [value] : value);
22
+ if (!parsed.success)
23
+ throw cageError('INVALID_INPUT', { reason: '审批人员字段须为 UUID 或 1–200 个 UUID 的数组' });
24
+ return [...new Set(parsed.data)];
25
+ }
26
+ case 'deptLeader': {
27
+ const deptId = vars[selector.field];
28
+ if (typeof deptId !== 'string')
29
+ return [];
30
+ const dept = await db.selectFrom('sys.dept').select(['leader_id', 'ancestors']).where('id', '=', deptId).where('tenant_id', '=', tenantId).executeTakeFirst();
31
+ if (!dept)
32
+ return [];
33
+ if (dept.leader_id)
34
+ return [dept.leader_id];
35
+ // 无直属负责人时从最近祖先开始查找,每次查询仍限同一租户。
36
+ for (const id of String(dept.ancestors).split('/').filter(Boolean).reverse()) {
37
+ const parent = await db.selectFrom('sys.dept').select('leader_id').where('id', '=', id).where('tenant_id', '=', tenantId).executeTakeFirst();
38
+ if (parent?.leader_id)
39
+ return [parent.leader_id];
40
+ }
41
+ return [];
42
+ }
43
+ case 'role': {
44
+ const role = await db.selectFrom('sys.role').select('id').where('code', '=', selector.code).where('tenant_id', '=', tenantId).where('status', '=', 'active').executeTakeFirst();
45
+ if (!role)
46
+ return [];
47
+ const users = await db.selectFrom('sys.user').select('id').where('tenant_id', '=', tenantId).where('status', '=', 'active')
48
+ .where(sql `role_ids @> ${JSON.stringify([role.id])}::jsonb`).execute();
49
+ return users.map(user => user.id);
50
+ }
51
+ }
52
+ }
53
+ //# sourceMappingURL=selectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectors.js","sourceRoot":"","sources":["../src/selectors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * 人工待办的领取/释放、转办、委派归还与前后/并行加签,由 InCodeEngine 和 HTTP 调用。
3
+ * 操作先锁实例再锁任务,重新核验归属、提交版本、权限与节点快照政策;任务修改和不可覆盖的操作记录共同提交。
4
+ * 本模块只维护 flow 数据,不执行最终业务结论;委派不等于批准,加签不创建新的审批节点或授予能力。
5
+ */
6
+ import { type Kernel, type Ctx } from '@yss123/cage-kernel';
7
+ import { type Transaction } from 'kysely';
8
+ import { z } from 'zod';
9
+ /** 人工节点显式开放的任务操作;缺省均关闭,已运行实例使用保存的政策而非最新代码。 */
10
+ export interface TaskActionPolicy {
11
+ /** 允许当前审批人将责任转给另一位已有审批权限的用户。 */
12
+ transfer?: boolean;
13
+ /** 允许委派处理后归还原审批人;受托人不能直接作出审批结论。 */
14
+ delegate?: boolean;
15
+ /** 允许原始待办添加当前节点的前签、后签或并行必签人;加签待办本身不能继续加签。 */
16
+ addSign?: boolean;
17
+ }
18
+ /** HTTP 与直接引擎调用共用的严格输入协议,拒绝未知字段;revision 是任务版本,不是业务对象版本。 */
19
+ export declare const taskActionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
20
+ targetUserId: z.ZodUUID;
21
+ expectedRevision: z.ZodNumber;
22
+ reason: z.ZodString;
23
+ action: z.ZodLiteral<"transfer">;
24
+ }, z.core.$strict>, z.ZodObject<{
25
+ targetUserId: z.ZodUUID;
26
+ expectedRevision: z.ZodNumber;
27
+ reason: z.ZodString;
28
+ action: z.ZodLiteral<"delegate">;
29
+ }, z.core.$strict>, z.ZodObject<{
30
+ expectedRevision: z.ZodNumber;
31
+ reason: z.ZodString;
32
+ action: z.ZodLiteral<"resolve">;
33
+ }, z.core.$strict>, z.ZodObject<{
34
+ expectedRevision: z.ZodNumber;
35
+ reason: z.ZodString;
36
+ action: z.ZodLiteral<"claim">;
37
+ }, z.core.$strict>, z.ZodObject<{
38
+ expectedRevision: z.ZodNumber;
39
+ reason: z.ZodString;
40
+ action: z.ZodLiteral<"unclaim">;
41
+ }, z.core.$strict>, z.ZodObject<{
42
+ userIds: z.ZodArray<z.ZodUUID>;
43
+ placement: z.ZodOptional<z.ZodEnum<{
44
+ parallel: "parallel";
45
+ before: "before";
46
+ after: "after";
47
+ }>>;
48
+ expectedRevision: z.ZodNumber;
49
+ reason: z.ZodString;
50
+ action: z.ZodLiteral<"addSign">;
51
+ }, z.core.$strict>], "action">;
52
+ /** action 区分领取/释放、转办、委派、归还和加签;placement 缺省并行,reason 必须说明原因,目标 ID 不授予权限。 */
53
+ export type TaskActionInput = z.infer<typeof taskActionSchema>;
54
+ /** 已提交的任务变更回执;新加签待办各从 revision=0 开始,原任务版本始终递增。 */
55
+ export interface TaskActionResult {
56
+ /** 被操作的原任务 ID。 */
57
+ taskId: string;
58
+ /** 变更后的原任务版本,重复提交旧版本会返回冲突而不会再次变更。 */
59
+ revision: number;
60
+ /** 本次加签新建的待办 ID,其他操作为空数组。 */
61
+ createdTaskIds: string[];
62
+ }
63
+ /**
64
+ * 按租户与当前受托人找到任务,再以实例→任务的固定顺序加锁。
65
+ * 锁后再次核对归属与当前步骤,防止转办和决定竞争时使用锁前的旧身份;找不到或不归本人统一 404。
66
+ * unassigned 仅供领取使用,只接受无人持有的 candidate;候选身份由调用方在同一锁内另查。
67
+ */
68
+ export declare function lockOwnedTask(k: Kernel, tx: Transaction<any>, process: string, taskId: string, userId: string, tenantId: string, unassigned?: boolean): Promise<{
69
+ inst: {
70
+ [x: string]: any;
71
+ };
72
+ task: {
73
+ [x: string]: any;
74
+ };
75
+ binding: import("@yss123/cage-kernel").Approval<import("@yss123/cage-kernel").AnyAggregate>;
76
+ }>;
77
+ /** 选人和决定都实时检查 active 用户、指定结论能力及单据 read/范围;此检查不替代最终命令中的硬约束。 */
78
+ export declare function authorizedTaskActor(k: Kernel, tx: Transaction<any>, inst: any, userId: string, outcome?: 'approved' | 'rejected' | 'returned'): Promise<Ctx>;
79
+ /**
80
+ * 仅追加审批动作,不覆盖原决定 comment;调用方的事务失败会连同记录一起回滚。
81
+ * 表对应用账号只开放 SELECT/INSERT;reason 是人工意见,调用人不得在其中放凭据或无权共享的内容。
82
+ */
83
+ export declare function recordTaskAction(tx: Transaction<any>, inst: any, taskId: string | null, actorId: string | null, action: string, reason: string | null, details?: Record<string, unknown>): Promise<void>;
84
+ /**
85
+ * 执行一个任务管理动作;领取/释放由 assignment 声明开放,其余由 actions 开放,AI 接管待办保持原有语义。
86
+ * 目标不得是本人、原委派人或该节点已承担/已完成审批的人,防止会签转办变相减少独立审批人数。
87
+ * 同节点最多追加 20 位必签人;重复网络提交凭旧 revision 拒绝,不提供成功回执缓存或自动重试。
88
+ */
89
+ export declare function executeTaskAction(k: Kernel, process: string, taskId: string, userId: string, tenantId: string, input: TaskActionInput): Promise<TaskActionResult>;
90
+ /** 前向迁移:旧待办保持 original/revision=0,既有实例无 actions 因而不会自动开放管理操作。 */
91
+ export declare const APPROVAL_TASK_ACTIONS_MIGRATION: {
92
+ name: string;
93
+ sql: string;
94
+ };
@@ -0,0 +1,198 @@
1
+ /**
2
+ * 人工待办的领取/释放、转办、委派归还与前后/并行加签,由 InCodeEngine 和 HTTP 调用。
3
+ * 操作先锁实例再锁任务,重新核验归属、提交版本、权限与节点快照政策;任务修改和不可覆盖的操作记录共同提交。
4
+ * 本模块只维护 flow 数据,不执行最终业务结论;委派不等于批准,加签不创建新的审批节点或授予能力。
5
+ */
6
+ import { cageError, loadUserGrants, userCtx } from '@yss123/cage-kernel';
7
+ import { sql } from 'kysely';
8
+ import { z } from 'zod';
9
+ import { resolveApprovers } from './selectors.js';
10
+ const common = { expectedRevision: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER), reason: z.string().trim().min(1).max(1000) };
11
+ /** HTTP 与直接引擎调用共用的严格输入协议,拒绝未知字段;revision 是任务版本,不是业务对象版本。 */
12
+ export const taskActionSchema = z.discriminatedUnion('action', [
13
+ z.strictObject({ action: z.literal('transfer'), ...common, targetUserId: z.uuid() }),
14
+ z.strictObject({ action: z.literal('delegate'), ...common, targetUserId: z.uuid() }),
15
+ z.strictObject({ action: z.literal('resolve'), ...common }),
16
+ z.strictObject({ action: z.literal('claim'), ...common }),
17
+ z.strictObject({ action: z.literal('unclaim'), ...common }),
18
+ z.strictObject({ action: z.literal('addSign'), ...common, userIds: z.array(z.uuid()).min(1).max(20), placement: z.enum(['parallel', 'before', 'after']).optional() }),
19
+ ]);
20
+ /**
21
+ * 按租户与当前受托人找到任务,再以实例→任务的固定顺序加锁。
22
+ * 锁后再次核对归属与当前步骤,防止转办和决定竞争时使用锁前的旧身份;找不到或不归本人统一 404。
23
+ * unassigned 仅供领取使用,只接受无人持有的 candidate;候选身份由调用方在同一锁内另查。
24
+ */
25
+ export async function lockOwnedTask(k, tx, process, taskId, userId, tenantId, unassigned = false) {
26
+ if (!z.uuid().safeParse(taskId).success)
27
+ throw cageError('NOT_FOUND');
28
+ const candidate = await tx.selectFrom('flow.approval_task').select('instance_id')
29
+ .where('id', '=', taskId).where('tenant_id', '=', tenantId)
30
+ .$if(!unassigned, query => query.where('assignee', '=', userId))
31
+ .$if(unassigned, query => query.where('assignment', '=', 'candidate').where('assignee', 'is', null)).executeTakeFirst();
32
+ if (!candidate)
33
+ throw cageError('NOT_FOUND');
34
+ const inst = await tx.selectFrom('flow.approval_instance').selectAll().where('id', '=', candidate.instance_id)
35
+ .where('tenant_id', '=', tenantId).where('process', '=', process).forUpdate().executeTakeFirst();
36
+ if (!inst)
37
+ throw cageError('NOT_FOUND');
38
+ const task = await tx.selectFrom('flow.approval_task').selectAll().where('id', '=', taskId).where('tenant_id', '=', tenantId).forUpdate().executeTakeFirst();
39
+ if (!task || (unassigned ? task.assignment !== 'candidate' || task.assignee !== null : task.assignee !== userId))
40
+ throw cageError('NOT_FOUND');
41
+ // 并行分支各自拥有活跃节点,不能用实例兼容摘要 current_step 排除其他分支的合法待办。
42
+ const activeStep = await tx.selectFrom('flow.approval_step').select('status').where('instance_id', '=', inst.id).where('step', '=', task.step).executeTakeFirst();
43
+ if (inst.status !== 'running' || task.status !== 'pending' || !activeStep || !['running', 'waiting_manual'].includes(activeStep.status))
44
+ throw cageError('INVALID_TRANSITION');
45
+ const binding = k.registry.approvalByProcess(process).a;
46
+ const subject = await tx.selectFrom(`${binding.agg.table.schema}.${binding.agg.table.name}`).select('version')
47
+ .where('id', '=', inst.business_key).where('tenant_id', '=', tenantId).executeTakeFirst();
48
+ if (!subject || (inst.subject_version !== null && subject.version !== inst.subject_version))
49
+ throw cageError('CONFLICT', { reason: '审批所针对的业务版本已变化' });
50
+ return { inst, task, binding };
51
+ }
52
+ /** 选人和决定都实时检查 active 用户、指定结论能力及单据 read/范围;此检查不替代最终命令中的硬约束。 */
53
+ export async function authorizedTaskActor(k, tx, inst, userId, outcome = 'approved') {
54
+ const binding = k.registry.approvalByProcess(inst.process).a;
55
+ const command = outcome === 'approved' ? binding.onApproved : outcome === 'rejected' ? binding.onRejected : binding.onReturned;
56
+ // 复用持有实例锁的连接加载授权;若另从 app 池取连接,排队操作占满池时会阻塞锁持有者。
57
+ const grants = await loadUserGrants(tx, userId, inst.tenant_id);
58
+ const actor = grants ? userCtx(grants) : null;
59
+ if (!actor || !command || !actor.capabilities.has(k.registry.capabilityOf(command)) || !actor.capabilities.has(`${binding.agg.name}.read`))
60
+ throw cageError('FORBIDDEN');
61
+ // 只查安全视图中的存在性,不读取明文字段或制造不必要的明文读取审计;范围仍由读账号落实。
62
+ const visible = await k.read.tx(actor, read => read.selectFrom(`safe.${binding.agg.table.name}`).select('id').where('id', '=', inst.business_key).executeTakeFirst());
63
+ if (!visible)
64
+ throw cageError('NOT_FOUND');
65
+ return actor;
66
+ }
67
+ /**
68
+ * 仅追加审批动作,不覆盖原决定 comment;调用方的事务失败会连同记录一起回滚。
69
+ * 表对应用账号只开放 SELECT/INSERT;reason 是人工意见,调用人不得在其中放凭据或无权共享的内容。
70
+ */
71
+ export async function recordTaskAction(tx, inst, taskId, actorId, action, reason, details = {}) {
72
+ await tx.insertInto('flow.approval_task_action').values({ tenant_id: inst.tenant_id, instance_id: inst.id,
73
+ task_id: taskId, actor_id: actorId, action, reason, details: JSON.stringify(details) }).execute();
74
+ }
75
+ /**
76
+ * 执行一个任务管理动作;领取/释放由 assignment 声明开放,其余由 actions 开放,AI 接管待办保持原有语义。
77
+ * 目标不得是本人、原委派人或该节点已承担/已完成审批的人,防止会签转办变相减少独立审批人数。
78
+ * 同节点最多追加 20 位必签人;重复网络提交凭旧 revision 拒绝,不提供成功回执缓存或自动重试。
79
+ */
80
+ export async function executeTaskAction(k, process, taskId, userId, tenantId, input) {
81
+ const parsed = taskActionSchema.safeParse(input);
82
+ if (!parsed.success)
83
+ throw cageError('INVALID_INPUT');
84
+ const data = parsed.data;
85
+ return k.app.transaction().execute(async (tx) => {
86
+ const { inst, task } = await lockOwnedTask(k, tx, process, taskId, userId, tenantId, data.action === 'claim');
87
+ if (task.revision !== data.expectedRevision)
88
+ throw cageError('CONFLICT');
89
+ await authorizedTaskActor(k, tx, inst, userId);
90
+ const node = inst.steps[task.step];
91
+ if (data.action === 'claim' || data.action === 'unclaim') {
92
+ if (node.kind === 'ai' || node.assignment !== 'candidate' || task.assignment !== 'candidate')
93
+ throw cageError('FORBIDDEN');
94
+ if (task.delegation === 'pending')
95
+ throw cageError('INVALID_TRANSITION');
96
+ if (data.action === 'claim') {
97
+ if (!(await resolveApprovers(tx, node.approver, inst.vars, tenantId)).includes(userId))
98
+ throw cageError('FORBIDDEN');
99
+ // 候选身份不允许一人领取同节点第二票;已完成票和委派 owner 也算已承担责任。
100
+ const peer = await tx.selectFrom('flow.approval_task').select('id').where('instance_id', '=', inst.id).where('step', '=', task.step)
101
+ .where('id', '!=', task.id).where(q => q.or([q('assignee', '=', userId), q('owner_id', '=', userId)])).executeTakeFirst();
102
+ if (peer)
103
+ throw cageError('CONFLICT', { reason: '领取人已参与当前节点' });
104
+ }
105
+ else {
106
+ // 不能用释放候选任务绕过已提出的必签责任;完成后可释放,父子关联仍保留。
107
+ const child = await tx.selectFrom('flow.approval_task').select('id').where('parent_task_id', '=', task.id)
108
+ .where('status', 'in', ['pending', 'waiting']).executeTakeFirst();
109
+ if (child)
110
+ throw cageError('INVALID_TRANSITION', { reason: '存在未完成加签,不能释放任务' });
111
+ }
112
+ const assignee = data.action === 'claim' ? userId : null;
113
+ await tx.updateTable('flow.approval_task').set({ assignee, owner_id: null, delegation: null, revision: task.revision + 1 }).where('id', '=', taskId).execute();
114
+ await tx.updateTable('flow.approval_instance').set({ updated_at: sql `now()` }).where('id', '=', inst.id).execute();
115
+ await recordTaskAction(tx, inst, taskId, userId, data.action, data.reason, { from: task.assignee, to: assignee, revision: task.revision + 1 });
116
+ return { taskId, revision: task.revision + 1, createdTaskIds: [] };
117
+ }
118
+ const permission = data.action === 'resolve' ? 'delegate' : data.action;
119
+ if (node.kind === 'ai' || !node.actions?.[permission])
120
+ throw cageError('FORBIDDEN', { reason: '该节点未开放此任务操作' });
121
+ const pendingDelegation = task.delegation === 'pending';
122
+ if ((data.action === 'resolve') !== pendingDelegation)
123
+ throw cageError('INVALID_TRANSITION');
124
+ const createdTaskIds = [];
125
+ let assignee = task.assignee, owner = task.owner_id, delegation = task.delegation;
126
+ if (data.action === 'resolve') {
127
+ // 归还只能回到服务端保留的原审批人;停用或撤权后不能假装归还成功。
128
+ await authorizedTaskActor(k, tx, inst, task.owner_id);
129
+ assignee = task.owner_id;
130
+ delegation = 'resolved';
131
+ }
132
+ else {
133
+ const targets = data.action === 'addSign' ? data.userIds : [data.targetUserId];
134
+ if (new Set(targets).size !== targets.length || targets.includes(userId))
135
+ throw cageError('INVALID_INPUT');
136
+ const peers = await tx.selectFrom('flow.approval_task').select(['assignee', 'owner_id', 'task_kind'])
137
+ .where('instance_id', '=', inst.id).where('step', '=', task.step).execute();
138
+ if (targets.some(id => peers.some(p => p.assignee === id || p.owner_id === id)))
139
+ throw cageError('CONFLICT', { reason: '接收人已参与当前节点' });
140
+ for (const target of targets)
141
+ await authorizedTaskActor(k, tx, inst, target);
142
+ if (data.action === 'addSign') {
143
+ // 第一批在途快照只有 addSign 布尔值,仍限原来的并行加签;新实例显式保存位置集合。
144
+ if (!(node.signPositions ?? ['parallel']).includes(data.placement ?? 'parallel'))
145
+ throw cageError('FORBIDDEN', { reason: '该实例未开放此加签位置' });
146
+ if (task.task_kind !== 'original')
147
+ throw cageError('FORBIDDEN', { reason: '加签待办不能再次加签' });
148
+ if (peers.filter(p => p.task_kind === 'additional').length + targets.length > 20)
149
+ throw cageError('INVALID_INPUT', { reason: '节点加签总人数最多为 20' });
150
+ for (const target of targets) {
151
+ const added = await tx.insertInto('flow.approval_task').values({ tenant_id: tenantId, instance_id: inst.id,
152
+ step: task.step, title: task.title, assignee: target, task_kind: 'additional', parent_task_id: task.id,
153
+ sign_position: data.placement ?? 'parallel', status: data.placement === 'after' ? 'waiting' : 'pending' }).returning('id').executeTakeFirstOrThrow();
154
+ createdTaskIds.push(added.id);
155
+ }
156
+ }
157
+ else {
158
+ assignee = data.targetUserId;
159
+ owner = data.action === 'delegate' ? userId : null;
160
+ delegation = data.action === 'delegate' ? 'pending' : null;
161
+ }
162
+ }
163
+ // 前签先挂起父任务,只有全部前签批准才能由引擎唤醒;waiting 任务不能操作或决定。
164
+ await tx.updateTable('flow.approval_task').set({ assignee, owner_id: owner, delegation, revision: task.revision + 1,
165
+ status: data.action === 'addSign' && data.placement === 'before' ? 'waiting' : 'pending' }).where('id', '=', taskId).execute();
166
+ await tx.updateTable('flow.approval_instance').set({ updated_at: sql `now()` }).where('id', '=', inst.id).execute();
167
+ await recordTaskAction(tx, inst, taskId, userId, data.action, data.reason, { from: task.assignee, to: assignee,
168
+ revision: task.revision + 1, ...(data.action === 'addSign' ? { userIds: data.userIds, taskIds: createdTaskIds, placement: data.placement ?? 'parallel' } : {}) });
169
+ return { taskId, revision: task.revision + 1, createdTaskIds };
170
+ });
171
+ }
172
+ /** 前向迁移:旧待办保持 original/revision=0,既有实例无 actions 因而不会自动开放管理操作。 */
173
+ export const APPROVAL_TASK_ACTIONS_MIGRATION = {
174
+ name: 'cage:approval_task_actions_001',
175
+ sql: `
176
+ ALTER TABLE flow.approval_task ADD COLUMN revision integer NOT NULL DEFAULT 0 CHECK (revision >= 0);
177
+ ALTER TABLE flow.approval_task ADD COLUMN owner_id uuid;
178
+ ALTER TABLE flow.approval_task ADD COLUMN delegation text CHECK (delegation IN ('pending','resolved'));
179
+ ALTER TABLE flow.approval_task ADD COLUMN task_kind text NOT NULL DEFAULT 'original' CHECK (task_kind IN ('original','additional'));
180
+ ALTER TABLE flow.approval_task ADD CONSTRAINT approval_task_delegation_owner CHECK (delegation IS NULL OR owner_id IS NOT NULL);
181
+ CREATE TABLE flow.approval_task_action (
182
+ id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
183
+ tenant_id uuid NOT NULL,
184
+ instance_id uuid NOT NULL REFERENCES flow.approval_instance(id),
185
+ task_id uuid REFERENCES flow.approval_task(id),
186
+ actor_id uuid,
187
+ action text NOT NULL,
188
+ reason text,
189
+ details jsonb NOT NULL,
190
+ created_at timestamptz NOT NULL DEFAULT now()
191
+ );
192
+ CREATE INDEX approval_task_action_instance_idx ON flow.approval_task_action(tenant_id, instance_id, id);
193
+ REVOKE ALL ON flow.approval_task_action FROM cage_app;
194
+ GRANT SELECT, INSERT ON flow.approval_task_action TO cage_app;
195
+ GRANT USAGE, SELECT ON SEQUENCE flow.approval_task_action_id_seq TO cage_app;
196
+ `,
197
+ };
198
+ //# sourceMappingURL=task-actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-actions.js","sourceRoot":"","sources":["../src/task-actions.ts"],"names":[],"mappings":"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"}