@stalfh233/omc-cli 0.4.24 → 0.4.26
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/dist/cli.js
CHANGED
|
@@ -734,7 +734,7 @@ function intentWarnings(intent) {
|
|
|
734
734
|
// default (数据新增/数据更新/…). `rule.save` keeps the stored name for these
|
|
735
735
|
// codes, so a declared `name` is ignored — say so rather than silently
|
|
736
736
|
// dropping it (a caller who meant to rename would otherwise be confused).
|
|
737
|
-
if (PLATFORM_TRIGGER_RULE_CODES.has(rule.code))
|
|
737
|
+
if (PLATFORM_TRIGGER_RULE_CODES.has(rule.code) && rule.nameImplicit !== true)
|
|
738
738
|
warnings.push({
|
|
739
739
|
resource: `rule:${model.code}.${rule.code}`,
|
|
740
740
|
code: "rule-preset-name-ignored",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ENDPOINTS } from "../../endpoints.js";
|
|
2
|
+
import { PLATFORM_TRIGGER_RULE_CODES } from "../../lanes/rule-graph.js";
|
|
2
3
|
import { decodeJsonColumn, JSON_COLUMN_NULL_COALESCE } from "../../json-column.js";
|
|
3
4
|
import { wireCall, wireRows } from "../../wire.js";
|
|
4
5
|
import { countConditionLeaves, prepareRuleGraph, RULE_IDENTITY_FILTER, validateRuleNodeGraph } from "../../lanes/rule-graph.js";
|
|
@@ -7,6 +8,16 @@ import { isScalarString, pushError } from "../validation.js";
|
|
|
7
8
|
import { toPlain } from "../yaml.js";
|
|
8
9
|
/** Keys a rule item accepts. */
|
|
9
10
|
const RULE_KEYS = new Set(["code", "name", "enabled", "bizRuleType", "customTrigger", "actions", "nodeGraph"]);
|
|
11
|
+
/** Platform-managed display names of the preset trigger rows (live rule.list evidence 2026-10-12). */
|
|
12
|
+
const PRESET_RULE_DEFAULT_NAMES = Object.freeze({
|
|
13
|
+
Create: "数据新增",
|
|
14
|
+
Update: "数据更新",
|
|
15
|
+
Delete: "数据删除",
|
|
16
|
+
GetList: "加载列表数据",
|
|
17
|
+
Load: "加载表单详情",
|
|
18
|
+
Available: "流程生效",
|
|
19
|
+
Cancel: "流程作废",
|
|
20
|
+
});
|
|
10
21
|
/** Keys a compact action accepts. */
|
|
11
22
|
const ACTION_KEYS = new Set(["type", "target", "filter", "when", "set"]);
|
|
12
23
|
/** Keys a compact filter/assignment item accepts. */
|
|
@@ -369,8 +380,21 @@ export const businessruleCapability = {
|
|
|
369
380
|
pushError(ctx, "intent-rule-code-duplicate", `规则 code 在模型内重复:${code}`, `${base}.code`, "value");
|
|
370
381
|
seen.add(code);
|
|
371
382
|
}
|
|
372
|
-
|
|
373
|
-
|
|
383
|
+
// r18 retro (G4, parse-level): a PRESET trigger row's name is
|
|
384
|
+
// platform-managed (Create=数据新增…; rule.save's update branch ignores
|
|
385
|
+
// the caller's name for these codes) — so it may be OMITTED for preset
|
|
386
|
+
// codes and the compiler fills the platform default. CUSTOM rules keep
|
|
387
|
+
// the required name (the designer enforces one there too).
|
|
388
|
+
let nameImplicit = false;
|
|
389
|
+
let ruleName;
|
|
390
|
+
if (isScalarString(nameNode))
|
|
391
|
+
ruleName = nameNode.value;
|
|
392
|
+
else if (PLATFORM_TRIGGER_RULE_CODES.has(code)) {
|
|
393
|
+
nameImplicit = true;
|
|
394
|
+
ruleName = PRESET_RULE_DEFAULT_NAMES[code] ?? code;
|
|
395
|
+
}
|
|
396
|
+
else
|
|
397
|
+
pushError(ctx, "intent-rule-name-invalid", "规则 name 必须是非空字符串(预置触发行 Create/Update/… 可省略,省略即用平台默认名)", `${base}.name`, "value");
|
|
374
398
|
let enabled = false;
|
|
375
399
|
if (enabledNode !== undefined) {
|
|
376
400
|
if (enabledNode.kind !== "scalar" || typeof enabledNode.value !== "boolean")
|
|
@@ -406,11 +430,12 @@ export const businessruleCapability = {
|
|
|
406
430
|
else
|
|
407
431
|
nodeGraph = toPlain(nodeGraphNode);
|
|
408
432
|
}
|
|
409
|
-
if (code.length === 0 ||
|
|
433
|
+
if (code.length === 0 || ruleName === undefined)
|
|
410
434
|
return;
|
|
411
435
|
const rule = {
|
|
412
436
|
code,
|
|
413
|
-
name:
|
|
437
|
+
name: ruleName,
|
|
438
|
+
...(nameImplicit ? { nameImplicit: true } : {}),
|
|
414
439
|
enabled,
|
|
415
440
|
...(bizRuleType !== undefined ? { bizRuleType } : {}),
|
|
416
441
|
...(customTrigger !== undefined ? { customTrigger } : {}),
|
|
@@ -551,6 +551,15 @@ export function registerRuntimeDataLane(tools) {
|
|
|
551
551
|
submit: z.boolean().optional().describe("r18 retro:true=一调完成态——保存后立即直提(无流程模型 DRAFT→COMPLETED,触发 Create 业务规则);与 workflowCode 互斥(流程草稿须走 data.submit 两段式)。默认 false 仅存草稿"),
|
|
552
552
|
...readbackProjectionArgs,
|
|
553
553
|
}, async (session, args) => {
|
|
554
|
+
// F-A (self-audit): the combo used to be silently ignored (the workflow
|
|
555
|
+
// draft branch returns without honoring submit). Refuse before any wire.
|
|
556
|
+
if (args.submit === true && typeof args.workflowCode === "string" && args.workflowCode.trim())
|
|
557
|
+
throw new ToolRefusalError({
|
|
558
|
+
status: "refused",
|
|
559
|
+
blocker: "submit-workflow-code-conflict",
|
|
560
|
+
schemaCode: args.schemaCode,
|
|
561
|
+
message: "submit:true 与 workflowCode 互斥——workflowCode 是流程草稿两段式的第一段(返回 workItemId 后用 data.submit 提交);无流程模型的一调完成态用 submit:true 且不带 workflowCode",
|
|
562
|
+
});
|
|
554
563
|
const { sheetCode, resolvedFrom } = await resolveFormSheetCode(session, { schemaCode: args.schemaCode, sheetCode: args.sheetCode });
|
|
555
564
|
const formData = await stampChildRowStatuses(session, args.schemaCode, args.formData);
|
|
556
565
|
if (typeof args.workflowCode === "string" && args.workflowCode.trim()) {
|
|
@@ -645,6 +654,24 @@ export function registerRuntimeDataLane(tools) {
|
|
|
645
654
|
// "record AND rule effect", not "a draft". Chain the no-flow submit in
|
|
646
655
|
// the same governed write (the same sibling execute apply_changes uses).
|
|
647
656
|
if (args.submit === true) {
|
|
657
|
+
// F-B (self-audit): data.submit AUTO-STARTS a published workflow
|
|
658
|
+
// (resolvePublishedWorkflowCode → formType 1 → PROCESSING, not
|
|
659
|
+
// COMPLETED) — the one-call chain's ruleHint would lie. Workflow-
|
|
660
|
+
// backed models keep the two-phase chain.
|
|
661
|
+
const publishedWorkflow = await resolvePublishedWorkflowCode(session, args.schemaCode);
|
|
662
|
+
if (publishedWorkflow) {
|
|
663
|
+
return {
|
|
664
|
+
performed: { errcode: performed.errcode, bizObjectId, sheetCode, resolvedFrom, submitted: false },
|
|
665
|
+
readback: {
|
|
666
|
+
...plainReadback,
|
|
667
|
+
submitRefused: {
|
|
668
|
+
blocker: "submit-model-has-workflow",
|
|
669
|
+
workflowCode: publishedWorkflow,
|
|
670
|
+
message: `本模型有已发布流程 ${publishedWorkflow}:submit:true 的直提只适用无流程模型(流程模型会自动起流程得到 PROCESSING 而非完成态,Create 规则语义也不同)。草稿已保存;正确链路 = data.save {workflowCode} 建流程草稿(返回 workItemId)→ data.submit {bizObjectId, workflowInstanceId, workItemId}(见 describe data.submit --example workflow-backed-data-submit)`,
|
|
671
|
+
},
|
|
672
|
+
},
|
|
673
|
+
};
|
|
674
|
+
}
|
|
648
675
|
const submitTool = tools.find((entry) => entry.name === "data.submit");
|
|
649
676
|
const submitOutcome = submitTool?.writeExecute
|
|
650
677
|
? await submitTool.writeExecute(session, { schemaCode: args.schemaCode, bizObjectId, formData: args.formData })
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stalfh233/omc-cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.26",
|
|
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.26",
|
|
55
55
|
"proper-lockfile": "4.1.2",
|
|
56
56
|
"write-file-atomic": "6.0.0",
|
|
57
57
|
"zod": "^3.23.8",
|
|
@@ -171,7 +171,10 @@ only the section for the capability you need —
|
|
|
171
171
|
- **recipe**:
|
|
172
172
|
- `omc describe data.save --example workflow-backed-data-save`
|
|
173
173
|
- `omc describe data.submit --example workflow-backed-data-submit`(有流程)
|
|
174
|
-
-
|
|
174
|
+
- 无流程模型的规则验证路径(两选):
|
|
175
|
+
- 一调:`data.save {schemaCode, formData, submit:true}` ——保存+直提 COMPLETED,触发 Create 规则(模型有已发布流程时会拒绝并指路两段式)
|
|
176
|
+
- 两步:`data.save`(DRAFT)→ `data.submit {schemaCode, bizObjectId, formData}` ——示例 `omc describe data.submit --example plain-data-submit`
|
|
177
|
+
- 流程模型:`data.save {workflowCode}`(返回 workItemId)→ `data.submit {bizObjectId, workflowInstanceId, workItemId}`(workflow-backed-data-submit)
|
|
175
178
|
- **边界 / 陷阱**:读实际业务记录是 OMC 独有能力。**计算字段(FORMULA/子表计算)不由 API 回填**——写测试数据带预算值,公式正确性人工前台确认;带子表计算字段的模型 API 写可能 50000(服务端重算 NPE),前台正常。
|
|
176
179
|
|
|
177
180
|
---
|