@stalfh233/omc-cli 0.4.36 → 0.4.37
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 +2 -2
- package/dist/cli.js +42 -578
- package/dist/execution-metadata.js +24 -1160
- package/dist/intent/plan-apply.js +587 -0
- package/dist/recipes/b2-registration.js +87 -0
- package/dist/recipes/businessrule.js +269 -0
- package/dist/recipes/datarule.js +215 -0
- package/dist/recipes/dictionary.js +42 -0
- package/dist/recipes/field.js +230 -0
- package/dist/recipes/form.js +19 -0
- package/dist/recipes/list-view.js +31 -0
- package/dist/recipes/model.js +34 -0
- package/dist/recipes/online-js.js +32 -0
- package/dist/recipes/runtime-data.js +113 -0
- package/dist/recipes/shared.js +8 -0
- package/dist/recipes/workflow.js +119 -0
- package/package.json +2 -2
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { environment, model, commonRecovery } from "./shared.js";
|
|
2
|
+
const workflowTemplateUpdate = Object.freeze({
|
|
3
|
+
id: "workflow-approval-template-update",
|
|
4
|
+
title: "改流程草稿模板(开始→审批→结束,可多级)并发布",
|
|
5
|
+
status: "requires-prior-readback",
|
|
6
|
+
tool: "workflow.update",
|
|
7
|
+
args: {
|
|
8
|
+
environment,
|
|
9
|
+
schemaCode: model,
|
|
10
|
+
code: "applyWorkflow",
|
|
11
|
+
template: {
|
|
12
|
+
workflowCode: "applyWorkflow",
|
|
13
|
+
activities: [
|
|
14
|
+
{ activityCode: "Activity1", activityType: "START", activityName: "开始", i18nMessage: "开始" },
|
|
15
|
+
{ activityCode: "Activity2", activityType: "PARTICIPANT", activityName: "填写申请单", i18nMessage: "填写申请单", participant: "{Originator}" },
|
|
16
|
+
{ activityCode: "Activity3", activityType: "PARTICIPANT", activityName: "部门负责人审批", i18nMessage: "部门负责人审批", participant: "FindUserByRole({Originator.OU},\"<部门负责人角色code>\",\"random\")" },
|
|
17
|
+
{ activityCode: "Activity4", activityType: "PARTICIPANT", activityName: "财务负责人审批", i18nMessage: "财务负责人审批", participant: "FindUserByRole({Originator.OU},\"<财务负责人角色code>\",\"random\")" },
|
|
18
|
+
{ activityCode: "Activity5", activityType: "END", activityName: "结束", i18nMessage: "结束" },
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
preconditions: ["workflow.create 已完成;先用 workflow.get_draft 取草稿基线——**默认(紧凑)面已含 activities 的 activityCode/type/name 与 edges,够改流程,不要 --full(30–75KB)**"],
|
|
23
|
+
conditionalRequirements: [
|
|
24
|
+
"**activities 用数组**(也接受 {0:…,1:…} 索引对象);每个活动必须带 activityCode(Activity1..N)与 activityType,缺了会被拒——以 get_draft 的值为基线改,不要凭记忆拼;",
|
|
25
|
+
"**一个模型只能有一个流程**:workflow.create 对已有流程的模型会拒(一个模型只能有一个流程);要改现有流程直接 workflow.update,不要另建新 code;",
|
|
26
|
+
"多级审批:为每个审批节点各写一个 PARTICIPANT 活动(activityCode 唯一),END 放最后;数组里按顺序就是审批链顺序;新增的审批节点由工具自动接入链路(补全到 END 的连线),无需自己写 routes;",
|
|
27
|
+
"**{Originator}=发起人自己**:审批节点用它=提交人自审自己——提交人与审批人同账号时平台可能直接自动通过(COMPLETED,无待办;r40 实证,与节点结构有关)。需要独立审批人时绑定具体用户 id 或 `FindUserByRole({Originator.OU},\"<角色code>\",\"random\")`;验收要 PENDING 待办时先确认审批人≠提交人;",
|
|
28
|
+
"**participant 必须是平台可解析的三种形态之一(真实生产 2026-09-23 观察)**:(a) 关键字 `{Originator}`;(b) 参与者对象数组 JSON `[{\"code\":\"<角色code>\",\"corpId\":\"<corpId|other>\",\"id\":\"<roleId>\",\"name\":\"<角色名>\",\"type\":2}]`(type 2=角色,3=用户;多个用 `+` 连接);(c) 函数 `FindUserByRole({Originator.OU},\"<roleCode>\",\"random\")`。**自由文本角色名(如 `部门负责人`)能 publish 但解析不到人、不生成待办**——先用 `org.role.list` / `org.department.list` 拿 code/id 再构造。工具会在 readback 里以 `participantWarnings` 标出自由文本。",
|
|
29
|
+
"**审批节点必须带 sheetCode(=模型默认表单槽位,通常等于 schemaCode)——S29 契约:participant sheetCode 为空 publish 会 401026 WORKFLOW_ACTIVITY_NO_SHEET。工具已自动回填,正常无需手填**;",
|
|
30
|
+
"节点类型 START / PARTICIPANT / END;省略的既有节点由 merge 保留;",
|
|
31
|
+
"**平台 workflow.create 会自动生成含「填写申请单」发起节点的草稿(START → 填写申请单 → 审批 → END);workflow.update 是 merge,不删除既有节点——要严格三节点需在设计器删该节点,或如实接受该发起节点**",
|
|
32
|
+
"**读回 participant 为空是平台模板更新面的已知残留,不要反复 update 试图修正(实测 6 次 update 仍为空);记录该差异并留待设计器核对,一次读回确认即可**",
|
|
33
|
+
],
|
|
34
|
+
priorToolReferences: [{ tool: "workflow.get_draft", args: { environment, workflowCode: "applyWorkflow" }, purpose: "取草稿基线作为 merge 基线(默认面即含 activityCode/name/edges;不要 --full)" }],
|
|
35
|
+
dryRun: { supported: true, command: `omc call workflow.update --env ${environment} --dry-run --args '<recipe.args>'`, notes: "dry-run 校验模板形状,不写入" },
|
|
36
|
+
expectedReadback: { readback: { draftUpdated: true, activities: "<节点数=你数组长度>", edges: "<链路>" }, next: ["用默认 workflow.get_draft 复核 activities/edges(不要 --full)", "workflow.publish", "workflow.bindRule"] },
|
|
37
|
+
refusalRecovery: [
|
|
38
|
+
{ code: "tool-input-invalid", action: "每个 activity 补 activityCode(从 get_draft 抄);templateType 省略" },
|
|
39
|
+
{ code: "workflow-publish-invalid", action: "publish 被 ValidateMessage[] 拒(401026/401027/401017)时,多为审批节点 sheetCode 为空或新增节点未接入链路——工具已自动回填 sheetCode 并补全链,改完模板再 update 一次;不要反复 publish" },
|
|
40
|
+
...commonRecovery,
|
|
41
|
+
],
|
|
42
|
+
requiresEnvironmentDerivedIds: true,
|
|
43
|
+
prerequisiteData: { source: "workflow.get_draft", fields: ["activities[].activityCode"] },
|
|
44
|
+
});
|
|
45
|
+
const workflowConditionalBranch = Object.freeze({
|
|
46
|
+
id: "workflow-conditional-branch",
|
|
47
|
+
title: "按字段条件分流(urgent 走主管审批,否则直接结束)",
|
|
48
|
+
status: "requires-prior-readback",
|
|
49
|
+
tool: "workflow.update",
|
|
50
|
+
args: {
|
|
51
|
+
environment,
|
|
52
|
+
schemaCode: model,
|
|
53
|
+
code: "applyWorkflow",
|
|
54
|
+
template: {
|
|
55
|
+
workflowCode: "applyWorkflow",
|
|
56
|
+
activities: [
|
|
57
|
+
{ activityCode: "A1", activityType: "START", activityName: "开始", i18nMessage: "开始" },
|
|
58
|
+
{ activityCode: "A2", activityType: "PARTICIPANT", activityName: "填写申请单", i18nMessage: "填写申请单", participant: "{Originator}" },
|
|
59
|
+
{ activityCode: "A3", activityType: "PARTICIPANT", activityName: "主管审批", i18nMessage: "主管审批", participant: "FindUserByRole({Originator.OU},\"SYS_1000000\",\"random\")" },
|
|
60
|
+
{ activityCode: "A4", activityType: "END", activityName: "结束", i18nMessage: "结束" },
|
|
61
|
+
],
|
|
62
|
+
routes: [
|
|
63
|
+
{ preNode: "A1", postNode: "A2" },
|
|
64
|
+
{ preNode: "A2", postNode: "A3", ruleConditionGroup: [[{ currentDataItem: "r16_level", bizPropertyType: 12, conditionType: "EQ", value: "urgent" }]] },
|
|
65
|
+
{ preNode: "A2", postNode: "A4", utilizeElse: true },
|
|
66
|
+
{ preNode: "A3", postNode: "A4" },
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
preconditions: ["workflow.create 已完成;路由的活动 code(preNode/postNode)必须命中 activities 里的 activityCode;先用 workflow.get_draft 取基线"],
|
|
71
|
+
conditionalRequirements: [
|
|
72
|
+
"**条件连线 = routes[] 里的 ruleConditionGroup**(外层 OR、内层 AND);叶只能有 4 个键 `{currentDataItem, bizPropertyType, conditionType, value}`——**多一个键(如照抄业务规则的 ruleValueType/targetDataItem)会让平台回 workflow/update 误导性的 `401001 流程不存在!`,工具已写前拒绝**。",
|
|
73
|
+
"`currentDataItem` = 当前模型字段 code(子表列用 `childSchemaCode.fieldCode`);`bizPropertyType` **用数字索引**(SHORT_TEXT=0 / NUMERICAL=2 / DATE=3 / LOGICAL=4 / RADIO=12 / DROPDOWN_BOX=14 / STAFF_SELECTOR=50…;工具也接受枚举名并转索引);`conditionType` ∈ EQ/NEQ/GT/LT/GTEQ/LTEQ/CT/NCT/EP/NEP/BETWEEN/...;`value` 为字面量。",
|
|
74
|
+
"**else/兜底连线用 `utilizeElse:true`**(其余条件不满足时走);工具会自动把条件连线置 `popupType:EXPRESSION`(否则平台静默跳过)。",
|
|
75
|
+
"分支可只写 activities + routes:工具按数组顺序补全到 END 的连线(`con` 兜底线仍需你显式给,除非它就是主链)。",
|
|
76
|
+
],
|
|
77
|
+
priorToolReferences: [
|
|
78
|
+
{ tool: "workflow.get_draft", args: { environment, workflowCode: "applyWorkflow" }, purpose: "取草稿基线(apply_workflow 换成真实 workflowCode;默认面即含 activityCode/name/edges,不要 --full)" },
|
|
79
|
+
{ tool: "org.role.list", args: { environment }, purpose: "取真实参与人/角色 code,避免自由文本名解析不到人" },
|
|
80
|
+
],
|
|
81
|
+
dryRun: { supported: true, command: `omc call workflow.update --env ${environment} --dry-run --args '<recipe.args>'`, notes: "dry-run 校验 activities/routes/条件叶,不写入" },
|
|
82
|
+
expectedReadback: { readback: { draftUpdated: true, rules: [{ postActivityCode: "A3", ruleConditionGroup: [[{ currentDataItem: "r16_level", bizPropertyType: 12, conditionType: "EQ", value: "urgent" }]], popupType: "EXPRESSION" }, { postActivityCode: "A4", utilizeElse: true }] }, next: ["workflow.publish", "data.submit 两条(命中/不命中)验 workitem.list"] },
|
|
83
|
+
refusalRecovery: [
|
|
84
|
+
{ code: "workflow-route-condition-invalid", action: "条件叶只留 currentDataItem/bizPropertyType/conditionType/value;补 currentDataItem 与 conditionType;bizPropertyType 用数字索引或已知枚举名" },
|
|
85
|
+
{ code: "workflow-not-found", action: "先 workflow.create,再 workflow.get_draft 取基线——不要把 workflow 模板 id 当 workflowCode" },
|
|
86
|
+
{ code: "workflow-route-not-found", action: "preNode/postNode 必须是 activities 里真实存在的 activityCode(从 get_draft 抄)" },
|
|
87
|
+
...commonRecovery,
|
|
88
|
+
],
|
|
89
|
+
requiresEnvironmentDerivedIds: true,
|
|
90
|
+
prerequisiteData: { source: "workflow.get_draft", fields: ["activities[].activityCode", "org.role code"] },
|
|
91
|
+
});
|
|
92
|
+
const workflowBinding = Object.freeze({
|
|
93
|
+
id: "workflow-handler-binding",
|
|
94
|
+
title: "将规则合并绑定到 workflow handler 并发布",
|
|
95
|
+
status: "requires-prior-readback",
|
|
96
|
+
tool: "workflow.bindRule",
|
|
97
|
+
args: { environment, schemaCode: model, workflowCode: "<workflow.code>", ruleCode: "Create", handler: "end", publish: true },
|
|
98
|
+
preconditions: ["模型只有一个目标 workflow;workflow.create 已完成且 draft 存在;规则已保存"],
|
|
99
|
+
conditionalRequirements: ["handler 只能是 start、cancel、activate、end;workflow.bindRule 是 merge,不会删除既有 bizActions"],
|
|
100
|
+
priorToolReferences: [
|
|
101
|
+
{ tool: "workflow.get_draft", args: { environment, workflowCode: "<workflow.code>" }, purpose: "取得完整 draft,并确认目标 handler 字段" },
|
|
102
|
+
{ tool: "rule.list", args: { environment, schemaCode: model }, purpose: "确认 Create 规则存在" },
|
|
103
|
+
],
|
|
104
|
+
dryRun: { supported: true, command: `omc call workflow.bindRule --env ${environment} --dry-run --args '<recipe.args>'`, notes: "dry-run 验证 handler/code 互斥和写治理,不更新 workflow" },
|
|
105
|
+
expectedReadback: { readback: { handler: "end", handlerField: "endEventHandler", bound: true, published: true, publishedBound: true, semantics: "merge" } },
|
|
106
|
+
refusalRecovery: [
|
|
107
|
+
{ code: "workflow-not-found", action: "先 workflow.create,再用 workflow.get_draft 取得完整模板" },
|
|
108
|
+
{ code: "workflow-bindrule-codes-invalid", action: "只传 ruleCode 或只传 ruleCodes;不要同时传两者" },
|
|
109
|
+
{ code: "workflow-publish-not-applied", action: "先 workflow.get_draft/validate 修复完整模板,再重新 bindRule;以 published-face marker 为准" },
|
|
110
|
+
...commonRecovery,
|
|
111
|
+
],
|
|
112
|
+
requiresEnvironmentDerivedIds: true,
|
|
113
|
+
prerequisiteData: { source: "workflow.get_draft + rule.list", fields: ["workflow.code", "rule.code"] },
|
|
114
|
+
});
|
|
115
|
+
export const WORKFLOW_METADATA = Object.freeze({
|
|
116
|
+
"workflow.update": Object.freeze({ recipes: [workflowTemplateUpdate, workflowConditionalBranch], relatedTools: ["workflow.get_draft", "workflow.publish"] }),
|
|
117
|
+
"workflow.bindRule": Object.freeze({ recipes: [workflowBinding], relatedTools: ["workflow.create", "workflow.get_draft", "workflow.get_published", "rule.list"] }),
|
|
118
|
+
});
|
|
119
|
+
//# sourceMappingURL=workflow.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stalfh233/omc-cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.37",
|
|
4
4
|
"description": "CloudPivot 8.6 configuration capability CLI — governed, fail-closed, coverage-manifest bounded.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"commander": "14.0.3",
|
|
54
|
-
"omc-core": "0.4.
|
|
54
|
+
"omc-core": "0.4.37",
|
|
55
55
|
"proper-lockfile": "4.1.2",
|
|
56
56
|
"write-file-atomic": "6.0.0",
|
|
57
57
|
"zod": "^3.23.8",
|