@stalfh233/omc-cli 0.0.0-stage → 0.4.0

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 (181) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +304 -3
  3. package/coverage/m1-coverage-manifest-v1.json +1278 -0
  4. package/dist/approval-token.js +102 -0
  5. package/dist/args.js +25 -0
  6. package/dist/artifacts.js +119 -0
  7. package/dist/bench/call-face-eval.js +256 -0
  8. package/dist/bench/context-attribution.js +151 -0
  9. package/dist/bench/discovery-cost-eval.js +230 -0
  10. package/dist/bench/driver.js +81 -0
  11. package/dist/bench/evals.js +236 -0
  12. package/dist/bench/fake-http-server.js +65 -0
  13. package/dist/bench/instrument.js +87 -0
  14. package/dist/bench/intent-face-eval.js +343 -0
  15. package/dist/bench/run.js +166 -0
  16. package/dist/bench/scenario.js +343 -0
  17. package/dist/bench/types.js +76 -0
  18. package/dist/bi-wire.js +41 -0
  19. package/dist/bizservice-config.js +581 -0
  20. package/dist/call.js +153 -0
  21. package/dist/capability-absences.js +23 -0
  22. package/dist/capability-overview.js +492 -0
  23. package/dist/capability-shape.js +154 -0
  24. package/dist/cli-contract.js +70 -0
  25. package/dist/cli-output.js +73 -0
  26. package/dist/cli.js +1418 -0
  27. package/dist/code-rules.js +69 -0
  28. package/dist/command-transport.js +155 -0
  29. package/dist/config-store.js +195 -0
  30. package/dist/context.js +21 -0
  31. package/dist/contract-consistency.js +66 -0
  32. package/dist/contract-resources.js +62 -0
  33. package/dist/coverage-consistency.js +62 -0
  34. package/dist/coverage-registry.js +76 -0
  35. package/dist/coverage.js +130 -0
  36. package/dist/data-list-filter.js +114 -0
  37. package/dist/discovery.js +390 -0
  38. package/dist/endpoints.js +154 -0
  39. package/dist/environment-policy.js +26 -0
  40. package/dist/execution-metadata.js +1092 -0
  41. package/dist/fake/app.js +45 -0
  42. package/dist/fake/b2-registration.js +594 -0
  43. package/dist/fake/businessrule.js +242 -0
  44. package/dist/fake/datarule.js +72 -0
  45. package/dist/fake/dictionary.js +108 -0
  46. package/dist/fake/environment.js +30 -0
  47. package/dist/fake/field.js +167 -0
  48. package/dist/fake/form.js +101 -0
  49. package/dist/fake/index.js +121 -0
  50. package/dist/fake/list-view.js +289 -0
  51. package/dist/fake/model.js +136 -0
  52. package/dist/fake/online-js.js +18 -0
  53. package/dist/fake/report.js +253 -0
  54. package/dist/fake/routes.js +47 -0
  55. package/dist/fake/rule-lifecycle.js +37 -0
  56. package/dist/fake/runtime-data.js +367 -0
  57. package/dist/fake/state.js +67 -0
  58. package/dist/fake/workflow.js +364 -0
  59. package/dist/field-change.js +200 -0
  60. package/dist/field-families.js +896 -0
  61. package/dist/form-layout.js +111 -0
  62. package/dist/form-support.js +821 -0
  63. package/dist/goal-routes.js +468 -0
  64. package/dist/governed-execution.js +87 -0
  65. package/dist/human-summary.js +212 -0
  66. package/dist/identity.js +62 -0
  67. package/dist/intent/baseline.js +57 -0
  68. package/dist/intent/capabilities/bizservice.js +274 -0
  69. package/dist/intent/capabilities/businessrule.js +493 -0
  70. package/dist/intent/capabilities/datarule.js +187 -0
  71. package/dist/intent/capabilities/field.js +545 -0
  72. package/dist/intent/capabilities/form.js +136 -0
  73. package/dist/intent/capabilities/index.js +64 -0
  74. package/dist/intent/capabilities/listview.js +157 -0
  75. package/dist/intent/capabilities/model.js +100 -0
  76. package/dist/intent/capabilities/onlinejs.js +108 -0
  77. package/dist/intent/capabilities/report.js +355 -0
  78. package/dist/intent/capabilities/workflow.js +458 -0
  79. package/dist/intent/capability.js +6 -0
  80. package/dist/intent/cli.js +91 -0
  81. package/dist/intent/compare.js +56 -0
  82. package/dist/intent/compiler.js +79 -0
  83. package/dist/intent/dsl.js +129 -0
  84. package/dist/intent/plan-file.js +63 -0
  85. package/dist/intent/readback.js +65 -0
  86. package/dist/intent/schema.js +158 -0
  87. package/dist/intent/validation.js +30 -0
  88. package/dist/intent/yaml.js +315 -0
  89. package/dist/json-column.js +68 -0
  90. package/dist/lanes/app-contract.js +95 -0
  91. package/dist/lanes/app-coverage.js +16 -0
  92. package/dist/lanes/app.js +174 -0
  93. package/dist/lanes/apply-changes.js +231 -0
  94. package/dist/lanes/b2-registration-contract.js +292 -0
  95. package/dist/lanes/b2-registration-coverage.js +48 -0
  96. package/dist/lanes/b2-registration.js +1187 -0
  97. package/dist/lanes/businessrule-contract.js +232 -0
  98. package/dist/lanes/businessrule-coverage.js +16 -0
  99. package/dist/lanes/businessrule.js +221 -0
  100. package/dist/lanes/contract-support.js +65 -0
  101. package/dist/lanes/coverage-declaration.js +9 -0
  102. package/dist/lanes/datarule-contract.js +155 -0
  103. package/dist/lanes/datarule-coverage.js +19 -0
  104. package/dist/lanes/datarule-protocol.js +308 -0
  105. package/dist/lanes/datarule.js +818 -0
  106. package/dist/lanes/dictionary-contract.js +78 -0
  107. package/dist/lanes/dictionary-coverage.js +24 -0
  108. package/dist/lanes/dictionary.js +235 -0
  109. package/dist/lanes/environment-contract.js +70 -0
  110. package/dist/lanes/environment-coverage.js +14 -0
  111. package/dist/lanes/environment.js +163 -0
  112. package/dist/lanes/field-contract.js +223 -0
  113. package/dist/lanes/field-coverage.js +27 -0
  114. package/dist/lanes/field.js +374 -0
  115. package/dist/lanes/form-contract.js +97 -0
  116. package/dist/lanes/form-coverage.js +16 -0
  117. package/dist/lanes/form.js +185 -0
  118. package/dist/lanes/lane-ids.js +34 -0
  119. package/dist/lanes/list-view-contract.js +175 -0
  120. package/dist/lanes/list-view-coverage.js +20 -0
  121. package/dist/lanes/list-view-shapes.js +1207 -0
  122. package/dist/lanes/list-view.js +578 -0
  123. package/dist/lanes/meta-contract.js +85 -0
  124. package/dist/lanes/meta.js +255 -0
  125. package/dist/lanes/model-contract.js +168 -0
  126. package/dist/lanes/model-coverage.js +20 -0
  127. package/dist/lanes/model.js +986 -0
  128. package/dist/lanes/online-js-contract.js +99 -0
  129. package/dist/lanes/online-js-coverage.js +28 -0
  130. package/dist/lanes/online-js.js +127 -0
  131. package/dist/lanes/report-contract.js +144 -0
  132. package/dist/lanes/report-coverage.js +21 -0
  133. package/dist/lanes/report.js +476 -0
  134. package/dist/lanes/rule-graph.js +1846 -0
  135. package/dist/lanes/rule-lifecycle-contract.js +92 -0
  136. package/dist/lanes/rule-lifecycle-coverage.js +20 -0
  137. package/dist/lanes/rule-lifecycle.js +176 -0
  138. package/dist/lanes/runtime-data-contract.js +264 -0
  139. package/dist/lanes/runtime-data-coverage.js +25 -0
  140. package/dist/lanes/runtime-data.js +1054 -0
  141. package/dist/lanes/workflow-contract.js +223 -0
  142. package/dist/lanes/workflow-coverage.js +40 -0
  143. package/dist/lanes/workflow.js +1813 -0
  144. package/dist/online-js-layout.js +58 -0
  145. package/dist/online-js-source.js +276 -0
  146. package/dist/package-tool.js +51 -0
  147. package/dist/package.js +73 -0
  148. package/dist/plan.js +73 -0
  149. package/dist/read.js +144 -0
  150. package/dist/redact.js +28 -0
  151. package/dist/rule-support.js +587 -0
  152. package/dist/runtime-support.js +134 -0
  153. package/dist/server.js +92 -0
  154. package/dist/session-manager.js +30 -0
  155. package/dist/session.js +149 -0
  156. package/dist/skills.js +112 -0
  157. package/dist/support.js +98 -0
  158. package/dist/tool-types.js +127 -0
  159. package/dist/tools.js +59 -0
  160. package/dist/usage-log.js +197 -0
  161. package/dist/wire.js +287 -0
  162. package/dist/workflow-support.js +99 -0
  163. package/dist/write-lease.js +26 -0
  164. package/dist/write-lock.js +109 -0
  165. package/dist/write.js +176 -0
  166. package/dist/zip.js +156 -0
  167. package/docs/tool-surface-map.md +42 -0
  168. package/package.json +71 -6
  169. package/skills/omc-acceptance-criteria.md +47 -0
  170. package/skills/omc-business-configuration.md +257 -0
  171. package/skills/omc-capabilities.md +197 -0
  172. package/skills/omc-capability-scouting.md +55 -0
  173. package/skills/omc-config-draft-review.md +171 -0
  174. package/skills/omc-five-piece-flow.md +35 -0
  175. package/skills/omc-glossary.md +86 -0
  176. package/skills/omc-refusals.md +110 -0
  177. package/skills/omc-requirement-analysis.md +161 -0
  178. package/skills/omc-requirement-vocabulary.md +51 -0
  179. package/skills/omc-start-here.md +82 -0
  180. package/skills/omc-tool-selection.md +119 -0
  181. package/skills/omc-write-hazards.md +87 -0
package/package.json CHANGED
@@ -1,6 +1,71 @@
1
- {
2
- "name": "@stalfh233/omc-cli",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
1
+ {
2
+ "name": "@stalfh233/omc-cli",
3
+ "version": "0.4.0",
4
+ "description": "CloudPivot 8.6 configuration capability CLI — governed, fail-closed, coverage-manifest bounded.",
5
+ "type": "module",
6
+ "bin": {
7
+ "omc": "./dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "coverage",
12
+ "skills",
13
+ "docs",
14
+ "package.json",
15
+ "README.md",
16
+ "!dist/**/*.js.map",
17
+ "!dist/**/*.d.ts",
18
+ "!dist/**/*.d.ts.map"
19
+ ],
20
+ "exports": {
21
+ "./package.json": "./package.json"
22
+ },
23
+ "scripts": {
24
+ "build": "tsc --project tsconfig.build.json",
25
+ "lint": "tsc --noEmit --pretty false",
26
+ "typecheck": "tsc --noEmit",
27
+ "coverage:manifest": "tsx scripts/coverage-manifest.ts --write",
28
+ "coverage:check": "tsx scripts/coverage-manifest.ts --check",
29
+ "test": "npm run build && node --test --import tsx test/*.test.ts",
30
+ "verify": "npm run typecheck && npm run coverage:check && npm test",
31
+ "eval:call-face": "node --import tsx scripts/run-call-face-eval.ts",
32
+ "eval:intent-face": "node --import tsx scripts/run-intent-face-eval.ts",
33
+ "eval:discovery-cost": "node --import tsx scripts/run-discovery-cost-baseline.ts",
34
+ "eval:discovery-comparison": "node --import tsx scripts/run-discovery-cost-comparison.ts",
35
+ "conformance:read": "node conformance/run-conformance.mjs --layer read",
36
+ "conformance:write": "node conformance/run-conformance.mjs --layer write",
37
+ "conformance:frontend": "node conformance/frontend-acceptance.mjs",
38
+ "conformance:deep-config": "node conformance/deep-config-acceptance.mjs",
39
+ "test:live": "node --test --import tsx test/live-acceptance.test.ts",
40
+ "test:live-workflow": "node conformance/live-regression.mjs",
41
+ "test:live-permission": "node conformance/live-permission-acceptance.mjs",
42
+ "sandbox:dogfood": "node conformance/setup-dogfood-sandbox.mjs",
43
+ "payload:report": "tsx scripts/payload-report.ts",
44
+ "prepublishOnly": "npm run build"
45
+ },
46
+ "engines": {
47
+ "node": ">=20"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ },
52
+ "dependencies": {
53
+ "commander": "14.0.3",
54
+ "omc-core": "0.4.0",
55
+ "proper-lockfile": "4.1.2",
56
+ "write-file-atomic": "6.0.0",
57
+ "zod": "^3.23.8",
58
+ "zod-to-json-schema": "^3.25.2"
59
+ },
60
+ "devDependencies": {
61
+ "@types/node": "^22.0.0",
62
+ "tsx": "^4.19.0",
63
+ "typescript": "^5.6.0"
64
+ },
65
+ "license": "MIT",
66
+ "repository": {
67
+ "type": "git",
68
+ "url": "https://gitlab.h3yun.com/fuwenbin/oh-my-cpagents.git",
69
+ "directory": "packages/omc-cli"
70
+ }
71
+ }
@@ -0,0 +1,47 @@
1
+ ---
2
+ name: omc-acceptance-criteria
3
+ description: Decide whether a CLI change is accepted. Use before claiming done: readback, delivery-state, zero-residue, and negative-test gates.
4
+ ---
5
+
6
+ # Acceptance Criteria (验收标准)
7
+
8
+ A change is accepted only when every gate below holds.
9
+
10
+ ## Per-write
11
+
12
+ 1. **Environment permission** — `writable:true` admits the write; `writable:false` refuses before wire. A production write additionally carries `confirmProduction:true` and records `productionConfirmed:true`.
13
+ 2. **Authoritative readback** — the post-write read proves the intended state from the authoritative face (`field.list` published face, `form.get` published flags, `data.load` for M2 data, `onlinejs.compose` publishedHtmlJson + SHA-256 for Online JS). "Called without error" is not acceptance.
14
+ 3. **Delivery state recorded** — the `.omc/` artifact exists with `deliveryState: DELIVERED` and the environment fingerprint.
15
+ 4. **Zero residue** — fixtures removed and exact absence proven on every face (draft and published); final state CLEANED.
16
+
17
+ ## Per-session
18
+
19
+ 5. **`uncertain` resolved** — every uncertain outcome was re-discovered before any further write.
20
+ 6. **Secrets zero-echo** — no output, artifact, or error contains the credential or bearer token.
21
+ 7. **Boundaries respected** — every `capability-out-of-coverage` refusal was treated as a boundary, not retried through another tool.
22
+ 8. **Draft gate evidenced** — if the session performed any write, the report must attach each design draft it presented and the human's approval turn(s) (and every revision). A write with no preceding draft/approval record fails acceptance — read `omc-config-draft-review`.
23
+
24
+ ## Portal/DOM acceptance (opt-in, real platform)
25
+
26
+ Storage readback is NOT platform consumption. When the change is a form/design
27
+ artifact, the strongest acceptance is the opt-in live batteries — and they ARE
28
+ the "open a browser" step; do not report "no portal acceptance entry point":
29
+
30
+ - `npm run test:live` — designer canvas, condition panels **and the condition
31
+ dialog must render >=1 rule row** (a serialization can crash the formatter and
32
+ silently drop the row while the panel still says "Set"), portal fields (two
33
+ loads), list columns, list buttons, Online JS wrapper + `window.h3form` boot.
34
+ - `npm run test:live-workflow` — two-stage workflow + rule write-back via
35
+ `data.save(workflowCode)` → `workitem.list` → `data.submit` → `data.load`.
36
+ - `npm run test:live-permission` — node field permissions read from
37
+ `form/load.formPermission.dataPermissions` as a NON-admin participant (an
38
+ admin is force-granted `e:true`).
39
+
40
+ ## Negative baseline (must stay green)
41
+
42
+ - Read-only environment → `environment-write-disabled`, zero wire calls.
43
+ - Writable production without `confirmProduction:true` → `production-confirmation-required`, zero wire calls.
44
+ - Concurrent writes → serialized by the write lease (max 1 in flight).
45
+ - Blocked lane (e.g. `W2-permissions`) → refused with citation.
46
+ - Transport outage during a write → `uncertain` + `frozen`, never `ok`.
47
+ - Non-8.6 version (or missing version evidence) → writes fail closed.
@@ -0,0 +1,257 @@
1
+ ---
2
+ name: omc-business-configuration
3
+ description: 中文 CloudPivot 业务配置 runbook。用于把模型、字段、表单、视图、子表、流程权限、业务规则、按钮、在线 JS 和现存业务集成方法按需求落地并验收。
4
+ ---
5
+
6
+ # CloudPivot 业务配置 Runbook
7
+
8
+ 本技能讲业务需求如何落成配置包;底层 wire 形状和白屏陷阱见 `omc-write-hazards`。
9
+
10
+ ## 入口
11
+
12
+ ```bash
13
+ CLI="packages/omc-cli/dist/cli.js"
14
+ node "$CLI" commands --json
15
+ node "$CLI" describe <tool>
16
+ node "$CLI" contract <lane>
17
+ node "$CLI" call discover_environment --env <env> --args '{}'
18
+ node "$CLI" help omc-config-draft-review
19
+ node "$CLI" help omc-five-piece-flow
20
+ ```
21
+
22
+ ## 需求五维
23
+
24
+ 把需求拆成五个维度(注意:这是**需求维度**,不同于 `omc-five-piece-flow` 的"五件套"执行五阶段):
25
+
26
+ 1. **模型**:主对象、应用、业务 code。
27
+ 2. **字段**:类型、选项、关联目标、模型可空性。
28
+ 3. **表单与视图**:控件、子表 Sheet201、列表列、排序、筛选、按钮。
29
+ 4. **流程**:节点、参与人、每节点字段权限。
30
+ 5. **自动化**:规则、流程绑定、按钮、业务集成、在线 JS。
31
+
32
+ ## 标准顺序
33
+
34
+ **配置顺序以 `omc-config-draft-review` §8 为唯一真相**(模型 → 字段 → 发布 → 表单 → 视图 → 规则 → 流程);执行阶段见 `omc-five-piece-flow`。本 runbook 只补充业务侧要点:
35
+
36
+ 1. 读环境基线:应用、模型、字段、表单、视图、流程、规则、服务。
37
+ 2. 出中文草稿(`omc-config-draft-review`):环境、应用、资源 code、字段表、流程图、映射、按钮、清理方案。
38
+ 3. 取得用户明确确认;确认前不写环境。
39
+ 4. 需求包含运行行为时,用 CLI 真实触发;测试数据的保留/清理要写进草稿。
40
+
41
+ 完成标准:每项资源有 readback;每个运行写入有 delivery 状态;每个映射字段都有目标值;失败步骤、已完成步骤和清理动作可追踪。
42
+
43
+ ## 模型与字段
44
+
45
+ - 模型层字段默认可空;必填、只读、可见性在表单和流程节点配置。
46
+ - `propertyEmpty` 默认 `false`,不要把业务必填硬编码在数据模型。
47
+ - 关联单选优先读目标模型已发布字段,明确显示字段;无映射不要写空数组字符串。
48
+
49
+ ## 子表
50
+
51
+ 一个主表可以有多个子表,但子表不能嵌套子表。
52
+
53
+ 创建父字段:
54
+
55
+ ```json
56
+ {
57
+ "schemaCode": "expense",
58
+ "code": "expense_items",
59
+ "name": "费用明细",
60
+ "propertyType": "CHILD_TABLE",
61
+ "subFields": [
62
+ { "code": "item_name", "name": "费用项目", "propertyType": "SHORT_TEXT" },
63
+ { "code": "item_amount", "name": "金额", "propertyType": "NUMERICAL" },
64
+ { "code": "item_date", "name": "发生日期", "propertyType": "DATE" }
65
+ ]
66
+ }
67
+ ```
68
+
69
+ 子列像主表字段一样 CRUD,但 schemaCode 是父字段 code:
70
+
71
+ ```bash
72
+ omc call field.create --env local --args '{"schemaCode":"expense_items","code":"item_note","name":"明细备注","propertyType":"LONG_TEXT"}'
73
+ omc call field.update --env local --args '{"schemaCode":"expense_items","code":"item_note","name":"备注"}'
74
+ omc call field.delete --env local --args '{"schemaCode":"expense_items","code":"item_note"}'
75
+ omc call field.publish --env local --args '{"schemaCode":"expense"}'
76
+ ```
77
+
78
+ 父表单重建后,Sheet201 控件应有业务子列,子列 key 不应出现在普通 `viewJson`。
79
+
80
+ 声明式面同样支持子表(`intent.yaml`),子列写在父字段的 `subFields` 下;子列只接受标量族,不能嵌套子表/关联/公式:
81
+
82
+ ```yaml
83
+ models:
84
+ - code: expense
85
+ name: 费用报销单
86
+ fields:
87
+ - code: expense_items
88
+ name: 费用明细
89
+ type: CHILD_TABLE
90
+ subFields:
91
+ - code: item_name
92
+ name: 费用项目
93
+ type: SHORT_TEXT
94
+ - code: item_amount
95
+ name: 金额
96
+ type: NUMERICAL
97
+ ```
98
+
99
+ `intent plan/apply/readback` 会把子列的缺失、改名、类型漂移当成独立差异(`subfield:` 资源);新增子列自动编译成 `field.create --schemaCode <父字段 code>` 并触发模型级 `field.publish`。父字段本身改名仍用 `field.update`,`field.update` 不接受 `subFields`。
100
+
101
+ `intent apply` 默认在交付后自动做一次最终读回等价确认:等价则 `verification.status:"ok"`;不等价则整体 `refused` + `blocker:"intent-readback-mismatch"`(exit 12),**绝不当作成功**——按 `verification.differences` 定位后重新 `intent plan`,不要盲重试。`--no-verify` 可关闭该确认(只在你已单独跑 readback 时)。
102
+
103
+ 业务规则也进了声明式面(`models[].rules[]`)。常用数据事件规则用紧凑 `actions`,编译器合成 nodeGraph;复杂图用 `nodeGraph` 原样透传(二选一):
104
+
105
+ ```yaml
106
+ rules:
107
+ - code: Update # 平台预置码(Create/Update/Delete…)或自定义码
108
+ name: 更新归档
109
+ enabled: true # true → 额外 rule.enable(publish+启用);false → 已启用则 rule.disable
110
+ actions:
111
+ - type: UPDATE
112
+ target: archive_model # 同模型可省略 target(默认本模型);跨模型才必须写
113
+ filter:
114
+ - field: source_no
115
+ from: doc_no # from = 动态(触发字段);或比较键:equals/notEquals/gt/gte/lt/lte: <标量>
116
+ set:
117
+ - field: amount
118
+ from: total # from = 动态;也可 value: <字面量>
119
+ ```
120
+
121
+ - **每个 filter 项必须有且只有一个条件来源**:`from`(动态 EQ)或一个比较键(`equals`/`notEquals`/`gt`/`gte`/`lt`/`lte` + 标量)。缺来源 `intent-rule-leaf-source-missing` 拒绝;**绝不**静默成 `EQ null`。
122
+ - 动作节点的条件分「定位数据」与「执行门」两类,**别混**(详见下「规则图的触发条件」)。
123
+ - **跨模型写(`targetObjectCode`≠规则模型)平台支持、可运行时生效**(2026-09-28 真机复核)。两个前提:① 承载它的规则必须真的触发——`Create` 规则在提交时触发;`Update` 规则只在 `data.update` 触发,**submit 不执行它**(放进 `Update` 是典型静默空转,lint 警告 `rule-graph-cross-model-update-trigger-inert`;也可绑定流程事件如 `end`)。② 目标行必须已提交——目标查询不匹配 DRAFT 行,`data.save` 未 submit 的行不回写。
124
+ - 关联字段:`type: WORK_SHEET` + `relativeCode: <目标模型>` + `options.displayField`,与 `field.create` 行形状一致。(键名是 `relativeCode`,wire 键 `relativeSchemaCode`,别混。)
125
+ - 节点显示名用 activity 级的 `name`(`participant.name` 只作参与者说明,平台不认作节点名;`{type: Originator, name: 部门负责人}` 会被工具提升为节点名)。
126
+ - **字段级数据规则**(`models[].datarules[]`,`dataRuleType` 1校验/2计算/3拼接/4必填/5只读)——注意是 `dataRuleType`(不是 `type`):
127
+ ```yaml
128
+ datarules:
129
+ - { propertyCode: order_note, dataRuleType: 4, options: { requiredFormula: '{amount} 大于 {"valueType":"custom","value":5000}' }, name: 金额超5000说明必填 }
130
+ ```
131
+ ⚠️ **type 3/4/5 不驱动门户表单控件**(真机复核):平台存成 bizdatarule,只镜像进控件 `historyOpt`,运行时门户读的是控件 `options`。门户条件(如「金额>5000 时必填」)必须写在 `fields[].options`(`requiredFormula`/`readonlyCondition`/`shortTextStitch`);写进 `datarules[]` 设计器可见但门户不拦(validate/plan 给 `datarule-not-portal-facing` 警告)。datarule 只用于服务端引擎(校验/计算)。
132
+
133
+ - 规则排在字段发布之后(编译器按能力排序:先建全部模型/字段,再跑规则)。
134
+ - `rule.save` 只写草稿;`enabled` 由 `rule.enable` 保证(publish+启用)——readback 用 `enabled` 和**语义图摘要**(忽略画布几何)判等价。
135
+
136
+ ## 表单与视图
137
+
138
+ - 新字段加入已有表单:`form.draft --rebuild`,然后 `form.publish`。
139
+ - rebuild 会保留已识别的关系映射、显示和布局 options;Sheet201 columns 按最新子表字段刷新。
140
+ - **配置列表视图用 `listview.configure`(省略 `code` 即平台自动生成的默认视图 code=schemaCode),不要先 `listview.create`——那会多出一个视图。** 只有确实要第二个视图才 create;两者职责分开。
141
+ - 数值控件:`scale` 是小数位数(0=整数,1=1位,2=2位…);「金额两位小数」用 `scale:2`。列表列 displayFormat 由 scale 推导。
142
+ - **列表列只放业务字段**:平台 `listview.create` 会预置系统列(`name/creater/createdTime/sequenceNo`)和一条 `createdTime` 默认筛选;intent 的 `fieldCodes` 是权威集合,编译器用 `replaceColumns:true + hideDefaultSystemFields:true + conditions:[]` 清掉预置项。要展示某系统列/筛选就显式点名。
143
+ - 筛选条件默认显示:`conditions[].visible` 不传也应为 true。
144
+ - 配置默认视图后即可用 `data.list`;否则部分 8.6.26 读面业务列可能为 null,单行用 `data.load` 核对。
145
+ - 读回视图用 `listview.get`(默认回列/排序/条件/动作紧凑清单)与 `listview.list`。
146
+
147
+ ## 流程字段权限
148
+
149
+ 新增字段后,必须重新检查每个参与节点的 `propertyPermissions`:
150
+
151
+ - 填写节点:需求要求的字段可编辑,必要字段必填。
152
+ - 审批节点:通常 `visible:true, editable:false, required:false`。
153
+ - 不需要展示的字段明确 `visible:false`。
154
+
155
+ **怎么配**(没有单独的权限工具,别把「找不到入口」当不支持→假阻塞):`workflow.get_draft --full` 读节点正文,改目标
156
+ `ParticipantActivity.propertyPermissions[]`(`{propertyCode, visible, editable, required, summary, subPropertyPermissions}`),
157
+ 用 `workflow.update` 原样回写,再 `workflow.publish`。**要生效必须 `summary:true`**(只有它进运行时 `activitySummaries`;
158
+ 否则 `form/load` 的 `formPermission.dataPermissions` 回退默认,读不到你的 `editable:false`);子表列用 `subPropertyPermissions`。
159
+ 验收用 `npm run test:live-permission` + **非管理员参与者**(管理员会被后端强制 `e:true` 掩盖)。
160
+
161
+ 声明式流程(intent)的 `workflow.template` 用 **`activities` + `routes`**(不是 `nodes`/`edges`):活动 `{id, type: START|END|PARTICIPANT|…, participant?}`,路由 `{preNode, postNode}` 必须指向已声明活动 code;`workflow.update` 只从 `activities` 读节点,写 `nodes` 会在 apply 时 `rules[0] references an unknown activity`(validate 会提前拦)。
162
+
163
+ 示例:
164
+
165
+ ```text
166
+ 开始 → 填写申请单 → 部门审批 → 财务审批 → 结束
167
+ ```
168
+
169
+ 如果环境里存在测试节点,先确认保留还是删除,不要静默覆盖。
170
+
171
+ ## 业务规则
172
+
173
+ **先选对机制,别一律上规则图**(三者代价差很大):
174
+
175
+ | 需求形态 | 用哪个 | 入口 |
176
+ | --- | --- | --- |
177
+ | 条件必填 / 条件只读 / 恒只读(表单交互层) | 字段 `options` | `field.update --example form-conditional-required` / `form-conditional-readonly` / `form-always-readonly` |
178
+ | 服务端字段级校验 / 计算 / 拼接 / 显示(type 1..5) | 数据规则 | `datarule.create`(字段级引擎) |
179
+ | 数据事件自动化(创建/更新时改字段、调服务、发起流程) | 规则图 | 本节 `rule.save`(`--example standard-business-rule-graph`) |
180
+
181
+ 「超过某值必填 / 等于某值只读」= **字段 options**,**不要**建规则图、也**不要**用 `datarule.create`
182
+ (实测:`datarule` type3/4/5 不会让门户表单控件变必填/只读,且符号式经 `historyOpt` 镜像会让表单渲染崩溃;
183
+ 平台的 bizdatarule 会被镜像进表单控件 `historyOpt`,而设计器/运行时读的是控件 `options`)。
184
+
185
+ ### 条件式(必填/只读/显示)怎么写
186
+
187
+ - **恒必填**:`requiredFormula: "true"`(字面量);**条件必填**:`requiredFormula: "{触发字段} 操作符 {\"valueType\":...,\"value\":...}"`。
188
+ - 操作符用**中文**(设计器产出):等于/不等于/大于/小于/大于等于/小于等于/包含/包含全部/等于任意一个/为空/不为空;也接受符号 `== != > >= <= Contains IsEmpty`。为空/不为空**不带值**。
189
+ - 写完后 `field.publish` → `configure_form`(同步进控件)→ **门户打开表单改触发字段的值**,断言目标控件变 `required` / `disabled`(存储回读不算验证)。
190
+ - 恒只读:`readonlyFormula: true`。
191
+
192
+ ### 规则图的触发条件(关键)
193
+
194
+ 规则支持**触发条件**,不要用「两条无条件规则」表达互斥结果:
195
+
196
+ - **节点级条件有两大类,别混**(各节点类型都可能有,完整字段/样例见 `describe rule.save --full` 的 RULE_NODE_TEMPLATES):
197
+ - **定位要操作哪些数据**(`filterCondition`:叶 `targetSchemaDataItem`+`ruleConditionType`):UPDATE=改哪条(空=整表)、DELETE=删哪条、CREATE=存在符合则不新增+`findMainData`、QUERY=`targetConditionGroups`、**ASSIGN=在输入数据源匹配要取值的行(不是执行门!)**。⚠️ 非唯一字段(金额等)会命中**多条**;改「当前/关联那一条」用唯一键(`id` 或 `from`)。`actions.filter` 表达这类(同模型省略→默认 `id=id`;跨模型省略 fail-closed)。
198
+ - **执行门 / 满足条件触发**(`dataCondition`,BIZ_ACTION 用 `execConditionGroups`):**与定位两码事**——决定「要不要执行」,不决定「改哪条」。compact `actions.when` 表达 UPDATE 执行门(叶 `currentSchemaDataItem`+`ruleDataConditionType`);其它节点用 `nodeGraph`。**条件改自身**:`when: [{field: amount, gt: 10000}]` + 省略 `filter`(默认 `id=id`)——别把条件写进 `filter`,那会改掉所有符合的行(bench66 多行互覆)。
199
+ - 子表定位 `filterSubCondition`;子表触发范围 `childTriggerConditionType∈ADD/MODIFY/DELETE`。
200
+ - **触发时机**:数据事件(`Create`/`Update`/`Delete`)**只分发到平台预置 code 行**;流程相关用预置 `Available`(流程生效)/`Cancel`(流程作废),或流程事件绑定 `workflow.bindRule` 的 `end`/`cancel`/`start`/`activate`。
201
+ - **预置规则身份不可改**:`Create`/`Update`/`Delete`/`Load`/`GetList`/`Available`/`Cancel` 名称由平台维护(`Create`=数据新增);传 `name` 不生效(仅自定义规则名称可改),可改的是节点名 `nodeName`。
202
+ - **流程事件只绑自定义规则**:`workflow.bindRule` 的 `ruleCodes` 只能给自定义 code——设计器的事件规则选择器不提供预置触发行(绑 `Create` 到 `end` 非法,工具 fail closed)。要「审批通过后执行某逻辑」:新建自定义规则承载动作节点再绑 `end`。
203
+ - **审批通过/驳回回写**:通过绑 `end`(或 `Available`)、驳回绑 `cancel`(或 `Cancel`)——**不要**把两条各自 FIXED 赋值的规则都绑到 `endEventHandler`(两条都会执行、后者覆盖前者;工具会在 `bizActions.length>1` 时回读 `advisory` 提醒)。真实生产只在 `endEventHandler` 绑**一条**多分支规则图。
204
+
205
+ 规则图需要显式:
206
+
207
+ - `ruleCode`、名称、触发方式
208
+ - 每个节点 `nodeName`
209
+ - `nodeType`、路由、目标模型
210
+ - 主表/子表 `findMainData`
211
+ - 每个映射的 source/target 字段:**新增/更新节点的字段映射 = `dataActions`**(每目标字段一条叶:`{targetDataItem, ruleValueType:"DYNAMIC"/"FIXED", value:""/字面量, ruleActionType:"EQUALS", currentDataItemValue:"<来源字段>"}`)。**`execFormMapping` 只是展示开关,不是映射来源**——只写 `execFormMapping:true` 不写 `dataActions`,「主表字段值设置」是空的、新增行业务字段全 null(工具对 `execFormMapping:true` 缺 `dataActions` fail closed `rule-graph-create-mapping-missing`)。**写跨表节点前先 `rule.get` 读一条真实同型规则(如 `purchase_request`/`Create`)当基线**,不要从模板推断。
212
+
213
+ 流程结束后新增目标表单,配置发布后要真实跑完流程,再读目标表单每个字段(`data.load`,不是 `data.list`——后者只投影列表列);只看到规则 `ENABLED` 不等于映射成功。
214
+
215
+ ## 业务集成
216
+
217
+ 优先复用现存 service/method,不做无必要的部署:
218
+
219
+ ```bash
220
+ omc call service.get --env local --args '{"serviceCode":"omc_demo_restful"}'
221
+ ```
222
+
223
+ - **新写一个接口 ≠ 新建一个服务**。同一个服务下可以挂多个方法:新服务用 `service.register`(`serviceCode` 已存在会 `duplicate-service` 拒绝),**往已有服务加方法用 `method.create`**(服务不存在 → 拒绝并提示先用 `service.register`;方法已存在 → 拒绝并提示改用 `method.update`)。不要为加一个方法而删服务重建(会连带丢掉服务的其它方法与规则绑定)。
224
+
225
+ BIZ_ACTION:
226
+
227
+ - 先读方法输入/输出参数面。
228
+ - `codeType: 1` 的 PROPERTY 输入:`bizCode` 是源字段 code,`propertyName` 是显示名,`serviceMethodParameterCode` 必须命中方法参数。
229
+ - **常量入参用 `codeType: 0`(CONST)**(如固定请求头 `X-LowCode-Corpid`):值可放 `bizCode`,也可放 `value`(工具会自动移入 `bizCode`)。平台 CONST **只读 `bizCode`**——`value`/`expressionValue` 原样存着的话,运行时取到的是字面 `null`。
230
+ - 参数面每参数必带 `bizPropertyType`(参数类型),否则业务规则按类型匹配字段会失败、映射不到(缺失即拒绝);`externParameterType`/`description` 工具补齐。**返回值参数默认不必填(`required:false`),入参按需必填**——返回值声明为必填会经规则 designer 的 `required` 镜像强制每条输出映射也必填,是绑定摩擦的常见来源。
231
+ - `rule.save` 自动补 `serviceName`/`serviceMethodName`/节点 `nodeCategory:"actionNode"`/映射元素 `index`(弹窗异步加载,稍候再判空)。
232
+ - 配规则后读回 methodMapping,再用按钮或流程实际触发一次。
233
+ - 服务、方法、参数不确定时拒绝猜,先读证据。
234
+
235
+ ## 按钮与在线 JS
236
+
237
+ - 直接执行规则:`useLocation: ROW` + `operateType: WITH_OUT_VIEW`。
238
+ - `WITH_VIEW` 是打开表单。
239
+ - FLOW 按钮需要 workflowCode;CLI 会补安全的 actionConfig。
240
+ - **在线 JS 分两条**:本 CLI 只做**发布与回读**——用 `onlinejs.compose` 把已定稿的 `source` 组合进平台 skeleton 的 `customScript` 再 publish,回读 `publishedHtmlJson`+SHA-256。**脚本内容的编写/增量合并不在本 CLI**:若当前项目自带在线 JS 编写规范(例如其 `.cpdocs`/技能或项目文档),遵循它;否则向用户/设计者索取已定稿的 `source`。不要在 omc 侧手写或臆造 JS 逻辑。
241
+
242
+ ## 运行验收与清理
243
+
244
+ 运行测试前在草稿里列出:
245
+
246
+ - 测试输入值
247
+ - 预计生成的记录/调用
248
+ - 每个字段的验收值
249
+ - 清理哪些测试数据,保留哪些配置
250
+
251
+ 推荐顺序:
252
+
253
+ ```text
254
+ 配置读回 → CLI 运行触发 → workitem/data/service 读回 → 比较字段 → 清理测试数据
255
+ ```
256
+
257
+ 浏览器不是常规验收步骤;只有用户报告 UI 回归时才做专项诊断。
@@ -0,0 +1,197 @@
1
+ ---
2
+ name: omc-capabilities
3
+ description: The OMC capability catalogue — what each capability can do, its tools, recipes, and boundaries. Use to answer "can OMC/platform do X?" and to find the tool for X before discovery.
4
+ ---
5
+
6
+ # Capability Catalogue (能力总表)
7
+
8
+ The one place that says **what OMC can configure and what each capability
9
+ covers**. Read it when you need to answer "能不能做 X?/ 用哪个能力?" yourself —
10
+ before you escalate the question to the user, and before you decide "X 要二开".
11
+
12
+ This topic is the **prose authority** for capability coverage; `omc capabilities`
13
+ / `omc next` / `omc capability <id>` are its machine-readable projection over the
14
+ same 15 capabilities (a `verify` test fails if the two drift). A concrete wire
15
+ shape is always reached by `omc describe <tool> --example <recipe>` — this
16
+ catalogue only names the tool and the recipe, never re-specifies the payload.
17
+
18
+ **How to read it (progressive disclosure):** scan the 能力索引 table, then read
19
+ only the section for the capability you need —
20
+ `omc help omc-capabilities --section "<能力>"`. Do not load every section.
21
+
22
+ ## 能力索引
23
+
24
+ | 能力 | 一句话 | 能做哪些事(需求线索) | 读哪节 |
25
+ | --- | --- | --- | --- |
26
+ | 环境治理 `environment` | 环境发现/指纹/就绪 | 环境、指纹、版本、连接、登录、就绪、发现 | [环境治理](#环境治理-environment) |
27
+ | 应用 `app` | 应用包生命周期 | 应用、门户、分组、app 建删移 | [应用](#应用-app) |
28
+ | 数据字典 `dictionary` | 字典与字典记录 | 字典、选项来源、树型、键值、字段下拉来源 | [数据字典](#数据字典-dictionary) |
29
+ | 业务模型 `model` | 模型生命周期 | 模型、对象、表、主数据、改名、物理删除 | [业务模型](#业务模型-model) |
30
+ | 字段 `field` | 字段族 + 子表 + **计算字段** | 字段、属性、子表、明细、下拉、单选、多选、附件、人员、部门、日期、数值、关联、**公式/计算/求和/汇总/合计/回主表** | [字段](#字段-field) |
31
+ | 默认表单 `form` | 表单布局与发布 | 表单、页面、布局、控件、只读、显示 | [默认表单](#默认表单-form) |
32
+ | 列表视图 `listview` | 列表表头与列 | 列表、视图、查询列、筛选、表头、甘特 | [列表视图](#列表视图-listview) |
33
+ | 字段级规则 `datarule` | 字段级控件规则 | 字段级规则、控件规则、校验规则、计算拼接、显示规则、条件必填/只读/显示 | [字段级规则](#字段级规则-datarule) |
34
+ | 业务规则 `businessrule` | 图形规则图 + **定时任务** | 业务规则、触发器、规则图、事件、BRANCH、BIZ_ACTION、**定时任务/定时/每天/周期/调度** | [业务规则](#业务规则-businessrule) |
35
+ | 规则生命周期 `rule-lifecycle` | 规则启停删 | 启用规则、停用规则、删除规则、规则启停 | [规则生命周期](#规则生命周期-rule-lifecycle) |
36
+ | 流程模板 `workflow` | 审批流程模板 | 流程、工作流、审批、节点、待办、流转、参与人、审批人 | [流程模板](#流程模板-workflow) |
37
+ | 表单在线 JS `onlinejs` | 表单脚本发布/回读 | 在线js、脚本、联动、onload、onvalidate | [表单在线 JS](#表单在线-js-onlinejs) |
38
+ | 业务集成 `bizservice` | 集成服务与方法 | 集成、接口、服务、回调、对接、外部系统、datasql、restful | [业务集成](#业务集成-bizservice) |
39
+ | 报表 `report` | 报表页 + BI 图表(**仅显式要求时**) | 报表、图表、看板、bi、dashboard(用户点名的才做) | [报表](#报表-report) |
40
+ | 运行数据 `data` | 业务记录读写 | 运行数据、提交数据、保存记录、查记录 | [运行数据](#运行数据-data) |
41
+
42
+ **边界**(不在覆盖内)见 [边界](#边界boundaries)。**落点判据**(配置 vs 二开)
43
+ 的唯一权威源是 `cpdocs-guide` 的「落点」。
44
+
45
+ ---
46
+
47
+ ## 环境治理 `environment`
48
+
49
+ - **能做哪些事**:读环境指纹与版本桶(决定证据版本);就绪自检(登录/许可证/最小路径),写入开关与生产授权在 `omc setup`。
50
+ - **工具**:`discover_environment`、`environment.fingerprint`
51
+ - **边界 / 陷阱**:只读;不进 intent(用 `omc setup` / `discover_environment`)。写前一律先确认环境真相。
52
+
53
+ ## 应用 `app`
54
+
55
+ - **能做哪些事**:列出应用包、创建、改名/分组移动、删除(删除级联其模型)。
56
+ - **工具**:`app.list`、`app.create`、`app.update`、`app.delete`
57
+ - **边界 / 陷阱**:环境已带默认 `applicationCode`,建模**不必**先建应用;未进 intent,用 `omc call app.*`。
58
+
59
+ ## 数据字典 `dictionary`
60
+
61
+ - **能做哪些事**:字典与字典记录全生命周期(键值型/树型、启停);作为选择字段的选项来源;字典分类。
62
+ - **工具**:`dictionary.list`、`dictionary.type`、`dictionary.names`、`dictionary.get`、`dictionary.records`、`dictionary.save`、`dictionary.status`、`dictionary.usage`、`dictionary.parent`、`dictionary.classes`、`dictionary.class.save`、`dictionary.class.delete`
63
+ - **recipe**:`omc describe dictionary.save --example dictionary-key-value`
64
+ - **边界 / 陷阱**:选择字段有三种选项来源——`custom` / `dictionary` / `businessModel`;关联单选/多选支持 `searchFormula` 与 `conditions` JSON 筛选。
65
+
66
+ ## 业务模型 `model`
67
+
68
+ - **能做哪些事**:模型创建、改名、物理删除(`absent:true` 回读)、存在性、批量删除、摘要;一次建模型+字段+表单用 `configure_model`。
69
+ - **工具**:`model.list`、`model.inspect`、`model.create`、`model.delete`、`model.deleteMany`、`model.setSummary`、`model.update`、`configure_model`
70
+ - **recipe**:`omc describe configure_model --example model-with-fields-form`
71
+ - **边界 / 陷阱**:`model.inspect <schemaCode>` 一次拿全字段/表单/列表/规则/流程摘要,别逐面 6 次调用。**保留 code**:字段 code 用 `name` 会被平台占用,须避开。**每个模型都必须建并发布默认表单**——只建模型不建/不发布表单则无法录入查看(`configure_form` 或 `form.draft(rebuild:true)` + `form.publish`)。**「汇总/统计/按月」类需求**:常见做法是**一张汇总表**(独立业务模型,如 `x_monthly_summary`)接住结果,用定时任务/规则把源数据汇总写进去——**但这按需求定**,不是写死的规则。需求确认时把"汇总表"作为常规选项提出来跟用户确认,别默认往报表或二开上引。
72
+
73
+ ## 字段 `field`
74
+
75
+ - **单据号/自动编号(原生,勿二开)**:单据号是表单 **Serial Number 控件**(字段类型 100 SequenceNo)的 `options.seqNoSetting` 分段构建器(CONSTANT/DATE/SEQNO/DATAITEM/UID 段),SEQNO 段 `resetDate:DAY/MONTH/YEAR` 原生按期重置——`describe field.update --example field-serial-number`。**不要落 SequenceService SPI 二开**(r5-crm 实证重造轮子);编号生成时机=submit(`data.save` 不生成)。
76
+
77
+ - **能做哪些事**:字段族全链 create→publish→表单绑定;**CHILD_TABLE 子表**(子列是 schemaCode=父字段 code 上的普通字段);**计算字段**(默认用普通字段 + 「计算规则」,见下)。
78
+ - **工具**:`field.list`、`field.create`、`field.update`、`field.publish`、`field.delete`
79
+ - **recipe**:
80
+ - `omc describe field.create --example numeric-two-decimals`(数值 + scale)
81
+ - `omc describe field.create --example dictionary-backed-single-select`
82
+ - `omc describe field.create --example minimal-child-table`(子表 + 标量子列)
83
+ - `omc describe field.create --example business-model-dropdown`
84
+ - **边界 / 陷阱**:
85
+ - **计算类需求默认走「普通字段 + 计算规则」,不要建「计算公式」字段类型(FORMULA)**:建一个**数值/单行文本**业务字段,再配一条**字段级计算规则**(`datarule.create` `dataRuleType:2`,`options.shortTextStitch={"formula","editorText","editorMark"}`)。理由:平台约定用正常业务字段承载、顺带配计算规则(真机 2026-10-08 production 表单核验 + 设计器弹窗显示)。「计算公式」字段类型不是默认,仅当确需一列专用公式时才用。
86
+ - **计算规则公式引用**:同类字段裸 `{字段code}`(`{a}+{b}`);**子表列用 `{子表字段code.子列code}`**(`{Sub_item_information_table.taxInclusiveAmount}`);子表求和 `SUM({子表.子列})`;支持 `IF(cond,a,b)`、`CASE(v,c1,r1,c2,r2)`、`VALUE()`、`AND`、比较 `=`、字符串字面量与运算符空格。recipe:`omc describe datarule.create --example field-compute-rule|field-compute-subtable-sum|field-compute-child-column`。
87
+ - 计算由**门户前端**执行,API(`data.save/update`)不回填/重算——写测试数据带预算值,正确性人工前台确认。(FORMULA 字段类型仍受支持,但非默认。)
88
+ - 计算由**门户前端**执行,API(`data.save/update`)不回填/重算——写测试数据带预算值,正确性人工前台确认。
89
+ - 子表列支持标量族 + WORK_SHEET 关联列(需 `relativeCode`+options);**嵌套子表 / MULT_WORK_SHEET / RELEVANCE_DATA 不覆盖**。
90
+
91
+ ## 默认表单 `form`
92
+
93
+ - **能做哪些事**:表单 draft-first 布局、发布、`publishedHtmlJson` 绑定读回;把已发布字段绑进默认表单。
94
+ - **工具**:`form.get`、`form.draft`、`form.publish`、`configure_form`
95
+ - **recipe**:`omc describe configure_form --example publish-default-form`
96
+ - **边界 / 陷阱**:默认表单已存在,用 `configure_form`/`form.draft(rebuild)` 改它,不要新建。
97
+ - **每个模型交付前其默认表单必须已发布**:只建草稿=用户无法录入/查看。用 `configure_form` 或 `form.draft(rebuild:true)`+`form.publish` 发布。
98
+ - **发布态以 `form.get` 的 `published`/`existDraft` 布尔为准**,不要看 `publishedControlCodes` 是否非空(草稿字段也非空,会误判)。交付前列出每个模型的 `form.get.published` 核对。
99
+ - **写业务数据的前提是先发布模型+表单**:正确顺序 = 建模型 → 发布字段(`field.publish`)→ 建并**发布**默认表单(`form.publish`)→ 才 `data.save`/`data.submit`。不要在建/未发布状态下写业务数据。
100
+
101
+ ## 列表视图 `listview`
102
+
103
+ - **能做哪些事**:视图表头列、排序、筛选条件生命周期(create/configure/delete)。
104
+ - **工具**:`listview.get`、`listview.list`、`listview.create`、`listview.configure`、`listview.delete`
105
+ - **recipe**:`omc describe listview.configure --example configure-default-list`
106
+ - **边界 / 陷阱**:默认视图已存在,`listview.configure` 省略 code 即配置默认视图。**按字段分组(queryLayer)未取证**——别猜写。
107
+
108
+ ## 字段级规则 `datarule`
109
+
110
+ - **能做哪些事**:字段级数据规则(bizdatarule)create/update/delete;条件必填(type4)、条件只读(type5)、条件显示(type3)、计算拼接(type2)等,按平台校验器闭环。
111
+ - **工具**:`datarule.list`、`datarule.create`、`datarule.update`、`datarule.delete`
112
+ - **recipe**:
113
+ - `omc describe datarule.create --example datarule-conditional-required`
114
+ - `omc describe datarule.create --example datarule-conditional-readonly`
115
+ - `omc describe datarule.create --example datarule-conditional-display`
116
+ - **边界 / 陷阱**:目标字段必须已发布;同一字段多条规则时 update/delete 必须带 `dataRuleType` 去歧义。
117
+
118
+ ## 业务规则 `businessrule`
119
+
120
+ - **能做哪些事**:图形规则图(nodeGraph)——数据事件(Create/Update/Delete)触发、按钮/流程触发、动作节点(UPDATE/CREATE/DELETE/QUERY/ASSIGN/MESSAGE/BIZ_ACTION/GET_LIST…)、BRANCH 条件分支、**定时任务 TIMING_TASK**(每天/周期,SCHEDULER 节点)。
121
+ - **工具**:`rule.list`、`rule.get`、`rule.save`、`rule.node.update`
122
+ - **recipe**:
123
+ - `omc describe rule.save --example standard-business-rule-graph`
124
+ - `omc describe rule.save --example business-rule-branch-conditional`
125
+ - `omc describe rule.save --example rule-timing-task`(**每天/周期定时执行**)
126
+ - **边界 / 陷阱**:
127
+ - **「每天定时执行」= 定时任务 TIMING_TASK,是平台原生配置,不是外部定时器、不是在线 JS、无需二开**;`nodeGraph.bizRuleType:2` + SCHEDULER 节点 + `nodeGraph.schedulerSetting`。
128
+ - 数据事件只分发到平台预置 code 行(Create/Update/Delete);自定义 ruleCode 需按钮/流程/定时/显式触发。
129
+ - 保存 ≠ 可见,需 `rule.enable`(见 rule-lifecycle;绑流程事件前必须 enable,否则运行时 Business rule does not exist——r3-wms 实测)。BRANCH 多出口是「全部命中即走」,分级互斥用嵌套 BRANCH。
130
+ - **无存在性/计数判定原语**:BRANCH 不能按「QUERY 是否返回行」分支(PRE_OUT 分支不接收 QUERY 空结果,r3-wms 实测)。因此**硬拦保存做不到**(重复校验只能降级为打标,且**规则图内 QUERY→UPDATE 打标会静默空转**(8.6.26 UPDATE 的 inputParam 只认触发行 `_input`,`_QN_output` 引用被忽略——r4-fin 双跑实证 2026-10-09)。唯一可靠路径=改写预置 Create 规则挂 BIZ_ACTION 自调二开 markDuplicates(见 `describe rule.save --example data-duplicate-flag`))。
131
+
132
+ ## 规则生命周期 `rule-lifecycle`
133
+
134
+ - **能做哪些事**:业务规则的启用、停用、批量停用、删除。
135
+ - **工具**:`rule.enable`、`rule.disable`、`rule.delete`、`rule.disableMany`、`configure_rule`
136
+ - **边界 / 陷阱**:`enabled` 是运行时真相,`status` 可能滞后。`rule.disableMany` 默认含预置行,`customOnly:true` 只停自定义。
137
+
138
+ ## 流程模板 `workflow`
139
+
140
+ - **能做哪些事**:流程模板 get_draft/get_published、create、update、publish、bindRule(事件处理器规则绑定)、delete、workitem.list;参与人用组织对象。
141
+ - **工具**:`workflow.get_draft`、`workflow.get_published`、`workflow.validate`、`workflow.create`、`workflow.update`、`workflow.publish`、`workflow.bindRule`、`workflow.delete`、`configure_workflow`、`workitem.list`、`org.role.list`、`org.department.list`、`org.user.search`
142
+ - **recipe**:`omc describe workflow.bindRule --example workflow-handler-binding`
143
+ - **边界 / 陷阱**:greenfield 首版;`publish`/`bindRule` 不得在 `ValidateMessage[]` 拒绝时报告成功。运行时 workitem(提交/审批)走 `data.submit`。
144
+
145
+ ## 表单在线 JS `onlinejs`
146
+
147
+ - **能做哪些事**:表单在线 JS 的 compose 六元素骨架、`draftHtmlJson.customScript`、发布与 SHA-256 回读(脚本**编写**不在 CLI 范围,遵循项目在线 JS 规范或向用户索取定稿 source)。
148
+ - **工具**:`onlinejs.compose`
149
+ - **边界 / 陷阱**:仅表单在线 JS;后端在线开发(`/api/api/programming` Java 源码)用二开扩展包,不在 CLI 范围。
150
+
151
+ ## 业务集成 `bizservice`
152
+
153
+ - **能做哪些事**:业务服务与方法注册(RESTFUL/DATA_SQL/DATA_TABLE/SAP/KAFKA/SOAP)、方法增改删、分类/连接池、导入导出、设计器测试。
154
+ - **工具**:`service.get`、`method.get`、`method.update`、`method.create`、`method.delete`、`service.category.list`、`service.category.create`、`service.category.update`、`service.category.delete`、`service.dbconnpool.list`、`service.dbconnpool.create`、`service.dbconnpool.update`、`service.dbconnpool.delete`、`service.adapter_config`、`service.table_list`、`service.table_sql`、`service.register`、`service.update`、`service.delete`、`service.export`、`service.check`、`service.import`、`method.test`
155
+ - **recipe**:`omc describe service.register --example restful-query-service`
156
+ - **边界 / 陷阱**:方法 `configJson` 走 AES-128-ECB;**二开接口 = 扩展模块写 REST 接口 + RESTFUL 服务指向它**(页面/规则引用);RESTFUL/DATA_SQL 绑定前须带适配器必需配置(否则是注册壳)。
157
+
158
+ ## 报表 `report`
159
+
160
+ - **能做哪些事**:报表树/元数据读取、报表页建改删、BI dashboard 配置、图表增改删、图表数据查询、数据集读取/关联。
161
+ - **工具**:`report.tree`、`report.get`、`report.chartdata`、`report.datasource.list`、`report.datasource.link`、`report.create`、`report.update`、`report.delete`、`report.configure`
162
+ - **边界 / 陷阱**:
163
+ - **`report` 是"按需出现"的能力:只有用户显式要求报表 / 图表 / 看板 / dashboard 时才使用。常规开发流程不产出报表——不要在方案/存疑清单里对"统计/汇总/按月"之类的需求主动引入 `report`。**
164
+ - **跨对象统计聚合(如"按月按客户统计金额")默认不落 `report`**:先看能否用字段/查询配置表达;表达不了就落二开聚合接口(扩展写接口 + RESTFUL),**不要默认引 BI/报表**。报表是另一条独立交付物,需用户点名。
165
+ - 报表页走 `/api/api/report/*`;BI 走 `/dashboard/v1/*`(无 errcode 信封,body 必带 `config:{token,reportCode,appCode}`,缺则静默 no-op);外层 `corpId` 是真实查询键,默认 `"a"`。
166
+
167
+ ## 运行数据 `data`
168
+
169
+ - **能做哪些事**:业务记录列出、加载、保存、更新、删除、提交(工作流)。
170
+ - **工具**:`data.list`、`data.load`、`data.save`、`data.update`、`data.delete`、`data.submit`
171
+ - **recipe**:
172
+ - `omc describe data.save --example workflow-backed-data-save`
173
+ - `omc describe data.submit --example workflow-backed-data-submit`
174
+ - **边界 / 陷阱**:读实际业务记录是 OMC 独有能力。**计算字段(FORMULA/子表计算)不由 API 回填**——写测试数据带预算值,公式正确性人工前台确认;带子表计算字段的模型 API 写可能 50000(服务端重算 NPE),前台正常。
175
+
176
+ ---
177
+
178
+ ## 边界(boundaries)
179
+
180
+ 这些面**不在配置覆盖内**。被挡/不支持是**明确的答复**,不是要绕过的障碍——如实报告,不要用相近能力伪造。
181
+
182
+ | 面 | 状态 | 说明 |
183
+ | --- | --- | --- |
184
+ | 权限 / 授权矩阵 | blocked | 授权矩阵不在配置面 |
185
+ | 嵌套子表(子表套子表) | blocked | 一级子表可用,嵌套不可 |
186
+ | OCR / 电子签章 / 发票识别 | unsupported | 不在平台配置覆盖内 |
187
+ | 应用发布 / 环境上线 / 生产发布 | unsupported | CLI 只做配置,不做环境发布 |
188
+ | 在线后端编码 / EXECUTE_CODE / ONLINE_DEVELOP | unsupported | 用二开扩展包,不用在线 JS 伪造 |
189
+
190
+ > `blocked` / `unsupported` 是**原生配置**的判定,通常把行为路由到另一个代码所有者(`配置 + 后端扩展`),**不等于**需求不可交付。把 blocked face 编译成「做不了、留人工」是失败模式。
191
+
192
+ ## 相关 topic
193
+
194
+ - 需求分析(定面/归类/选路):`omc-requirement-analysis`;线索词表:`omc-requirement-vocabulary`
195
+ - 用哪个工具最省:`omc-tool-selection`;写前人审门:`omc-config-draft-review`
196
+ - 被拒/状态异常:`omc-refusals`;新面取证:`omc-capability-scouting`
197
+ - 每能力的配置怎么配:`omc-business-configuration` 的对应节;写入风险:`omc-write-hazards`