@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.
- package/README.md +77 -9
- package/dist/ai.d.ts +55 -0
- package/dist/ai.js +51 -0
- package/dist/ai.js.map +1 -0
- package/dist/bridge.d.ts +7 -1
- package/dist/bridge.js +29 -8
- package/dist/bridge.js.map +1 -1
- package/dist/deadlines.d.ts +29 -0
- package/dist/deadlines.js +72 -0
- package/dist/deadlines.js.map +1 -0
- package/dist/engine.d.ts +138 -4
- package/dist/engine.js +306 -99
- package/dist/engine.js.map +1 -1
- package/dist/execution.d.ts +41 -0
- package/dist/execution.js +85 -0
- package/dist/execution.js.map +1 -0
- package/dist/http.d.ts +6 -0
- package/dist/http.js +83 -12
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/openapi.d.ts +17 -0
- package/dist/openapi.js +71 -0
- package/dist/openapi.js.map +1 -0
- package/dist/operations-schema.d.ts +20 -0
- package/dist/operations-schema.js +20 -0
- package/dist/operations-schema.js.map +1 -0
- package/dist/operations.d.ts +118 -0
- package/dist/operations.js +349 -0
- package/dist/operations.js.map +1 -0
- package/dist/route.d.ts +85 -7
- package/dist/route.js +100 -23
- package/dist/route.js.map +1 -1
- package/dist/selectors.d.ts +8 -0
- package/dist/selectors.js +53 -0
- package/dist/selectors.js.map +1 -0
- package/dist/task-actions.d.ts +94 -0
- package/dist/task-actions.js +198 -0
- package/dist/task-actions.js.map +1 -0
- package/dist/task-stages.d.ts +17 -0
- package/dist/task-stages.js +47 -0
- package/dist/task-stages.js.map +1 -0
- package/dist/types.d.ts +6 -2
- package/package.json +2 -2
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 前后加签的持久阶段与前向迁移,由审批引擎在批准事务内调用。
|
|
3
|
+
* 父子关系保存在任务上,不改写实例步骤或 AI run;实例锁保证激活和决定/取消不会交错提交。
|
|
4
|
+
* 所有追加票都是必签,any 的原票胜出只替代原票责任,不能吞掉已创建的加签。
|
|
5
|
+
*/
|
|
6
|
+
import { type Transaction } from 'kysely';
|
|
7
|
+
/**
|
|
8
|
+
* 批准后激活可运行任务并追加系统阶段记录,激活也递增 revision 使旧页面失效。
|
|
9
|
+
* before 全部完成才唤醒仍 waiting 的父票;父票已被 any 跳过则不复活。
|
|
10
|
+
* after 在 all 中等待自己的父票批准,在 any 中等待任意原票批准;追加票自身仍全部必签。
|
|
11
|
+
*/
|
|
12
|
+
export declare function activateSignatures(tx: Transaction<any>, inst: any, task: any, anyMode: boolean, userId: string): Promise<void>;
|
|
13
|
+
/** 前向升级:旧任务保持 direct、无父任务与签序,旧数据不会被转换为候选池或合并票数。 */
|
|
14
|
+
export declare const APPROVAL_TASK_STAGES_MIGRATION: {
|
|
15
|
+
name: string;
|
|
16
|
+
sql: string;
|
|
17
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 前后加签的持久阶段与前向迁移,由审批引擎在批准事务内调用。
|
|
3
|
+
* 父子关系保存在任务上,不改写实例步骤或 AI run;实例锁保证激活和决定/取消不会交错提交。
|
|
4
|
+
* 所有追加票都是必签,any 的原票胜出只替代原票责任,不能吞掉已创建的加签。
|
|
5
|
+
*/
|
|
6
|
+
import { sql } from 'kysely';
|
|
7
|
+
import { recordTaskAction } from './task-actions.js';
|
|
8
|
+
/**
|
|
9
|
+
* 批准后激活可运行任务并追加系统阶段记录,激活也递增 revision 使旧页面失效。
|
|
10
|
+
* before 全部完成才唤醒仍 waiting 的父票;父票已被 any 跳过则不复活。
|
|
11
|
+
* after 在 all 中等待自己的父票批准,在 any 中等待任意原票批准;追加票自身仍全部必签。
|
|
12
|
+
*/
|
|
13
|
+
export async function activateSignatures(tx, inst, task, anyMode, userId) {
|
|
14
|
+
const activated = [];
|
|
15
|
+
if (task.sign_position === 'before') {
|
|
16
|
+
const unfinished = await tx.selectFrom('flow.approval_task').select('id').where('parent_task_id', '=', task.parent_task_id)
|
|
17
|
+
.where('sign_position', '=', 'before').where('status', 'in', ['pending', 'waiting']).executeTakeFirst();
|
|
18
|
+
if (!unfinished) {
|
|
19
|
+
const parent = await tx.updateTable('flow.approval_task').set({ status: 'pending', revision: sql `revision + 1` })
|
|
20
|
+
.where('id', '=', task.parent_task_id).where('instance_id', '=', inst.id).where('status', '=', 'waiting').returning('id').execute();
|
|
21
|
+
activated.push(...parent.map(row => row.id));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (task.task_kind === 'original') {
|
|
25
|
+
const children = await tx.updateTable('flow.approval_task').set({ status: 'pending', revision: sql `revision + 1` })
|
|
26
|
+
.where('instance_id', '=', inst.id).where('step', '=', task.step).where('sign_position', '=', 'after').where('status', '=', 'waiting')
|
|
27
|
+
.$if(!anyMode, query => query.where('parent_task_id', '=', task.id)).returning('id').execute();
|
|
28
|
+
activated.push(...children.map(row => row.id));
|
|
29
|
+
}
|
|
30
|
+
if (activated.length)
|
|
31
|
+
await recordTaskAction(tx, inst, task.id, userId, 'activated', null, { taskIds: activated, cause: 'signature_dependency_approved' });
|
|
32
|
+
}
|
|
33
|
+
/** 前向升级:旧任务保持 direct、无父任务与签序,旧数据不会被转换为候选池或合并票数。 */
|
|
34
|
+
export const APPROVAL_TASK_STAGES_MIGRATION = {
|
|
35
|
+
name: 'cage:approval_task_stages_002',
|
|
36
|
+
sql: `
|
|
37
|
+
ALTER TABLE flow.approval_task ALTER COLUMN assignee DROP NOT NULL;
|
|
38
|
+
ALTER TABLE flow.approval_task ADD COLUMN assignment text NOT NULL DEFAULT 'direct' CHECK (assignment IN ('direct','candidate'));
|
|
39
|
+
ALTER TABLE flow.approval_task ADD COLUMN parent_task_id uuid REFERENCES flow.approval_task(id);
|
|
40
|
+
ALTER TABLE flow.approval_task ADD COLUMN sign_position text CHECK (sign_position IN ('parallel','before','after'));
|
|
41
|
+
ALTER TABLE flow.approval_task ADD CONSTRAINT approval_task_assignee_required CHECK (assignee IS NOT NULL OR assignment = 'candidate');
|
|
42
|
+
ALTER TABLE flow.approval_task ADD CONSTRAINT approval_task_signature_parent CHECK ((parent_task_id IS NULL AND sign_position IS NULL) OR (parent_task_id IS NOT NULL AND sign_position IS NOT NULL AND task_kind = 'additional' AND assignment = 'direct'));
|
|
43
|
+
CREATE INDEX approval_task_candidates_idx ON flow.approval_task(tenant_id, created_at DESC) WHERE assignment = 'candidate' AND assignee IS NULL AND status = 'pending';
|
|
44
|
+
CREATE INDEX approval_task_parent_idx ON flow.approval_task(parent_task_id) WHERE parent_task_id IS NOT NULL;
|
|
45
|
+
`,
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=task-stages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-stages.js","sourceRoot":"","sources":["../src/task-stages.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,GAAG,EAAoB,MAAM,QAAQ,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EAAoB,EAAE,IAAS,EAAE,IAAS,EAAE,OAAgB,EAAE,MAAc;IACnH,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,IAAI,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,CAAC;aACxH,KAAK,CAAC,eAAe,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC;QAC1G,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAA,cAAc,EAAE,CAAC;iBAC9G,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,aAAa,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;YACtI,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IACD,IAAI,IAAI,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAA,cAAc,EAAE,CAAC;aAChH,KAAK,CAAC,aAAa,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,eAAe,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,SAAS,CAAC;aACrI,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QACjG,SAAS,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,SAAS,CAAC,MAAM;QAAE,MAAM,gBAAgB,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC,CAAC;AAC7J,CAAC;AAED,mDAAmD;AACnD,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC5C,IAAI,EAAE,+BAA+B;IACrC,GAAG,EAAE;;;;;;;;;CASN;CACA,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import type { ApprovalEngine } from '@yss123/cage-kernel/worker';
|
|
2
|
+
/** 引擎交给桥接层的业务结论;结果不会直接更新业务表,必须解析到绑定命令重新校验。 */
|
|
2
3
|
export interface ApprovalOutcome {
|
|
3
4
|
process: string;
|
|
4
5
|
tenantId: string;
|
|
5
6
|
/** 单据 id */
|
|
6
7
|
businessKey: string;
|
|
7
|
-
outcome: 'approved' | 'rejected';
|
|
8
|
+
outcome: 'approved' | 'rejected' | 'returned';
|
|
8
9
|
/** 最后一位审批人:结论命令以流程身份执行,代表这个人(职责分离、额度按他判断) */
|
|
9
|
-
lastApprover
|
|
10
|
+
lastApprover?: string;
|
|
11
|
+
/** 审批所针对的单据提交版本;提供时命令拒绝把旧审批结论应用到已变化的对象。 */
|
|
12
|
+
expectedVersion?: number;
|
|
10
13
|
}
|
|
14
|
+
/** 外部引擎适配约定;调用方负责可信回调来源,桥接层负责重新核对结论命令及真人权限。 */
|
|
11
15
|
export interface ApprovalAdapter extends ApprovalEngine {
|
|
12
16
|
/** 注册流程结束回调 */
|
|
13
17
|
onCompleted(cb: (r: ApprovalOutcome) => Promise<void>): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yss123/cage-approval",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "审批适配接口、桥接与代码内封闭路由(可选)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"fastify": "^5.6.0",
|
|
19
19
|
"kysely": "^0.28.5",
|
|
20
20
|
"zod": "^4.1.5",
|
|
21
|
-
"@yss123/cage-kernel": "0.
|
|
21
|
+
"@yss123/cage-kernel": "0.3.1"
|
|
22
22
|
},
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"repository": {
|