@stalfh233/omc-cli 0.4.54 → 0.4.55

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stalfh233/omc-cli",
3
- "version": "0.4.54",
3
+ "version": "0.4.55",
4
4
  "description": "CloudPivot 8.6 configuration capability CLI — governed, fail-closed, coverage-manifest bounded.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -50,9 +50,9 @@
50
50
  "access": "public"
51
51
  },
52
52
  "dependencies": {
53
- "@stalfh233/omc-fake-platform": "0.4.54",
53
+ "@stalfh233/omc-fake-platform": "0.4.55",
54
54
  "commander": "14.0.3",
55
- "omc-core": "0.4.54",
55
+ "omc-core": "0.4.55",
56
56
  "proper-lockfile": "4.1.2",
57
57
  "write-file-atomic": "6.0.0",
58
58
  "zod": "^3.23.8",
@@ -10,7 +10,9 @@ A change is accepted only when every gate below holds.
10
10
  ## Per-write
11
11
 
12
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.
13
+ 2. **Authoritative readback** — prove the intended state from the authoritative face (`field.list`, `form.get`, `data.load`, `onlinejs.get` for Online JS, `model.inspect` for workflow/rules), pairing each write with its same-family reader (`onlinejs.compose`→`onlinejs.get`; `report.datasource.link`→`linkedCount>0`). "Called without error" is not acceptance.
14
+ 2a. **Judge must be decidable** — prove the field exists first; all-same values (`false`/`null`/`0`) mean a wrong judge, not a pass. `form.get` has no `customScript` key — use `onlinejs.get`.
15
+ 2b. **Reachable ≠ correct** — `method.test success:true` proves reachability only; without a contract report "接口连通,业务对接未验证(契约缺失)".
14
16
  3. **Delivery state recorded** — the `.omc/` artifact exists with `deliveryState: DELIVERED` and the environment fingerprint.
15
17
  4. **Zero residue** — fixtures removed and exact absence proven on every face (draft and published); final state CLEANED.
16
18
 
@@ -232,6 +232,26 @@ omc call service.get --env local --args '{"serviceCode":"omc_demo_restful"}'
232
232
 
233
233
  - **新写一个接口 ≠ 新建一个服务**。同一个服务下可以挂多个方法:新服务用 `service.register`(`serviceCode` 已存在会 `duplicate-service` 拒绝),**往已有服务加方法用 `method.create`**(服务不存在 → 拒绝并提示先用 `service.register`;方法已存在 → 拒绝并提示改用 `method.update`)。不要为加一个方法而删服务重建(会连带丢掉服务的其它方法与规则绑定)。
234
234
 
235
+ ### 方法参数面(RESTFUL)
236
+
237
+ - **`configJson.position` 只接受五个枚举名**:`QUERY_PARAMS`、`URL_VARIABLE`、`REQUEST_HEADER`、`REQUEST_BODY`、`PATH_PARAMS`。直觉写法 `REQUEST_PARAM` 不存在。入参与出参**都必须带 position**(出参缺它会写成功、但 invoke 时 NPE)。
238
+ - **写侧用名字、读侧是整数索引**(`{"position":2}` = `REQUEST_HEADER`)——核对时不要因类型变化误判"没写进去"。映射以写入名为准。
239
+ - **常量头(平台注入,如 `X-LowCode-Corpid`/`X-LowCode-EngineCode`)标 `required:false`**:标成必填会让 `method.test` 判缺参而 fail-closed;常量值放 `codeType:0` + `bizCode`。
240
+ - `method.test` 缺常量头时拒跑是设计:要么先补齐实参,要么把常量声明为 `required:false`。
241
+ - 一次性把**全部**非法参数项改完再重试;逐项失败会按方法数放大往返。
242
+
243
+ ### 方法 URL 前缀 × 鉴权方式(混用即 401)
244
+
245
+ | 方法 url 写法 | 实际拼接 | 鉴权 | 结果 |
246
+ |---|---|---|---|
247
+ | `/openapi/...` | `/api/openapi/...`(单层) | `OAuth2 Client Credentials`(`xclient`) | ✅ |
248
+ | `/api/...` | `/api/api/...`(双层) | 用户身份(用户 token,`client_id=api`) | ✅ |
249
+ | `/api/...` + `xclient` | 双层 | 混用 | ❌ `401 权限不够` |
250
+ | `/externalLink/...` | 单层免鉴权 | 无 | ⚠️ 能通但方向错误,**禁止**用于二开接口 |
251
+
252
+ - **排障先找同 adapter 的既有成功服务当形状模板**:`service.list` → `service.get`,看它的方法 url 前缀与鉴权方式(如 `save` = `/openapi/employee/save` + `xclient`),照抄形状,别从零试。
253
+ - 二开扩展接口走 `/openapi` + `xclient`;不要用免鉴权前缀承载业务接口。
254
+
235
255
  BIZ_ACTION:
236
256
 
237
257
  - 先读方法输入/输出参数面。
@@ -103,7 +103,15 @@ approved draft, and decide with the human. A second write may duplicate.
103
103
  `recovery` are included. Wait for it to clear (it auto-recovers when the holding
104
104
  process exits), then retry. This guards concurrency, not approval.
105
105
 
106
- ## 8. Input / target
106
+ ## 8. Runtime / gateway errors (not tool refusals, same discipline)
107
+
108
+ - `401 权限不够` (bizservice invoke / manual call) → check **URL prefix × auth** first: `/openapi/**` uses `xclient` (Client Credentials); `/api/api/**` uses user-identity token. Mixing them is a guaranteed 401. Compare with an existing successful service under the same adapter (`service.get` → method url).
109
+ - `500` with no errcode, body only `header:X-LowCode-EngineCode should not be empty!` → add the multi-tenant header; not a business error.
110
+ - `404 Not Found ... openresty` / `当前业务方法绑定的API在服务端找不到` → the method url prefix/layer count is wrong (double/triple `/api`); fix per the matrix, don't keep re-editing the url.
111
+ - `position` read back as an integer while written as an enum name → read-side encoding, not a failed write.
112
+ - **Version evidence missing**:先区分 **`pcServerUrl` 缺失**(读取耦合缺陷,0.4.54 已修,不再 fail-closed)与 **`systemVersion` 真缺失**(此时 fail-closed 正确)。不要伪造 8.6 版本。
113
+
114
+ ## 9. Input / target
107
115
 
108
116
  - `tool-input-invalid` — schema violation (exit 10); fix the arguments.
109
117
  - `dictionary-target-required`, `intent-plan-invalid` — a required selector or
@@ -23,6 +23,10 @@ omc help omc-write-hazards
23
23
 
24
24
  ## 模型字段与关联
25
25
 
26
+ - **SQL 保留字预检**:字段 code 命中数据库关键字(如 `order`)时 wire 才回 `10033 编码[order]为SQL关键字`。建字段前先检查常见保留字(order/group/user/key/index/desc/asc/select/from/where/table),命中就换语义后缀(`orderRef`/`orderNo`),不要建了再改。
27
+ - **跨读面包目录键**:`apppackage/list` 投影的目录键是 `h_app_function.code`,`apppackage/trees` 的键是 `h_app_function.id`。把前者的 code 当 id 传给 `bizmodels/create.parentId` 会落成孤儿菜单行(模型读面可达、应用树/门户失踪)。0.4.54 起 `model.create` 的显式 `folderId` 会按 id/code 双口径归一;其它写面仍要自己归一。
28
+ - **`readback.present=false` 是硬失败信号**:平台可能接受请求但对象不在权威面(典型=孤儿挂载)。0.4.54 起交付状态降级为 `WRITE_UNVERIFIED`;禁止用"平台最终一致性"经验豁免。
29
+
26
30
  - **code 定位写前先核在册**:`field.update` / `rule.node.update` 等按 code 定位的精确写,先 `model.inspect` / `field.list` 确认 code 在册;缺码即停并报"目标不存在 + 当前字段清单"——**别凭用户措辞假定 code 正确**(用户可能记错字段名),**也别擅自替换成语义相近的字段**(改错对象比不改更糟)。缺码 `field.update` 本就拒 301001,但写前先核能省一轮失败往返,并在草稿阶段就把"字段不存在"与"需求理解偏差"分清。
27
31
  - **改名核对以字段读为准**:`field.update` 改名后,`model.inspect` 聚合面的 `fields[].name` 可能仍是旧值(发布态快照/聚合缓存);核对显示名用 `field.list`(默认清单面有 name);核对 options 用 `field.list` 的 `code` 选择器 / `field.get` 或 `form.publish` 回读——两处读数不一致时以字段读为准,别误判"写入没生效"而重复写。
28
32
  - `propertyEmpty` 默认 `false`。模型层保持可空;必填、只读、可见性在表单和流程节点配置。
@@ -34,6 +38,18 @@ omc help omc-write-hazards
34
38
  - **运行时写值的最小形状**(组合出错只会得到一个不透明的 `50000`/NPE,逐一最小化再合):单选关联(9) → id 字符串 `"<id>"`;**人员/组织(50/51/60/61) → `[{"id":"<id>","type":3,"name":"<名>"}]`,`type` 必填且为整数**(缺/非整数 → `BizField.parseFromClient` 拆箱 NPE→50000;用户=3、部门=1);日期(3) → 字符串 `"2026-09-30 10:00:00"`;子表(8) → 行对象数组 `[{"<子列code>":<值>, ...}]`。先各写一条最小行通过,再组合。
35
39
  - **DATE(3) 字段的 `options.format` 必须是平台大写枚举**(`YYYY-MM-DD`、`YYYY-MM-DD HH:mm:ss`、`YYYY年MM月DD日`…),**不是 Java 的 `yyyy-MM-dd`**:平台 `DateBizField` 按字面比较,Java 写法能创建字段但**首次运行时 save 稳定 `50000`(`不支持的format`)**(2026-09-30 R5 实测)。`field.create`/`intent` 会就地拒绝非枚举值。
36
40
 
41
+ ## 运行数据读取的默认过滤
42
+
43
+ - `data.list` **默认不含 DRAFT**(`total` 也只算 COMPLETED):清测试数据时 `total:0` 不代表没有残留。核对/清理一律显式 `{"all":true,"showTotal":true}`,或读回体里的过滤标注。`data.load` 用于单行核对。
44
+
45
+ ## 报表数据集
46
+
47
+ - `report.datasource.link` 回 `DELIVERED` 但 `readback.linkedCount:0` = **假成功**:新模型尚未同步进 BI(`cloudpivot_report.i_datasource`/`i_modelschema` 无记录)。前置条件是先在设计器打开一次报表/触发同步;判定以 `linkedCount>0` 为准,不以 deliveryState 为准。0.4.54 起该形状直接被拒绝(`report-datasource-link-not-synced`)。
48
+
49
+ ## 应用发布边界
50
+
51
+ - `app.create`/`configure_model` 的 `publishBoundary.inScope:false` + `hint:publish-in-designer` 表示**应用发布必须在设计器完成**。交付说明必须把它列进「剩余人工动作」,不得宣称"全部配好"。
52
+
37
53
  ## 视图
38
54
 
39
55
  - `conditions[].visible` 未传时 CLI 默认 `true`;只有需求明确隐藏时传 `false`。