@microi.net/cli 5.5.8 → 5.6.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 (166) hide show
  1. package/.codebuddy-plugin/marketplace.json +2 -2
  2. package/.codebuddy-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/.mcp.json +1 -1
  5. package/.workbuddy-plugin/marketplace.json +2 -2
  6. package/.workbuddy-plugin/plugin.json +1 -1
  7. package/README.md +71 -71
  8. package/assets/build-meta.json +5 -5
  9. package/assets/feature-matrix.json +129 -129
  10. package/cordis.patch.yml +1 -1
  11. package/package.json +1 -1
  12. package/scripts/codex-marketplace.json +20 -20
  13. package/scripts/mcp-codex-stdio-adapter.js +189 -189
  14. package/scripts/mcp-trae-windows-launcher.cmd +21 -21
  15. package/scripts/microi-cli-mcp.js +7 -7
  16. package/scripts/microi-codex-broker.js +447 -447
  17. package/scripts/microi-codex-router.js +582 -582
  18. package/scripts/microi-skills.meta.json +336 -336
  19. package/skills/.microi-skills-version.json +2 -2
  20. package/skills/.progressive-disclosure-manifest.json +3566 -3566
  21. package/skills/README.md +3 -3
  22. package/skills/ai-engine/SKILL.md +45 -43
  23. package/skills/ai-platform-governance/SKILL.md +177 -177
  24. package/skills/ai-platform-governance/references/progressive-01-/345/212/237/350/203/275/345/274/200/345/205/263.md +190 -190
  25. package/skills/app-store/SKILL.md +177 -177
  26. package/skills/business-blueprint/SKILL.md +85 -85
  27. package/skills/datasource-engine/SKILL.md +91 -91
  28. package/skills/dos-orm/SKILL.md +81 -81
  29. package/skills/dos-orm/references/api-reference.md +229 -229
  30. package/skills/email-engine/SKILL.md +80 -80
  31. package/skills/email-engine/references/v8-email.md +34 -34
  32. package/skills/job-engine/SKILL.md +154 -143
  33. package/skills/message-notification/SKILL.md +126 -126
  34. package/skills/message-notification/agents/openai.yaml +5 -5
  35. package/skills/message-notification/references/contracts.md +102 -102
  36. package/skills/microi-ai-app-auth.js +652 -652
  37. package/skills/microi-ai-application/SKILL.md +102 -94
  38. package/skills/microi-ai-application/agents/openai.yaml +4 -4
  39. package/skills/microi-ai-application/references/frontend-baseline.md +164 -164
  40. package/skills/microi-client-frontend/SKILL.md +43 -43
  41. package/skills/microi-client-frontend/references/progressive-01-3-/345/212/250/346/200/201/346/214/211/351/222/256/347/263/273/347/273/237.md +2 -2
  42. package/skills/microi-client-frontend/references/progressive-02-8-/350/277/220/350/241/214/346/227/266/351/253/230/351/242/221/345/235/221/345/244/215/347/233/230.md +28 -28
  43. package/skills/microi-client-frontend/references/progressive-03-vue3-/345/211/215/347/253/257/345/276/256/346/234/215/345/212/241/345/256/277/344/270/273/350/247/204/345/210/231.md +56 -56
  44. package/skills/microi-codex/SKILL.md +46 -46
  45. package/skills/microi-codex-installer/SKILL.md +216 -216
  46. package/skills/microi-codex-installer/agents/openai.yaml +7 -7
  47. package/skills/microi-datasource-mapping/SKILL.md +67 -67
  48. package/skills/microi-db-schema/SKILL.md +6 -6
  49. package/skills/microi-db-schema/references/core-tables.md +18 -18
  50. package/skills/microi-db-schema/references/form-component-options.md +256 -256
  51. package/skills/microi-db-schema/references/schema-overview.md +11 -11
  52. package/skills/microi-db-schema/references/schema.md +46 -46
  53. package/skills/microi-db-schema/references/table-catalog.md +57 -57
  54. package/skills/microi-deployment/SKILL.md +18 -1
  55. package/skills/microi-deployment/references/deployment-matrix.md +101 -101
  56. package/skills/microi-docs-coverage/SKILL.md +123 -123
  57. package/skills/microi-docs-coverage/references/capability-map.md +1 -0
  58. package/skills/microi-docs-coverage/scripts/audit-doc-skill-coverage.mjs +894 -894
  59. package/skills/microi-form-engine/SKILL.md +50 -50
  60. package/skills/microi-form-engine/references/component-catalog.md +218 -218
  61. package/skills/microi-form-engine/references/data-source-events.md +124 -124
  62. package/skills/microi-form-layout/SKILL.md +13 -13
  63. package/skills/microi-form-layout/references/progressive-01-3-/344/270/211/347/247/215/345/210/206/347/273/204/347/232/204/345/255/230/345/202/250/344/270/216/351/205/215/347/275/256.md +235 -235
  64. package/skills/microi-frontend-sdk/SKILL.md +4 -4
  65. package/skills/microi-frontend-sdk/references/progressive-01-token-/345/275/223/345/211/215/347/231/273/345/275/225/347/224/250/346/210/267/344/270/216/345/275/223/345/211/215/347/273/210/347/253/257/347/231/273/345/275/225/345/215/217/350/256/256.md +175 -175
  66. package/skills/microi-left-right-layout/SKILL.md +141 -141
  67. package/skills/microi-microservice/SKILL.md +12 -10
  68. package/skills/microi-microservice/references/runtime-delivery.md +278 -278
  69. package/skills/microi-mobile-app-quality/references/progressive-01-4-/351/207/215/350/246/201/346/214/211/351/222/256/345/277/205/351/241/273/345/270/246/345/233/276/346/240/207.md +213 -213
  70. package/skills/microi-solution-quotation/SKILL.md +78 -78
  71. package/skills/microi-solution-quotation/agents/openai.yaml +4 -4
  72. package/skills/microi-solution-quotation/scripts/build_solution_quote.py +296 -296
  73. package/skills/microi-sso/SKILL.md +85 -85
  74. package/skills/microi-sso/references/acceptance.md +49 -49
  75. package/skills/microi-sso/references/configuration-and-security.md +53 -53
  76. package/skills/microi-sso/references/inbound.md +53 -53
  77. package/skills/microi-sso/references/outbound.md +39 -39
  78. package/skills/microi-system-delivery/references/progressive-02-/350/207/252/345/212/250/345/214/226/346/265/213/350/257/225/345/277/205/351/241/273/350/246/206/347/233/226/347/232/204/345/235/221.md +20 -20
  79. package/skills/microi-ui/SKILL.md +7 -2
  80. package/skills/microi-uniapp-frontend/SKILL.md +134 -134
  81. package/skills/microi-uniapp-frontend/references/progressive-01-/347/247/273/345/212/250/347/253/257/345/210/206/347/261/273-/345/217/214/346/240/217/345/210/227/350/241/250/347/213/254/347/253/213/346/273/232/345/212/250.md +136 -136
  82. package/skills/microi-uniapp-frontend/references/progressive-02-/345/205/263/351/224/256/344/270/232/345/212/241/350/265/204/344/272/247/344/270/215/345/276/227/351/273/230/350/256/244/351/200/211/344/270/255.md +124 -124
  83. package/skills/module-engine/SKILL.md +16 -16
  84. package/skills/ocr-engine/SKILL.md +2 -2
  85. package/skills/ocr-engine/agents/openai.yaml +1 -1
  86. package/skills/page-engine/SKILL.md +28 -28
  87. package/skills/page-engine/references/progressive-01-/346/211/200/346/234/211/347/273/204/344/273/266/347/261/273/345/236/213.md +126 -126
  88. package/skills/page-engine/references/progressive-02-/347/211/210/346/234/254/345/216/206/345/217/262-/345/271/266/345/217/221/344/277/235/345/255/230/344/270/216/345/233/236/346/273/232.md +42 -42
  89. package/skills/performance-testing/SKILL.md +120 -120
  90. package/skills/playwright-e2e/SKILL.md +84 -84
  91. package/skills/playwright-e2e/references/progressive-01-/345/205/250/350/207/252/345/212/250/347/231/273/345/275/225-/345/205/215/351/252/214/350/257/201/347/240/201-/344/275/206/344/270/215/345/205/215/345/257/206/347/240/201-/345/277/205/350/257/273.md +68 -68
  92. package/skills/playwright-e2e/references/progressive-02-/346/226/207/345/255/227/345/257/271/346/257/224/345/272/246/344/270/216/345/217/257/350/257/273/346/200/247/350/207/252/345/212/250/345/214/226/346/243/200/346/237/245-/345/277/205/345/201/232.md +64 -64
  93. package/skills/playwright-e2e/references/progressive-03-microi-helper-/346/250/241/346/235/277.md +20 -20
  94. package/skills/playwright-e2e/references/progressive-04-ci-/345/273/272/350/256/256.md +69 -69
  95. package/skills/print-engine/SKILL.md +36 -36
  96. package/skills/production-readonly-audit/SKILL.md +41 -41
  97. package/skills/report-engine/SKILL.md +71 -71
  98. package/skills/scripts/optimize-progressive-disclosure.mjs +204 -204
  99. package/skills/scripts/refresh-progressive-disclosure.mjs +64 -64
  100. package/skills/scripts/validate-progressive-disclosure.mjs +52 -52
  101. package/skills/search-engine/SKILL.md +75 -75
  102. package/skills/spider-engine/SKILL.md +190 -190
  103. package/skills/system-observability/SKILL.md +162 -162
  104. package/skills/system-observability/references/memory-incident-triage.md +73 -73
  105. package/skills/translate-engine/SKILL.md +1 -1
  106. package/skills/ui-design/SKILL.md +3 -1
  107. package/skills/uniapp-mall-assets/SKILL.md +170 -170
  108. package/skills/unity-integration/SKILL.md +155 -155
  109. package/skills/unity-integration/agents/openai.yaml +4 -4
  110. package/skills/unity-integration/references/ai-app-delivery.md +103 -103
  111. package/skills/unity-integration/references/sdk-api.md +82 -82
  112. package/skills/unity-integration/references/toolbox-migration.md +66 -66
  113. package/skills/unity-integration/references/webgl-hosting.md +57 -57
  114. package/skills/v8-api-config/SKILL.md +378 -378
  115. package/skills/v8-cache-pattern/SKILL.md +306 -306
  116. package/skills/v8-crud-api/SKILL.md +29 -29
  117. package/skills/v8-crud-api/references/progressive-01-/346/237/245/350/257/242/345/210/227/350/241/250-/345/210/206/351/241/265.md +56 -56
  118. package/skills/v8-debugging/SKILL.md +143 -143
  119. package/skills/v8-explorer-tree/SKILL.md +64 -64
  120. package/skills/v8-export-import/references/progressive-01-excellayout-/351/253/230/347/272/247/350/207/252/347/224/261/345/270/203/345/261/200.md +201 -201
  121. package/skills/v8-export-import/references/progressive-02-powerpoint-/345/257/274/345/207/272.md +118 -118
  122. package/skills/v8-export-import/references/progressive-03-/345/256/211/345/205/250-/346/200/247/350/203/275/346/263/250/346/204/217.md +32 -32
  123. package/skills/v8-file-upload/SKILL.md +154 -154
  124. package/skills/v8-file-upload/references/progressive-01-/345/205/254/346/234/211/346/241/266-vs-/347/247/201/346/234/211/346/241/266.md +133 -133
  125. package/skills/v8-file-upload/references/progressive-02-office-/346/226/207/344/273/266/345/234/250/347/272/277/347/274/226/350/276/221/347/211/210/346/234/254/345/217/267/350/247/204/345/210/231.md +138 -138
  126. package/skills/v8-formengine-http/SKILL.md +107 -107
  127. package/skills/v8-frontend-events/SKILL.md +22 -22
  128. package/skills/v8-frontend-events/references/bluetooth-print-api.md +135 -135
  129. package/skills/v8-frontend-events/references/bluetooth-print.md +247 -247
  130. package/skills/v8-frontend-events/references/progressive-01-/345/210/227/350/241/250/344/272/213/344/273/266.md +50 -50
  131. package/skills/v8-http-integration/SKILL.md +106 -106
  132. package/skills/v8-http-integration/references/progressive-01-get-/350/257/267/346/261/202.md +31 -31
  133. package/skills/v8-http-integration/references/progressive-02-/351/224/231/350/257/257/345/244/204/347/220/206/346/250/241/345/274/217.md +5 -5
  134. package/skills/v8-image-processing/SKILL.md +190 -190
  135. package/skills/v8-image-processing/agents/openai.yaml +4 -4
  136. package/skills/v8-image-processing/references/api-reference.md +623 -623
  137. package/skills/v8-menu-buttons/SKILL.md +103 -103
  138. package/skills/v8-menu-buttons/references/progressive-01-2-/346/214/211/351/222/256/345/257/271/350/261/241-schema.md +145 -145
  139. package/skills/v8-menu-buttons/references/progressive-02-8-/346/250/241/345/274/217-f-/345/220/216/345/217/260/344/273/273/345/212/241/346/214/211/351/222/256-/351/225/277/344/273/273/345/212/241.md +228 -228
  140. package/skills/v8-menu-buttons/references/progressive-03-10-/345/217/215/346/250/241/345/274/217-/351/201/277/345/205/215.md +43 -43
  141. package/skills/v8-mongodb/SKILL.md +65 -65
  142. package/skills/v8-mq-mqtt/SKILL.md +175 -175
  143. package/skills/v8-mq-mqtt/references/mqtt-production.md +342 -342
  144. package/skills/v8-mq-mqtt/references/progressive-01-v8-mqtt-iot-/347/211/251/350/201/224/347/275/221.md +137 -137
  145. package/skills/v8-mq-mqtt/scripts/check-mqtt-skill-coverage.mjs +203 -203
  146. package/skills/v8-saas-multi-tenant/SKILL.md +223 -223
  147. package/skills/v8-security/SKILL.md +25 -25
  148. package/skills/v8-security/references/progressive-01-2-/346/235/203/351/231/220/346/240/241/351/252/214.md +122 -122
  149. package/skills/v8-sql-query/SKILL.md +127 -127
  150. package/skills/v8-table-event/SKILL.md +20 -20
  151. package/skills/v8-table-event/references/progressive-01-informv8-js-/350/241/250/345/215/225/346/211/223/345/274/200/344/272/213/344/273/266.md +18 -18
  152. package/skills/v8-table-event/references/progressive-02-/345/211/215/347/253/257/344/272/213/344/273/266/345/220/215-v8-eventname-/345/217/257/350/203/275/347/232/204/345/200/274.md +15 -15
  153. package/skills/v8-tcp-integration/SKILL.md +1 -1
  154. package/skills/v8-tcp-integration/agents/openai.yaml +4 -4
  155. package/skills/v8-template-engine/SKILL.md +59 -59
  156. package/skills/v8-utilities/SKILL.md +92 -92
  157. package/skills/v8-utilities/references/client-api-index.md +143 -143
  158. package/skills/v8-utilities/references/platform-http-routes.md +83 -83
  159. package/skills/v8-utilities/references/server-api-index.md +74 -74
  160. package/skills/v8-workflow/SKILL.md +44 -44
  161. package/skills/vision-engine/SKILL.md +19 -19
  162. package/skills/vision-engine/references/architecture-and-acceptance.md +34 -34
  163. package/skills/workspace-conventions/SKILL.md +236 -236
  164. package/skills/workspace-conventions/references/progressive-01-/347/211/210/346/234/254/346/233/264/346/226/260/346/227/245/345/277/227/344/277/235/346/212/244/350/247/204/345/210/231-/345/274/272/345/210/266.md +208 -208
  165. package/skills/workspace-conventions/references/progressive-02-microi-net-api-/346/234/254/345/234/260/345/220/257/345/212/250/347/272/246/345/256/232.md +179 -179
  166. package/skills/workspace-conventions/references/progressive-03-cli-/344/270/216-ide-/346/217/222/344/273/266/351/224/231/347/211/210/345/205/261/345/255/230/347/272/246/345/256/232.md +21 -21
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: v8-crud-api
3
- description: Microi V8 CRUD 接口引擎开发。用于编写服务端 JavaScript,涉及 V8.FormEngine Add/Upt/Del/GetTableData、DosResult 返回、事务和校验。
3
+ description: Microi V8 CRUD 接口引擎开发。用于编写服务端 JavaScript,涉及 V8.FormEngine Add/Upt/Del/GetTableData、DosResult 返回、事务和校验。
4
4
  ---
5
5
 
6
6
  > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
@@ -20,20 +20,20 @@ AI 本地开发接口引擎时,优先修改 `microi-v8-engine/<租户>/<项目
20
20
  ```javascript
21
21
  /*
22
22
  * V8 ApiEngine
23
- * ApiEngineKey: 示例接口引擎Key
23
+ * ApiEngineKey: 示例接口引擎Key
24
24
  * Version: v1.0.0
25
- * 功能说明:
25
+ * 功能说明:
26
26
  * - 完整说明该接口引擎负责的业务功能、输入参数、关键返回字段和重要副作用。
27
27
  */
28
28
  ```
29
29
 
30
- 同步流程:`确认后端可达(不可达则自动启动 Microi.Server/Microi.net.Api/Microi.net.Api.csproj) -> 读取远端 -> 修改本地并递增语义版本头 -> JS 语法检查 -> 保存远端 -> 回读远端确认代码头 Version 与 sys_apiengine.Version 一致 -> 用 HTTP /apiengine/{key} + osclient Header 复测`。只用 MCP 保存成功不算完成,必须至少做回读或 HTTP 验证。普通 POST/PUT/PATCH/DELETE 禁止无脑追加 `--OsClient--...--`;该特殊路径仅保留给确实无法传 Header/Form/Query 的 GET/HEAD 或第三方回调场景。
30
+ 同步流程:`确认后端可达(不可达则自动启动 Microi.Server/Microi.net.Api/Microi.net.Api.csproj) -> 读取远端 -> 修改本地并递增语义版本头 -> JS 语法检查 -> 保存远端 -> 回读远端确认代码头 Version 与 sys_apiengine.Version 一致 -> 用 HTTP /apiengine/{key} + osclient Header 复测`。只用 MCP 保存成功不算完成,必须至少做回读或 HTTP 验证。普通 POST/PUT/PATCH/DELETE 禁止无脑追加 `--OsClient--...--`;该特殊路径仅保留给确实无法传 Header/Form/Query 的 GET/HEAD 或第三方回调场景。
31
31
 
32
- 如果保存或回读时出现 `fetch failed`、`ECONNREFUSED`、`000 Failed to connect`、端口无人监听等服务不可达问题,不能提前中止。需要启动或重启本地 API 时,必须在 `Microi.Server/Microi.net.Api` 目录通过 VS Code 可见终端执行 `dotnet run --launch-profile Microi.net.Api`,让开发者能肉眼看到并手动停止;不要用隐藏后台 shell 启动长期占用端口的 API 进程。若工具当前无法打开可见终端,应先说明限制并让用户启动/重启后继续验证。涉及 PC 页面联调或 Playwright 时,`Microi.Client` 也必须使用可见终端执行:`npm run dev -- --host 0.0.0.0 --port 1988`。只有启动失败、依赖缺失、数据库连接失败或端口冲突无法处理时才报告阻塞。
33
-
34
- Microi.net.Api 普通本地启动不要额外设置 `ASPNETCORE_ENVIRONMENT` / `DOTNET_ENVIRONMENT`,让 `Program.cs` 读取 `Microi.Server/Microi.net.Api/.microi-local` 并加载对应的 `appsettings.{Env}.json`。
32
+ 如果保存或回读时出现 `fetch failed`、`ECONNREFUSED`、`000 Failed to connect`、端口无人监听等服务不可达问题,不能提前中止。需要启动或重启本地 API 时,必须在 `Microi.Server/Microi.net.Api` 目录通过 VS Code 可见终端执行 `dotnet run --launch-profile Microi.net.Api`,让开发者能肉眼看到并手动停止;不要用隐藏后台 shell 启动长期占用端口的 API 进程。若工具当前无法打开可见终端,应先说明限制并让用户启动/重启后继续验证。涉及 PC 页面联调或 Playwright 时,`Microi.Client` 也必须使用可见终端执行:`npm run dev -- --host 0.0.0.0 --port 1988`。只有启动失败、依赖缺失、数据库连接失败或端口冲突无法处理时才报告阻塞。
35
33
 
36
- 版本与历史同步规则:通过 MCP 或 VS Code 插件保存接口引擎时,必须同步写入 `sys_apiengine.Version`;新版平台把每次修改说明作为独立记录写入 `mci_apiengine_change_history`,表单中的“修改历史”使用 `TableChild` 展示,不再让客户端拼接或覆盖 `sys_apiengine.ChangeHistory` 多行文本。写入必须携带版本号与简明说明,并使用幂等 `EntryKey` 防止网络重试产生重复记录。安装/升级表单引擎官方应用时,旧 `ChangeHistory` 按非空行迁入子表并保留旧物理列作滚动兼容;尚未安装该子表、旧库缺字段或迁移期间,后端应自动回退旧字段或仅更新 `ApiV8Code` 与 `UpdateTime`,不得因此阻断代码同步。
34
+ Microi.net.Api 普通本地启动不要额外设置 `ASPNETCORE_ENVIRONMENT` / `DOTNET_ENVIRONMENT`,让 `Program.cs` 读取 `Microi.Server/Microi.net.Api/.microi-local` 并加载对应的 `appsettings.{Env}.json`。
35
+
36
+ 版本与历史同步规则:通过 MCP 或 VS Code 插件保存接口引擎时,必须同步写入 `sys_apiengine.Version`;新版平台把每次修改说明作为独立记录写入 `mci_apiengine_change_history`,表单中的“修改历史”使用 `TableChild` 展示,不再让客户端拼接或覆盖 `sys_apiengine.ChangeHistory` 多行文本。写入必须携带版本号与简明说明,并使用幂等 `EntryKey` 防止网络重试产生重复记录。安装/升级表单引擎官方应用时,旧 `ChangeHistory` 按非空行迁入子表并保留旧物理列作滚动兼容;尚未安装该子表、旧库缺字段或迁移期间,后端应自动回退旧字段或仅更新 `ApiV8Code` 与 `UpdateTime`,不得因此阻断代码同步。
37
37
 
38
38
  生成接口引擎代码时,代码内容本身(文件头、普通注释、`console.log`、返回 `Msg` 等)不要包含 `Microi`、`吾码` 等平台品牌文字,除非业务数据或字段值本身必须如此。生成代码要有可维护注释:每个 `function` 前写清用途、关键参数和返回值;跨表事务、权限校验、状态机、金额/库存计算、复杂 `_Where` 条件等代码段前写短注释说明业务原因;避免“给变量赋值”这类无信息量注释。
39
39
 
@@ -46,29 +46,29 @@ Microi.net.Api 普通本地启动不要额外设置 `ASPNETCORE_ENVIRONMENT` / `
46
46
  - 通过 `V8.Param` 获取前端传入的参数(URL参数 / form-data / payload-json)
47
47
  - 通过 `V8.CurrentUser` 获取当前登录用户信息
48
48
  - 返回结果统一格式:`{ Code: 1, Data: any, Msg: '成功' }`
49
- - 所有 FormEngine 方法在服务器端支持第三个参数传入 `V8.DbTrans`(事务对象)
50
- - 服务端调用 FormEngine 默认**不触发**表单 V8 事件,加 `_InvokeType: 'Client'` 才触发
51
- - 接口内 `return Code=1` 自动提交事务、`Code≠1` 自动回滚事务,**禁止**手动 Commit/Rollback
52
-
49
+ - 所有 FormEngine 方法在服务器端支持第三个参数传入 `V8.DbTrans`(事务对象)
50
+ - 服务端调用 FormEngine 默认**不触发**表单 V8 事件,加 `_InvokeType: 'Client'` 才触发
51
+ - 接口内 `return Code=1` 自动提交事务、`Code≠1` 自动回滚事务,**禁止**手动 Commit/Rollback
52
+
53
53
  <!-- /microi-progressive:chunk -->
54
54
  <!-- microi-progressive:chunk id=v8-crud-api-002 sha256=9f10ab278468f292b5e26679b7a7ab2ea91bb6d4094e2bff8adb7cb15e39adce -->
55
- ## 性能底线(必须自检)
56
-
57
- - 写接口引擎前必须先做数据访问计划:需要哪些表、哪些字段、预计数据量、是否分页、是否需要缓存。
58
- - 禁止在 `for` / `while` / `forEach` / 嵌套循环中反复调用 `GetFormData`、`GetTableData`、`FromSql`、`ApiEngine.Run` 或外部 HTTP。先收集 Id/Key,用一次 `In` 查询或一条 JOIN/聚合 SQL 批量取回,再用对象字典映射。
59
- - 禁止用双重循环匹配两组列表。先把小表或关联表整理成 `{ id: row }`、`{ parentId: [] }` 这类 Map,再单循环组装结果。
60
- - 所有列表查询必须设置 `_SelectFields`,只取业务需要的字段;面向前端的列表必须分页或显式限制 `_PageSize`,不能一次拉全表。
61
- - 报表、统计、跨表汇总优先使用数据库聚合(`COUNT/SUM/GROUP BY/JOIN`)或一次批量查询后内存聚合,不能逐行查明细再累加。
62
- - 高频读取的系统配置、字典、菜单、字段、角色权限等静态数据要优先使用 `V8.Cache` 或平台已有缓存;写入后必须清理相关缓存。
63
- - 外部 HTTP、短信、翻译、文件处理等慢操作不要放在数据库事务内循环执行;能批量就批量,不能批量就拆成异步任务/队列。
64
- - 返回前做一次性能复核:数据库访问次数是否与数据量无关、是否避免 N+1 查询、是否有索引友好的 `_Where` 条件、是否不会因空参数导致全表扫描。
65
-
66
- ### 计量流水与分页审计
67
-
68
- - Token、积分、余额等计量必须由服务端在真实成功结果后记录,失败请求不得扣减;能够取得供应商 `usage` 时禁止用完整 JSON 字符数代替真实输入/输出 Token。
69
- - 余额扣减与流水新增必须在同一事务内完成,并锁定当前账户行,避免并发请求透支或出现“余额已扣但流水未写”。
70
- - 面向个人中心的流水接口必须按 `V8.CurrentUser.Id` 强制隔离,并返回 `PageIndex`、`PageSize`、`TotalCount`;列表只取页面需要的审计字段。
71
- - 为便于用户核对,可以保存经过空白归一化的用户输入短摘要;摘要按 Unicode 文本元素截取,不能截断 emoji 或代理对,也不要把完整请求 JSON 当摘要。
55
+ ## 性能底线(必须自检)
56
+
57
+ - 写接口引擎前必须先做数据访问计划:需要哪些表、哪些字段、预计数据量、是否分页、是否需要缓存。
58
+ - 禁止在 `for` / `while` / `forEach` / 嵌套循环中反复调用 `GetFormData`、`GetTableData`、`FromSql`、`ApiEngine.Run` 或外部 HTTP。先收集 Id/Key,用一次 `In` 查询或一条 JOIN/聚合 SQL 批量取回,再用对象字典映射。
59
+ - 禁止用双重循环匹配两组列表。先把小表或关联表整理成 `{ id: row }`、`{ parentId: [] }` 这类 Map,再单循环组装结果。
60
+ - 所有列表查询必须设置 `_SelectFields`,只取业务需要的字段;面向前端的列表必须分页或显式限制 `_PageSize`,不能一次拉全表。
61
+ - 报表、统计、跨表汇总优先使用数据库聚合(`COUNT/SUM/GROUP BY/JOIN`)或一次批量查询后内存聚合,不能逐行查明细再累加。
62
+ - 高频读取的系统配置、字典、菜单、字段、角色权限等静态数据要优先使用 `V8.Cache` 或平台已有缓存;写入后必须清理相关缓存。
63
+ - 外部 HTTP、短信、翻译、文件处理等慢操作不要放在数据库事务内循环执行;能批量就批量,不能批量就拆成异步任务/队列。
64
+ - 返回前做一次性能复核:数据库访问次数是否与数据量无关、是否避免 N+1 查询、是否有索引友好的 `_Where` 条件、是否不会因空参数导致全表扫描。
65
+
66
+ ### 计量流水与分页审计
67
+
68
+ - Token、积分、余额等计量必须由服务端在真实成功结果后记录,失败请求不得扣减;能够取得供应商 `usage` 时禁止用完整 JSON 字符数代替真实输入/输出 Token。
69
+ - 余额扣减与流水新增必须在同一事务内完成,并锁定当前账户行,避免并发请求透支或出现“余额已扣但流水未写”。
70
+ - 面向个人中心的流水接口必须按 `V8.CurrentUser.Id` 强制隔离,并返回 `PageIndex`、`PageSize`、`TotalCount`;列表只取页面需要的审计字段。
71
+ - 为便于用户核对,可以保存经过空白归一化的用户输入短摘要;摘要按 Unicode 文本元素截取,不能截断 emoji 或代理对,也不要把完整请求 JSON 当摘要。
72
72
 
73
73
  <!-- /microi-progressive:chunk -->
74
74
  <!-- microi-progressive:chunk id=v8-crud-api-003 sha256=d46768bbaaf8b2ebfdd38e09d11e886b135cb65e78984dbfa67d75ec5f947175 -->
@@ -18,27 +18,27 @@ var result = V8.FormEngine.GetTableData('SysUser', {
18
18
  _PageSize: V8.Param.pageSize || 20
19
19
  });
20
20
 
21
- return { Code: 1, Data: result.Data, DataCount: result.DataCount, Msg: '成功' };
22
- ```
23
-
24
- ### 请求内异步查询
25
-
26
- 后端接口引擎可在本次请求内使用真实异步查询;前端 V8 不使用这个方法名:
27
-
28
- ```javascript
29
- var result = await V8.FormEngine.GetTableDataAsync('SysUser', {
30
- _Where: [['Status', '=', 1]],
31
- _SelectFields: ['Id', 'Account', 'Name'],
32
- _PageIndex: 1,
33
- _PageSize: 20
34
- });
35
-
36
- return { Code: 1, Data: result.Data, DataCount: result.DataCount };
37
- ```
38
-
39
- 必须 `await` 结果。需要接口先返回、后续再批量处理时,应改用平台后台任务、Job、MQ 或 outbox,而不是丢弃 Promise。
40
-
41
- ### 多字段排序
21
+ return { Code: 1, Data: result.Data, DataCount: result.DataCount, Msg: '成功' };
22
+ ```
23
+
24
+ ### 请求内异步查询
25
+
26
+ 后端接口引擎可在本次请求内使用真实异步查询;前端 V8 不使用这个方法名:
27
+
28
+ ```javascript
29
+ var result = await V8.FormEngine.GetTableDataAsync('SysUser', {
30
+ _Where: [['Status', '=', 1]],
31
+ _SelectFields: ['Id', 'Account', 'Name'],
32
+ _PageIndex: 1,
33
+ _PageSize: 20
34
+ });
35
+
36
+ return { Code: 1, Data: result.Data, DataCount: result.DataCount };
37
+ ```
38
+
39
+ 必须 `await` 结果。需要接口先返回、后续再批量处理时,应改用平台后台任务、Job、MQ 或 outbox,而不是丢弃 Promise。
40
+
41
+ ### 多字段排序
42
42
 
43
43
  ```javascript
44
44
  var result = V8.FormEngine.GetTableData('SysUser', {
@@ -47,21 +47,21 @@ var result = V8.FormEngine.GetTableData('SysUser', {
47
47
  });
48
48
  ```
49
49
 
50
- ### 匿名查询(无需登录)
50
+ ### 匿名查询(无需登录)
51
51
 
52
52
  ```javascript
53
- var result = V8.FormEngine.GetTableDataAnonymous('Article', {
53
+ var result = V8.FormEngine.GetTableDataAnonymous('Article', {
54
54
  _Where: [['IsPublished', '=', 1]],
55
55
  _PageSize: 10
56
- });
57
- ```
58
-
59
- 匿名新增的公开入口是
60
- `POST /api/formengine/AddFormDataAnonymous`,且目标表必须显式允许匿名新增。
61
- 当前后端 `V8.FormEngine` 接口不公开
62
- `V8.FormEngine.AddFormDataAnonymous`;接口引擎内部仍使用
63
- `V8.FormEngine.AddFormData(...)` 并遵守可信执行身份。不要仅因为历史文档出现
64
- 该名称就为匿名业务接口关闭服务端校验。
56
+ });
57
+ ```
58
+
59
+ 匿名新增的公开入口是
60
+ `POST /api/formengine/AddFormDataAnonymous`,且目标表必须显式允许匿名新增。
61
+ 当前后端 `V8.FormEngine` 接口不公开
62
+ `V8.FormEngine.AddFormDataAnonymous`;接口引擎内部仍使用
63
+ `V8.FormEngine.AddFormData(...)` 并遵守可信执行身份。不要仅因为历史文档出现
64
+ 该名称就为匿名业务接口关闭服务端校验。
65
65
 
66
66
  ### 获取树形数据
67
67
 
@@ -160,11 +160,11 @@ V8.FormEngine.DelFormDataByWhere('SysUser', {
160
160
  ## 事务处理
161
161
 
162
162
  ```javascript
163
- // 接口引擎中 V8.Db 自动开启事务:
164
- // 返回DosResult/带Code对象:仅Code=1提交,其他值回滚
165
- // 返回对象但没有Code:回滚
166
- // 返回字符串/数字/数组/布尔/null且未异常:提交
167
- // 手动调用 V8.DbTrans.Commit() 或 Rollback() 无效,由平台统一管理
163
+ // 接口引擎中 V8.Db 自动开启事务:
164
+ // 返回DosResult/带Code对象:仅Code=1提交,其他值回滚
165
+ // 返回对象但没有Code:回滚
166
+ // 返回字符串/数字/数组/布尔/null且未异常:提交
167
+ // 手动调用 V8.DbTrans.Commit() 或 Rollback() 无效,由平台统一管理
168
168
 
169
169
  // FormEngine 可传入事务对象(第三个参数)
170
170
  V8.FormEngine.AddFormData('Table1', { Name: '测试' }, V8.DbTrans);
@@ -176,21 +176,21 @@ V8.ApiEngine.Run('other-engine-key', { Id: 'xxx' }, V8.DbTrans);
176
176
 
177
177
  <!-- /microi-progressive:chunk -->
178
178
  <!-- microi-progressive:chunk id=v8-crud-api-012 sha256=ea59e9c92b84986701a412f53a907fb2243bc7698422c1361d82280d1e4a3e4f -->
179
- ## 请求内异步与后台处理
180
-
181
- ```javascript
182
- // 本次请求必须拿到结果时,使用真实Async API并await
183
- var resp = await V8.Http.PostResponseAsync({
184
- Url: 'https://other.com/notify',
185
- PostParam: { Id: V8.Param.id },
186
- Timeout: 10
187
- });
188
- return resp.StatusCode >= 200 && resp.StatusCode < 300
189
- ? { Code: 1 }
190
- : { Code: 0, Msg: '通知失败' };
191
- ```
192
-
193
- 禁止用 `setTimeout` / `Task.Run` 实现“立即返回、后台继续”:接口返回后 Jint Engine、租户上下文、事务和执行租约会释放。脱离请求的任务使用后台任务、Job、MQ 或 outbox,并按 `EventId` 幂等处理与恢复。
179
+ ## 请求内异步与后台处理
180
+
181
+ ```javascript
182
+ // 本次请求必须拿到结果时,使用真实Async API并await
183
+ var resp = await V8.Http.PostResponseAsync({
184
+ Url: 'https://other.com/notify',
185
+ PostParam: { Id: V8.Param.id },
186
+ Timeout: 10
187
+ });
188
+ return resp.StatusCode >= 200 && resp.StatusCode < 300
189
+ ? { Code: 1 }
190
+ : { Code: 0, Msg: '通知失败' };
191
+ ```
192
+
193
+ 禁止用 `setTimeout` / `Task.Run` 实现“立即返回、后台继续”:接口返回后 Jint Engine、租户上下文、事务和执行租约会释放。脱离请求的任务使用后台任务、Job、MQ 或 outbox,并按 `EventId` 幂等处理与恢复。
194
194
 
195
195
  <!-- /microi-progressive:chunk -->
196
196
  <!-- microi-progressive:chunk id=v8-crud-api-013 sha256=d4d96c1d82d1fba71100919ff7b0d48441610fdef4602097723cffdcdaaeebf4 -->
@@ -200,7 +200,7 @@ return resp.StatusCode >= 200 && resp.StatusCode < 300
200
200
  V8.FormEngine.AddField({
201
201
  TableName: 'diy_test',
202
202
  Name: 'Age',
203
- Type: 'int', // 仅使用平台允许的varchar(N)/mediumtext/longtext/int/bigint/decimal(18,N)
203
+ Type: 'int', // 仅使用平台允许的varchar(N)/mediumtext/longtext/int/bigint/decimal(18,N)
204
204
  Label: '年龄',
205
205
  Component: 'NumberText',
206
206
  TableWidth: '100',
@@ -208,9 +208,9 @@ V8.FormEngine.AddField({
208
208
  });
209
209
  ```
210
210
 
211
- > 风险:会执行 DDL(ALTER TABLE)。仅在低代码自定义配置场景使用,业务运行时**不要**频繁调用。
212
-
213
- 日期时间字段统一使用 `varchar(25)` 保存 `yyyy-MM-dd HH:mm:ss`,组件使用 `DateTime`。禁止 `datetime/date/timestamp/float/double/boolean/string/text/nvarchar` 等平台不允许的物理类型。动态表/字段属于控制面能力,只允许 `Level >= 9999` 的可信管理脚本使用。
211
+ > 风险:会执行 DDL(ALTER TABLE)。仅在低代码自定义配置场景使用,业务运行时**不要**频繁调用。
212
+
213
+ 日期时间字段统一使用 `varchar(25)` 保存 `yyyy-MM-dd HH:mm:ss`,组件使用 `DateTime`。禁止 `datetime/date/timestamp/float/double/boolean/string/text/nvarchar` 等平台不允许的物理类型。动态表/字段属于控制面能力,只允许 `Level >= 9999` 的可信管理脚本使用。
214
214
 
215
215
  <!-- /microi-progressive:chunk -->
216
216
  <!-- microi-progressive:chunk id=v8-crud-api-014 sha256=42b43027eb510916aed85a3a21ea8a1c1c7697581ac8c48863e8ba8d0c793784 -->
@@ -1,34 +1,34 @@
1
1
  ---
2
2
  name: v8-debugging
3
- description: Microi V8 调试与日志指南。用于排查接口引擎、V8 事件、console.log、DataAppend.DebugLog、sys_log、异常处理和远程执行问题。
3
+ description: Microi V8 调试与日志指南。用于排查接口引擎、V8 事件、console.log、DataAppend.DebugLog、sys_log、异常处理和远程执行问题。
4
4
  ---
5
5
 
6
6
  > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
7
7
 
8
- # Microi V8 调试与日志
9
-
10
- 你正在为 Microi 吾码平台编写 V8 引擎代码,需要在开发/测试/生产环境进行排错。本指南提供调试模式、异常捕获、系统日志、调试输出的标准做法。
11
-
12
- 系统级排查优先读取 `../system-observability/SKILL.md` 并通过 `microi_query_system_observability` 查询统一日志、统计、详情、Trace、热点接口和运行数据;`microi_query_mongodb_logs` 仅保留给只需要旧 Mongo 日志列表的兼容场景。两者都必须限制租户、时间窗、页大小和返回字段,不在结果或回答中输出 Token、连接串、Secret 或完整敏感请求体。
8
+ # Microi V8 调试与日志
9
+
10
+ 你正在为 Microi 吾码平台编写 V8 引擎代码,需要在开发/测试/生产环境进行排错。本指南提供调试模式、异常捕获、系统日志、调试输出的标准做法。
11
+
12
+ 系统级排查优先读取 `../system-observability/SKILL.md` 并通过 `microi_query_system_observability` 查询统一日志、统计、详情、Trace、热点接口和运行数据;`microi_query_mongodb_logs` 仅保留给只需要旧 Mongo 日志列表的兼容场景。两者都必须限制租户、时间窗、页大小和返回字段,不在结果或回答中输出 Token、连接串、Secret 或完整敏感请求体。
13
13
 
14
14
  ## 三种输出通道
15
15
 
16
16
  | 通道 | 何处看 | 用途 |
17
17
  |------|--------|------|
18
- | 后端 V8 的 `console.log` / `console.error` | 租户系统日志(MongoDB);MCP/调试执行同时返回当次 `ConsoleOutput` | 临时诊断、性能日志 |
18
+ | 后端 V8 的 `console.log` / `console.error` | 租户系统日志(MongoDB);MCP/调试执行同时返回当次 `ConsoleOutput` | 临时诊断、性能日志 |
19
19
  | `DataAppend.DebugLog`(返回给前端) | 浏览器开发者工具 / Postman 响应 | 当次请求的关键节点、变量值 |
20
20
  | `V8.Method.AddSysLog({...})` | 系统日志页 / `sys_log` 表 | 业务操作审计、第三方回调记录 |
21
21
 
22
22
  ## 调试模式 isDebugLog
23
23
 
24
- 调试开关必须同时满足“服务端允许调试 + 当前用户 `Level >= 9999`”。不能只相信 URL/query 的 `isDebugLog=1`,匿名或普通用户否则可获得内部数据与堆栈。
24
+ 调试开关必须同时满足“服务端允许调试 + 当前用户 `Level >= 9999`”。不能只相信 URL/query 的 `isDebugLog=1`,匿名或普通用户否则可获得内部数据与堆栈。
25
25
 
26
26
  ```javascript
27
- var isAdmin = V8.CurrentUser && Number(V8.CurrentUser.Level || 0) >= 9999;
28
- var isDebugLog = isAdmin &&
29
- V8.SysConfig &&
30
- V8.SysConfig.EnableV8Debug === 1 &&
31
- (V8.Param.isDebugLog === '1' || V8.Param.isDebugLog === true);
27
+ var isAdmin = V8.CurrentUser && Number(V8.CurrentUser.Level || 0) >= 9999;
28
+ var isDebugLog = isAdmin &&
29
+ V8.SysConfig &&
30
+ V8.SysConfig.EnableV8Debug === 1 &&
31
+ (V8.Param.isDebugLog === '1' || V8.Param.isDebugLog === true);
32
32
  var debugLog = [];
33
33
  function dbg(msg, data) {
34
34
  if (!isDebugLog) return;
@@ -39,10 +39,10 @@ function dbg(msg, data) {
39
39
  });
40
40
  }
41
41
 
42
- dbg('开始查询参数', {
43
- Keyword: String(V8.Param.Keyword || '').substring(0, 100),
44
- PageIndex: V8.Param.PageIndex
45
- });
42
+ dbg('开始查询参数', {
43
+ Keyword: String(V8.Param.Keyword || '').substring(0, 100),
44
+ PageIndex: V8.Param.PageIndex
45
+ });
46
46
 
47
47
  var products = V8.FormEngine.GetTableData('Product', {
48
48
  _Where: [['Status', '=', 1]]
@@ -58,61 +58,61 @@ return {
58
58
  };
59
59
  ```
60
60
 
61
- 管理员在服务端显式开启调试后,才可用 `?isDebugLog=1` 查看当次请求的脱敏节点日志。生产环境默认关闭,调试完成后立即关闭。
62
-
63
- ## Jint 内存上限错误
64
-
65
- 出现 `Script has allocated ... but is limited to ...` 时,不要把它解释为
66
- 数据库返回数据的实际大小,也不要直接关闭内存限制。
67
-
68
- - Jint `LimitMemory` 使用当前执行线程的**累计托管分配字节数**,不是当前
69
- 存活堆或进程工作集;中间对象即使已经被 GC 回收,累计值也不会减少。
70
- - 平台必须在宿主对象、扩展和全局 V8 准备完成后调用
71
- `engine.Constraints.Reset()`,让全局 V8 和当前接口 V8 各自获得完整预算;
72
- 用户脚本以及脚本调用的 CLR/FormEngine 逻辑仍受同一阶段预算限制。
73
- - 默认单次执行预算为 2048 MB,默认节点硬上限为 8192 MB;根调用树默认
74
- 8192 MB、节点硬上限 32768 MB。存量接口仅把仍等于
75
- 历史默认值 1024 MB 的记录迁移到 2048 MB;客户明确设置的其它值不覆盖。
76
- - 旧版嵌套接口会让子引擎的初始化、查询、JSON 和业务分配被每一层父引擎
77
- 重复计数,因此四层、少量数据也可能提前触发 2GB。新版默认启用父子单层
78
- 预算隔离,每层独立计数,同时由根调用树默认 8192MB 的总预算兜底。
79
- - `LimitRecursion` 只限制当前 JavaScript 函数递归,不限制
80
- `V8.ApiEngine.Run` 层数;接口嵌套默认 32、节点硬上限默认 64。
81
- - 排查时记录 `ApiEngineKey`、实际 `LimitMemory`、返回行数、选择字段、
82
- 分页大小、`V8.Limits`、`DataAppend.V8Limit` 调用路径和重现脚本。若
83
- 2048 MB 仍触发,继续减少一次性对象图、流式或
84
- 分批处理;不得把上限无限提高或取消。
85
- - `V8_MEMORY_LIMIT` 表示单层预算,`V8_CALL_TREE_MEMORY_LIMIT` 表示整棵
86
- 调用树,`V8_STATEMENTS_LIMIT`、`V8_RECURSION_LIMIT`、`V8_TIMEOUT`、
87
- `V8_NESTED_DEPTH_LIMIT` 和 `V8_EXECUTION_QUEUE_TIMEOUT` 必须分别处理。
88
- - 后台任务总时长可以超过 10/30 分钟,但单片仍受上述预算;使用
89
- `HasMore + Checkpoint` 续跑,不要只提高单次超时或内存。
90
- - 接口引擎的正向开关是 `sys_apiengine.V8Limit`:默认关闭时
91
- `V8.Limits.UnlimitedRuntime=true`,打开后才应用超时、语句、函数递归、
92
- 累计分配和 Promise 等待限制。表后端事件同样使用正向 `diy_table.V8Limit`:
93
- 缺失、`null`、`0/false` 不设置单次预算,只有 `1/true` 才启用限制;旧
94
- `V8Unlimited` 仅在新字段不存在时反向兼容。
95
- 常驻内存保护、外部取消、并发、接口嵌套深度、权限沙箱与数据库限制始终
96
- 生效;两类开关都只能来自持久化可信元数据,不能从请求参数启用。
97
- - 服务端另有一个内置受信任特例:主租户中由持久队列恢复的
98
- `import-microi-store-package`:必须同时具备可信用户快照、`Level >= 9999`
99
- 和 TaskId,才允许 `V8.Limits.MemoryAccounting=ResidentMemoryGuardOnly`。
100
- 此模式不是“无限内存”,而是改用容器优先的进程 RSS 防线:95% 拒绝新工作、
101
- 98% 有界停机;导入器仍必须按资产分片并可从 checkpoint 幂等恢复。前台调用、
102
- 子租户或其它 Key 看到该模式都属于安全缺陷。
103
- - 回归至少验证 Jint 包版本、约束重置、默认/硬上限,以及 400 行左右普通
104
- FormEngine 查询与数据加工不会被平台准备阶段的累计分配误伤。
105
-
106
- ## try/catch 异常捕获 + 详情上报
61
+ 管理员在服务端显式开启调试后,才可用 `?isDebugLog=1` 查看当次请求的脱敏节点日志。生产环境默认关闭,调试完成后立即关闭。
62
+
63
+ ## Jint 内存上限错误
64
+
65
+ 出现 `Script has allocated ... but is limited to ...` 时,不要把它解释为
66
+ 数据库返回数据的实际大小,也不要直接关闭内存限制。
67
+
68
+ - Jint `LimitMemory` 使用当前执行线程的**累计托管分配字节数**,不是当前
69
+ 存活堆或进程工作集;中间对象即使已经被 GC 回收,累计值也不会减少。
70
+ - 平台必须在宿主对象、扩展和全局 V8 准备完成后调用
71
+ `engine.Constraints.Reset()`,让全局 V8 和当前接口 V8 各自获得完整预算;
72
+ 用户脚本以及脚本调用的 CLR/FormEngine 逻辑仍受同一阶段预算限制。
73
+ - 默认单次执行预算为 2048 MB,默认节点硬上限为 8192 MB;根调用树默认
74
+ 8192 MB、节点硬上限 32768 MB。存量接口仅把仍等于
75
+ 历史默认值 1024 MB 的记录迁移到 2048 MB;客户明确设置的其它值不覆盖。
76
+ - 旧版嵌套接口会让子引擎的初始化、查询、JSON 和业务分配被每一层父引擎
77
+ 重复计数,因此四层、少量数据也可能提前触发 2GB。新版默认启用父子单层
78
+ 预算隔离,每层独立计数,同时由根调用树默认 8192MB 的总预算兜底。
79
+ - `LimitRecursion` 只限制当前 JavaScript 函数递归,不限制
80
+ `V8.ApiEngine.Run` 层数;接口嵌套默认 32、节点硬上限默认 64。
81
+ - 排查时记录 `ApiEngineKey`、实际 `LimitMemory`、返回行数、选择字段、
82
+ 分页大小、`V8.Limits`、`DataAppend.V8Limit` 调用路径和重现脚本。若
83
+ 2048 MB 仍触发,继续减少一次性对象图、流式或
84
+ 分批处理;不得把上限无限提高或取消。
85
+ - `V8_MEMORY_LIMIT` 表示单层预算,`V8_CALL_TREE_MEMORY_LIMIT` 表示整棵
86
+ 调用树,`V8_STATEMENTS_LIMIT`、`V8_RECURSION_LIMIT`、`V8_TIMEOUT`、
87
+ `V8_NESTED_DEPTH_LIMIT` 和 `V8_EXECUTION_QUEUE_TIMEOUT` 必须分别处理。
88
+ - 后台任务总时长可以超过 10/30 分钟,但单片仍受上述预算;使用
89
+ `HasMore + Checkpoint` 续跑,不要只提高单次超时或内存。
90
+ - 接口引擎的正向开关是 `sys_apiengine.V8Limit`:默认关闭时
91
+ `V8.Limits.UnlimitedRuntime=true`,打开后才应用超时、语句、函数递归、
92
+ 累计分配和 Promise 等待限制。表后端事件同样使用正向 `diy_table.V8Limit`:
93
+ 缺失、`null`、`0/false` 不设置单次预算,只有 `1/true` 才启用限制;旧
94
+ `V8Unlimited` 仅在新字段不存在时反向兼容。
95
+ 常驻内存保护、外部取消、并发、接口嵌套深度、权限沙箱与数据库限制始终
96
+ 生效;两类开关都只能来自持久化可信元数据,不能从请求参数启用。
97
+ - 服务端另有一个内置受信任特例:主租户中由持久队列恢复的
98
+ `import-microi-store-package`:必须同时具备可信用户快照、`Level >= 9999`
99
+ 和 TaskId,才允许 `V8.Limits.MemoryAccounting=ResidentMemoryGuardOnly`。
100
+ 此模式不是“无限内存”,而是改用容器优先的进程 RSS 防线:95% 拒绝新工作、
101
+ 98% 有界停机;导入器仍必须按资产分片并可从 checkpoint 幂等恢复。前台调用、
102
+ 子租户或其它 Key 看到该模式都属于安全缺陷。
103
+ - 回归至少验证 Jint 包版本、约束重置、默认/硬上限,以及 400 行左右普通
104
+ FormEngine 查询与数据加工不会被平台准备阶段的累计分配误伤。
105
+
106
+ ## try/catch 异常捕获 + 详情上报
107
107
 
108
108
  ```javascript
109
109
  try {
110
110
  var r = V8.Http.Post({
111
111
  Url: 'https://api.partner.com/sync',
112
- PostParam: {
113
- Id: V8.Param.Id,
114
- Action: V8.Param.Action
115
- },
112
+ PostParam: {
113
+ Id: V8.Param.Id,
114
+ Action: V8.Param.Action
115
+ },
116
116
  ParamType: 'json',
117
117
  Timeout: 30
118
118
  });
@@ -120,11 +120,11 @@ try {
120
120
  throw new Error('合作方接口失败:' + r);
121
121
  }
122
122
  return { Code: 1, Data: JSON.parse(r) };
123
- } catch (ex) {
124
- // 完整异常信息
125
- var traceId = V8.Method.NewUlid();
126
- var errorDetails = {
127
- traceId: traceId,
123
+ } catch (ex) {
124
+ // 完整异常信息
125
+ var traceId = V8.Method.NewUlid();
126
+ var errorDetails = {
127
+ traceId: traceId,
128
128
  message: ex.message,
129
129
  stack: ex.stack,
130
130
  line: ex.lineNumber,
@@ -143,8 +143,8 @@ try {
143
143
 
144
144
  return {
145
145
  Code: 0,
146
- Msg: '同步失败,请按追踪号查询日志',
147
- DataAppend: isDebugLog ? { TraceId: traceId } : null
146
+ Msg: '同步失败,请按追踪号查询日志',
147
+ DataAppend: isDebugLog ? { TraceId: traceId } : null
148
148
  };
149
149
  }
150
150
  ```
@@ -164,67 +164,67 @@ V8.Method.AddSysLog({
164
164
  });
165
165
  ```
166
166
 
167
- 日志保存在按租户、月份拆分的 MongoDB 系统日志集合中,可在系统日志菜单查看并按 Type 过滤。所有 `AddSysLog` 调用统一进入后端异步队列,由后台批量写 MongoDB;批次先写本地 spool,MongoDB 故障和正常重启后自动幂等重放,因此业务请求不得自行启动线程或直接并发写 MongoDB。
168
-
169
- - 容器环境把固定目录 `logs/syslog-spool` 挂载到持久卷,不为路径增加环境变量。
170
- - 分布式部署的节点标识由平台自动生成;所有节点写同一 MongoDB 时仍按全局 `EventId` upsert。详情状态和私有文件票据存共享 Redis,本机内存只作故障兜底,不能依赖粘性会话。
171
- - 多节点可能同时观察到的菜单、详情关闭、附件分片和登录生命周期事件要使用确定性 `EventId`,不能只靠本机字典去重;服务正常停止会落盘排空,重启会自动重放。
172
- - 平台用户行为统一使用结构化字段 `Category`、`Action`、`Source`、`TargetType`、`TargetId`、`SessionId`、`DurationSeconds`、`Success`、`OccurredAt`。
173
- - 用户显示采用 `Name(Account)`;禁止记录密码、原始 Token、Authorization、Secret、ApiKey、连接字符串,内容还必须限长。
174
- - 前端只能上报纯 UI 行为信号;菜单访问、CRUD、导入导出、登录生命周期、私有文件实际访问等必须以后端真实执行点为事实源。
175
-
176
- ### 匿名登录/第三方授权接口的追踪日志
177
-
178
- 微信手机号、OAuth、短信快捷登录等匿名接口必须生成追踪号并按阶段记录失败。开发者工具成功不能替代体验版/真机验证。
179
-
180
- ```javascript
181
- var traceId = V8.Method.NewGuid().replace(/-/g, '').substring(0, 16);
182
-
183
- function fail(stage, message, detail) {
184
- V8.Method.AddSysLog({
185
- Type: 'ThirdPartyLogin',
186
- Title: '授权登录失败[' + stage + '][' + traceId + ']',
187
- Content: JSON.stringify({
188
- TraceId: traceId,
189
- Stage: stage,
190
- Message: message,
191
- Detail: detail || {},
192
- OsClient: V8.OsClient
193
- }),
194
- Remark: traceId,
195
- Level: 3
196
- });
197
- return { Code: 0, Msg: '授权登录失败(' + stage + '):' + message + ';追踪号:' + traceId };
198
- }
199
- ```
200
-
201
- - 在身份交换、AccessToken、手机号/用户资料交换、账号匹配、注册/更新、Token 签发前维护明确阶段名,所有显式失败和顶层 `catch` 都走同一个 `fail`。
202
- - 日志保留第三方 `errcode/errmsg`,但先脱敏;禁止记录 Secret、AccessToken、授权 code、LoginCode、OpenId、完整手机号和用户 Token。
203
- - `V8.Method.AddSysLog` 写 MongoDB 系统日志,适合 `Code=0` 仍需保留的结构化失败记录;`console.error` 也按当前 `OsClient` 进入 MongoDB,但不替代带追踪号的业务审计日志。
204
- - 前端响应显示同一个追踪号,排查时先按追踪号查系统日志,再结合第三方错误码定位。
205
-
206
- ## 后端 V8 console 的去向
207
-
208
- - 普通接口引擎和表单后端 V8 的 `console.log/info/warn/error` 按租户写入 MongoDB 系统日志,`Source/TargetType` 为 `V8`,可按接口 Key 或事件名定位。
209
- - MCP 远程执行和 V8 调试会通过请求级上下文捕获当次输出并返回 `ConsoleOutput`;不得用进程级 `Console.SetOut`,否则并发请求会互相截取日志。
210
- - Docker/服务器控制台只保留影响平台启动、主租户、日志管道或进程存活的关键日志,不再作为普通 V8 调试日志入口。
211
- - 前端 V8 的 `console.log` 仍在浏览器开发者工具中查看,与后端日志通道无关。
167
+ 日志保存在按租户、月份拆分的 MongoDB 系统日志集合中,可在系统日志菜单查看并按 Type 过滤。所有 `AddSysLog` 调用统一进入后端异步队列,由后台批量写 MongoDB;批次先写本地 spool,MongoDB 故障和正常重启后自动幂等重放,因此业务请求不得自行启动线程或直接并发写 MongoDB。
168
+
169
+ - 容器环境把固定目录 `logs/syslog-spool` 挂载到持久卷,不为路径增加环境变量。
170
+ - 分布式部署的节点标识由平台自动生成;所有节点写同一 MongoDB 时仍按全局 `EventId` upsert。详情状态和私有文件票据存共享 Redis,本机内存只作故障兜底,不能依赖粘性会话。
171
+ - 多节点可能同时观察到的菜单、详情关闭、附件分片和登录生命周期事件要使用确定性 `EventId`,不能只靠本机字典去重;服务正常停止会落盘排空,重启会自动重放。
172
+ - 平台用户行为统一使用结构化字段 `Category`、`Action`、`Source`、`TargetType`、`TargetId`、`SessionId`、`DurationSeconds`、`Success`、`OccurredAt`。
173
+ - 用户显示采用 `Name(Account)`;禁止记录密码、原始 Token、Authorization、Secret、ApiKey、连接字符串,内容还必须限长。
174
+ - 前端只能上报纯 UI 行为信号;菜单访问、CRUD、导入导出、登录生命周期、私有文件实际访问等必须以后端真实执行点为事实源。
175
+
176
+ ### 匿名登录/第三方授权接口的追踪日志
177
+
178
+ 微信手机号、OAuth、短信快捷登录等匿名接口必须生成追踪号并按阶段记录失败。开发者工具成功不能替代体验版/真机验证。
179
+
180
+ ```javascript
181
+ var traceId = V8.Method.NewGuid().replace(/-/g, '').substring(0, 16);
182
+
183
+ function fail(stage, message, detail) {
184
+ V8.Method.AddSysLog({
185
+ Type: 'ThirdPartyLogin',
186
+ Title: '授权登录失败[' + stage + '][' + traceId + ']',
187
+ Content: JSON.stringify({
188
+ TraceId: traceId,
189
+ Stage: stage,
190
+ Message: message,
191
+ Detail: detail || {},
192
+ OsClient: V8.OsClient
193
+ }),
194
+ Remark: traceId,
195
+ Level: 3
196
+ });
197
+ return { Code: 0, Msg: '授权登录失败(' + stage + '):' + message + ';追踪号:' + traceId };
198
+ }
199
+ ```
200
+
201
+ - 在身份交换、AccessToken、手机号/用户资料交换、账号匹配、注册/更新、Token 签发前维护明确阶段名,所有显式失败和顶层 `catch` 都走同一个 `fail`。
202
+ - 日志保留第三方 `errcode/errmsg`,但先脱敏;禁止记录 Secret、AccessToken、授权 code、LoginCode、OpenId、完整手机号和用户 Token。
203
+ - `V8.Method.AddSysLog` 写 MongoDB 系统日志,适合 `Code=0` 仍需保留的结构化失败记录;`console.error` 也按当前 `OsClient` 进入 MongoDB,但不替代带追踪号的业务审计日志。
204
+ - 前端响应显示同一个追踪号,排查时先按追踪号查系统日志,再结合第三方错误码定位。
205
+
206
+ ## 后端 V8 console 的去向
207
+
208
+ - 普通接口引擎和表单后端 V8 的 `console.log/info/warn/error` 按租户写入 MongoDB 系统日志,`Source/TargetType` 为 `V8`,可按接口 Key 或事件名定位。
209
+ - MCP 远程执行和 V8 调试会通过请求级上下文捕获当次输出并返回 `ConsoleOutput`;不得用进程级 `Console.SetOut`,否则并发请求会互相截取日志。
210
+ - Docker/服务器控制台只保留影响平台启动、主租户、日志管道或进程存活的关键日志,不再作为普通 V8 调试日志入口。
211
+ - 前端 V8 的 `console.log` 仍在浏览器开发者工具中查看,与后端日志通道无关。
212
212
 
213
213
  ## 性能跟踪(毫秒级耗时)
214
214
 
215
215
  ```javascript
216
- var t0 = Date.now();
216
+ var t0 = Date.now();
217
217
 
218
218
  var step1 = V8.FormEngine.GetTableData('Big', { _PageSize: 5000 });
219
- var t1 = Date.now();
219
+ var t1 = Date.now();
220
220
 
221
221
  var step2 = V8.Db.FromSql('SELECT COUNT(*) FROM Order').ToScalar();
222
- var t2 = Date.now();
222
+ var t2 = Date.now();
223
223
 
224
224
  dbg('耗时', { step1Ms: t1 - t0, step2Ms: t2 - t1, totalMs: t2 - t0 });
225
225
  ```
226
226
 
227
- ## 前端调试
227
+ ## 前端调试
228
228
 
229
229
  ```javascript
230
230
  // 前端 V8 事件中
@@ -234,31 +234,31 @@ console.error('校验失败', V8.Form);
234
234
 
235
235
  // 在浏览器开发者工具控制台查看
236
236
  // 或显式弹层:
237
- V8.Tips('调试: ' + JSON.stringify(V8.Form), true);
238
- ```
239
-
240
- ## VS Code 插件输出约定
241
-
242
- Microi VS Code 插件的右下角信息、警告和错误通知必须同步写入【输出 → Microi 吾码】,让构建、推送、拉取、登录、同步和调试结果在通知消失后仍可追溯。输出时间使用运行 VS Code 电脑的本地时区,格式统一为 `yyyy-MM-dd HH:mm:ss`,禁止直接使用 `toISOString()` 造成 UTC 时间偏差。
243
-
244
- - 后台 Token/会话维护等静默健康探测设置 `silent=true` 后,预期的网络不可达不得反复写成红色错误。
245
- - 用户主动执行拉取、推送或状态检查时,网络错误必须保留错误码、系统调用、地址、端口及聚合错误明细;禁止出现只有 `Error:`、没有原因的空日志。
246
- - 所有右下角通知统一经过通知封装写入输出;带操作按钮的通知还应记录用户选择,禁止业务模块直接调用 `vscode.window.showInformationMessage/showWarningMessage/showErrorMessage` 绕过持久日志。
247
-
248
- ## 不要在生产泄漏敏感信息
237
+ V8.Tips('调试: ' + JSON.stringify(V8.Form), true);
238
+ ```
239
+
240
+ ## VS Code 插件输出约定
241
+
242
+ Microi VS Code 插件的右下角信息、警告和错误通知必须同步写入【输出 → Microi 吾码】,让构建、推送、拉取、登录、同步和调试结果在通知消失后仍可追溯。输出时间使用运行 VS Code 电脑的本地时区,格式统一为 `yyyy-MM-dd HH:mm:ss`,禁止直接使用 `toISOString()` 造成 UTC 时间偏差。
243
+
244
+ - 后台 Token/会话维护等静默健康探测设置 `silent=true` 后,预期的网络不可达不得反复写成红色错误。
245
+ - 用户主动执行拉取、推送或状态检查时,网络错误必须保留错误码、系统调用、地址、端口及聚合错误明细;禁止出现只有 `Error:`、没有原因的空日志。
246
+ - 所有右下角通知统一经过通知封装写入输出;带操作按钮的通知还应记录用户选择,禁止业务模块直接调用 `vscode.window.showInformationMessage/showWarningMessage/showErrorMessage` 绕过持久日志。
247
+
248
+ ## 不要在生产泄漏敏感信息
249
249
 
250
250
  ```javascript
251
251
  // ❌ 危险:返回给前端
252
252
  return { Code: 0, Msg: ex.message, DataAppend: { Stack: ex.stack } };
253
253
 
254
- // ✅ 只返回关联ID;完整堆栈仅写内部日志
255
- var traceId = V8.Method.NewUlid();
256
- console.error('traceId=' + traceId + ' error=' + ex.message);
257
- return {
258
- Code: 0,
259
- Msg: '系统繁忙',
260
- DataAppend: { TraceId: traceId }
261
- };
254
+ // ✅ 只返回关联ID;完整堆栈仅写内部日志
255
+ var traceId = V8.Method.NewUlid();
256
+ console.error('traceId=' + traceId + ' error=' + ex.message);
257
+ return {
258
+ Code: 0,
259
+ Msg: '系统繁忙',
260
+ DataAppend: { TraceId: traceId }
261
+ };
262
262
  ```
263
263
 
264
264
  ## DosResult 状态码速查