@microi.net/cli 5.5.9 → 5.6.1

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 (161) 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/.workbuddy-plugin/marketplace.json +2 -2
  5. package/.workbuddy-plugin/plugin.json +1 -1
  6. package/assets/build-meta.json +5 -5
  7. package/cordis.patch.yml +1 -1
  8. package/package.json +1 -1
  9. package/scripts/mcp-server.js +99 -99
  10. package/scripts/microi-cli.js +39 -36
  11. package/scripts/microi-skills.meta.json +341 -338
  12. package/skills/.microi-skills-version.json +2 -2
  13. package/skills/.progressive-disclosure-manifest.json +3566 -3566
  14. package/skills/README.md +4 -4
  15. package/skills/ai-engine/SKILL.md +45 -45
  16. package/skills/ai-platform-governance/SKILL.md +177 -177
  17. package/skills/ai-platform-governance/references/progressive-01-/345/212/237/350/203/275/345/274/200/345/205/263.md +190 -190
  18. package/skills/app-store/SKILL.md +21 -4
  19. package/skills/business-blueprint/SKILL.md +85 -85
  20. package/skills/datasource-engine/SKILL.md +91 -91
  21. package/skills/dos-orm/SKILL.md +15 -0
  22. package/skills/dos-orm/references/api-reference.md +229 -229
  23. package/skills/email-engine/SKILL.md +80 -80
  24. package/skills/email-engine/references/v8-email.md +34 -34
  25. package/skills/job-engine/SKILL.md +154 -154
  26. package/skills/message-notification/SKILL.md +27 -1
  27. package/skills/message-notification/agents/openai.yaml +5 -5
  28. package/skills/message-notification/references/contracts.md +102 -102
  29. package/skills/microi-ai-app-auth.js +652 -652
  30. package/skills/microi-ai-application/SKILL.md +102 -102
  31. package/skills/microi-ai-application/agents/openai.yaml +4 -4
  32. package/skills/microi-ai-application/references/frontend-baseline.md +164 -164
  33. package/skills/microi-client-frontend/SKILL.md +47 -41
  34. 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 +4 -4
  35. 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 +30 -30
  36. 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 +58 -58
  37. package/skills/microi-codex/SKILL.md +2 -0
  38. package/skills/microi-codex-installer/SKILL.md +216 -216
  39. package/skills/microi-codex-installer/agents/openai.yaml +7 -7
  40. package/skills/microi-datasource-mapping/SKILL.md +67 -67
  41. package/skills/microi-db-schema/SKILL.md +6 -6
  42. package/skills/microi-db-schema/references/core-tables.md +18 -18
  43. package/skills/microi-db-schema/references/form-component-options.md +256 -256
  44. package/skills/microi-db-schema/references/schema-overview.md +11 -11
  45. package/skills/microi-db-schema/references/schema.md +46 -46
  46. package/skills/microi-db-schema/references/table-catalog.md +57 -57
  47. package/skills/microi-deployment/SKILL.md +18 -1
  48. package/skills/microi-deployment/references/deployment-matrix.md +101 -101
  49. package/skills/microi-docs-coverage/SKILL.md +10 -0
  50. package/skills/microi-docs-coverage/references/capability-map.md +3 -2
  51. package/skills/microi-docs-coverage/scripts/audit-doc-skill-coverage.mjs +894 -894
  52. package/skills/microi-form-engine/SKILL.md +27 -3
  53. package/skills/microi-form-engine/references/component-catalog.md +218 -218
  54. package/skills/microi-form-engine/references/data-source-events.md +124 -124
  55. package/skills/microi-form-layout/SKILL.md +13 -13
  56. 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
  57. package/skills/microi-frontend-sdk/SKILL.md +4 -4
  58. 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
  59. package/skills/microi-left-right-layout/SKILL.md +141 -141
  60. package/skills/microi-microservice/SKILL.md +2 -1
  61. package/skills/microi-microservice/references/runtime-delivery.md +278 -278
  62. 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
  63. package/skills/microi-solution-quotation/SKILL.md +78 -78
  64. package/skills/microi-solution-quotation/agents/openai.yaml +4 -4
  65. package/skills/microi-solution-quotation/scripts/build_solution_quote.py +296 -296
  66. package/skills/microi-sso/SKILL.md +6 -0
  67. package/skills/microi-sso/references/acceptance.md +49 -49
  68. package/skills/microi-sso/references/configuration-and-security.md +53 -53
  69. package/skills/microi-sso/references/inbound.md +53 -53
  70. package/skills/microi-sso/references/outbound.md +39 -39
  71. package/skills/microi-system-delivery/SKILL.md +5 -4
  72. 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 +7 -2
  73. package/skills/microi-ui/SKILL.md +7 -2
  74. package/skills/microi-uniapp-frontend/SKILL.md +134 -134
  75. 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
  76. 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
  77. package/skills/module-engine/SKILL.md +30 -14
  78. package/skills/ocr-engine/SKILL.md +2 -2
  79. package/skills/ocr-engine/agents/openai.yaml +1 -1
  80. package/skills/page-engine/SKILL.md +28 -28
  81. 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
  82. 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
  83. package/skills/performance-testing/SKILL.md +120 -120
  84. package/skills/playwright-e2e/SKILL.md +84 -84
  85. 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
  86. 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
  87. package/skills/playwright-e2e/references/progressive-03-microi-helper-/346/250/241/346/235/277.md +20 -20
  88. package/skills/playwright-e2e/references/progressive-04-ci-/345/273/272/350/256/256.md +69 -69
  89. package/skills/print-engine/SKILL.md +11 -3
  90. package/skills/production-readonly-audit/SKILL.md +41 -41
  91. package/skills/report-engine/SKILL.md +71 -71
  92. package/skills/scripts/optimize-progressive-disclosure.mjs +204 -204
  93. package/skills/scripts/refresh-progressive-disclosure.mjs +64 -64
  94. package/skills/scripts/sync-embedded-skills.mjs +46 -0
  95. package/skills/scripts/validate-progressive-disclosure.mjs +8 -3
  96. package/skills/search-engine/SKILL.md +75 -75
  97. package/skills/spider-engine/SKILL.md +190 -190
  98. package/skills/system-observability/SKILL.md +169 -157
  99. package/skills/system-observability/references/memory-incident-triage.md +73 -73
  100. package/skills/translate-engine/SKILL.md +1 -1
  101. package/skills/ui-design/SKILL.md +3 -1
  102. package/skills/uniapp-mall-assets/SKILL.md +170 -170
  103. package/skills/unity-integration/SKILL.md +155 -155
  104. package/skills/unity-integration/agents/openai.yaml +4 -4
  105. package/skills/unity-integration/references/ai-app-delivery.md +103 -103
  106. package/skills/unity-integration/references/sdk-api.md +82 -82
  107. package/skills/unity-integration/references/toolbox-migration.md +66 -66
  108. package/skills/unity-integration/references/webgl-hosting.md +57 -57
  109. package/skills/v8-api-config/SKILL.md +4 -0
  110. package/skills/v8-cache-pattern/SKILL.md +306 -306
  111. package/skills/v8-crud-api/SKILL.md +29 -29
  112. 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
  113. package/skills/v8-debugging/SKILL.md +143 -143
  114. package/skills/v8-explorer-tree/SKILL.md +64 -64
  115. 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
  116. package/skills/v8-export-import/references/progressive-02-powerpoint-/345/257/274/345/207/272.md +118 -118
  117. 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
  118. package/skills/v8-file-upload/SKILL.md +5 -2
  119. 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 +2 -2
  120. 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
  121. package/skills/v8-formengine-http/SKILL.md +126 -108
  122. package/skills/v8-frontend-events/SKILL.md +22 -22
  123. package/skills/v8-frontend-events/references/bluetooth-print-api.md +135 -135
  124. package/skills/v8-frontend-events/references/bluetooth-print.md +247 -247
  125. package/skills/v8-frontend-events/references/progressive-01-/345/210/227/350/241/250/344/272/213/344/273/266.md +50 -50
  126. package/skills/v8-http-integration/SKILL.md +106 -106
  127. package/skills/v8-http-integration/references/progressive-01-get-/350/257/267/346/261/202.md +31 -31
  128. 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
  129. package/skills/v8-image-processing/SKILL.md +190 -190
  130. package/skills/v8-image-processing/agents/openai.yaml +4 -4
  131. package/skills/v8-image-processing/references/api-reference.md +623 -623
  132. package/skills/v8-menu-buttons/SKILL.md +103 -103
  133. 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
  134. 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
  135. 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
  136. package/skills/v8-mongodb/SKILL.md +65 -65
  137. package/skills/v8-mq-mqtt/SKILL.md +175 -175
  138. package/skills/v8-mq-mqtt/references/mqtt-production.md +342 -342
  139. package/skills/v8-mq-mqtt/references/progressive-01-v8-mqtt-iot-/347/211/251/350/201/224/347/275/221.md +137 -137
  140. package/skills/v8-mq-mqtt/scripts/check-mqtt-skill-coverage.mjs +203 -203
  141. package/skills/v8-saas-multi-tenant/SKILL.md +223 -223
  142. package/skills/v8-security/SKILL.md +1 -1
  143. package/skills/v8-security/references/progressive-01-2-/346/235/203/351/231/220/346/240/241/351/252/214.md +122 -122
  144. package/skills/v8-sql-query/SKILL.md +7 -5
  145. package/skills/v8-table-event/SKILL.md +9 -2
  146. 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 +1 -1
  147. 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
  148. package/skills/v8-tcp-integration/SKILL.md +1 -1
  149. package/skills/v8-tcp-integration/agents/openai.yaml +4 -4
  150. package/skills/v8-template-engine/SKILL.md +59 -59
  151. package/skills/v8-utilities/SKILL.md +92 -92
  152. package/skills/v8-utilities/references/client-api-index.md +143 -143
  153. package/skills/v8-utilities/references/platform-http-routes.md +83 -83
  154. package/skills/v8-utilities/references/server-api-index.md +74 -74
  155. package/skills/v8-workflow/SKILL.md +13 -4
  156. package/skills/vision-engine/SKILL.md +19 -19
  157. package/skills/vision-engine/references/architecture-and-acceptance.md +34 -34
  158. package/skills/workspace-conventions/SKILL.md +35 -12
  159. 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 +2 -2
  160. 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
  161. 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,34 +1,34 @@
1
- # V8.Email 协议原子
2
-
3
- 业务编排使用接口引擎,下面的方法只供可信后端调用。
4
- 连接对象字段为 `Host`、`Port`、`Security`、`UserName`、`Credential`、`Timeout`。
5
- `Credential` 必须是 `V8.Email.ProtectCredential` 产生的当前租户密文。
6
- `Security` 仅允许 `SslOnConnect`、`StartTls`。超时默认 40 秒,最高 60 秒。
7
-
8
- | 方法 | 输入补充 | 返回 Data |
9
- | --- | --- | --- |
10
- | `V8.Email.ProtectCredential(value)` | 原文授权码 | 直接返回带版本前缀的租户密文字符串 |
11
- | `V8.Email.TestConnection(p)` | `Protocol: IMAP / SMTP` | `Connected, Protocol, Secure` |
12
- | `V8.Email.ListFolders(p)` | 无 | 最多 200 个 `Path, Name, Kind, Total, Unread` |
13
- | `V8.Email.Fetch(p)` | `Folder, AfterUid, UidValidity, Limit, Recent` | `NextUid, HasMore, Reset, UidValidity, Messages` |
14
- | `V8.Email.Inspect(p)` | `Folder, UidValidity, Uids`(最多 100) | `UidValidity, Messages`,含存在的 UID 和已读/星标/删除标志 |
15
- | `V8.Email.GetMessage(p)` | `Folder, UidValidity, Uid` | 信封、`TextBody, HtmlBody, Attachments` |
16
- | `V8.Email.GetAttachment(p)` | 上述字段及 `AttachmentIndex`(从 0 开始) | `FileName, ContentType, FileByteBase64` |
17
- | `V8.Email.SetFlags(p)` | `Folder, UidValidity, Uid, IsRead, IsStarred` | 结果状态 |
18
- | `V8.Email.Move(p)` | `Folder, UidValidity, Uid, DestinationFolder` | 移动结果;不得对整个目录执行无差别清空 |
19
- | `V8.Email.Send(p)` | SMTP 连接及下述 MIME 字段 | `DeliveryState, MessageId`,外层 `Code` 表示协议结果 |
20
- | `V8.Email.StoreSent(p)` | IMAP 连接及相同 MIME 字段 | 按 Message-Id 查重并保存已发送副本 |
21
-
22
- `Fetch.Recent=true` 读取末尾最多 `Limit` 封邮件,但保留历史 `AfterUid` 游标。
23
- 常规 Fetch 按 UID 窗口分页,`Limit` 最高 100;即使窗口为空也推进游标。
24
- 返回的 `Reset` 必须与 `UidValidity` 一起持久化,不能把旧代邮件指向新代同号 UID。
25
-
26
- MIME 字段:`To, Cc, Bcc, Subject, TextBody, HtmlBody, InReplyTo, MessageId, Attachments`。
27
- 附件对象:`FileName, ContentType, FileByteBase64`,最多 10 个,总大小不超过 10MB;
28
- 读取单封原始邮件上限 25MB,正文上限 2MB。超限应明确报错,不能静默丢内容。
29
-
30
- `Send` 的结果:`Accepted`、`Rejected` 或 `Unknown`。
31
- 在业务层保存草稿及去重标记后才能调用;不要对 `Unknown` 自动重试 SMTP。
32
- `StoreSent` 与真正发信分开,不可将保存副本当作已经投递。
33
-
34
- 相关源码:`Microi.Server/Microi.V8Engine/Extend/Email/V8Email.cs`。
1
+ # V8.Email 协议原子
2
+
3
+ 业务编排使用接口引擎,下面的方法只供可信后端调用。
4
+ 连接对象字段为 `Host`、`Port`、`Security`、`UserName`、`Credential`、`Timeout`。
5
+ `Credential` 必须是 `V8.Email.ProtectCredential` 产生的当前租户密文。
6
+ `Security` 仅允许 `SslOnConnect`、`StartTls`。超时默认 40 秒,最高 60 秒。
7
+
8
+ | 方法 | 输入补充 | 返回 Data |
9
+ | --- | --- | --- |
10
+ | `V8.Email.ProtectCredential(value)` | 原文授权码 | 直接返回带版本前缀的租户密文字符串 |
11
+ | `V8.Email.TestConnection(p)` | `Protocol: IMAP / SMTP` | `Connected, Protocol, Secure` |
12
+ | `V8.Email.ListFolders(p)` | 无 | 最多 200 个 `Path, Name, Kind, Total, Unread` |
13
+ | `V8.Email.Fetch(p)` | `Folder, AfterUid, UidValidity, Limit, Recent` | `NextUid, HasMore, Reset, UidValidity, Messages` |
14
+ | `V8.Email.Inspect(p)` | `Folder, UidValidity, Uids`(最多 100) | `UidValidity, Messages`,含存在的 UID 和已读/星标/删除标志 |
15
+ | `V8.Email.GetMessage(p)` | `Folder, UidValidity, Uid` | 信封、`TextBody, HtmlBody, Attachments` |
16
+ | `V8.Email.GetAttachment(p)` | 上述字段及 `AttachmentIndex`(从 0 开始) | `FileName, ContentType, FileByteBase64` |
17
+ | `V8.Email.SetFlags(p)` | `Folder, UidValidity, Uid, IsRead, IsStarred` | 结果状态 |
18
+ | `V8.Email.Move(p)` | `Folder, UidValidity, Uid, DestinationFolder` | 移动结果;不得对整个目录执行无差别清空 |
19
+ | `V8.Email.Send(p)` | SMTP 连接及下述 MIME 字段 | `DeliveryState, MessageId`,外层 `Code` 表示协议结果 |
20
+ | `V8.Email.StoreSent(p)` | IMAP 连接及相同 MIME 字段 | 按 Message-Id 查重并保存已发送副本 |
21
+
22
+ `Fetch.Recent=true` 读取末尾最多 `Limit` 封邮件,但保留历史 `AfterUid` 游标。
23
+ 常规 Fetch 按 UID 窗口分页,`Limit` 最高 100;即使窗口为空也推进游标。
24
+ 返回的 `Reset` 必须与 `UidValidity` 一起持久化,不能把旧代邮件指向新代同号 UID。
25
+
26
+ MIME 字段:`To, Cc, Bcc, Subject, TextBody, HtmlBody, InReplyTo, MessageId, Attachments`。
27
+ 附件对象:`FileName, ContentType, FileByteBase64`,最多 10 个,总大小不超过 10MB;
28
+ 读取单封原始邮件上限 25MB,正文上限 2MB。超限应明确报错,不能静默丢内容。
29
+
30
+ `Send` 的结果:`Accepted`、`Rejected` 或 `Unknown`。
31
+ 在业务层保存草稿及去重标记后才能调用;不要对 `Unknown` 自动重试 SMTP。
32
+ `StoreSent` 与真正发信分开,不可将保存副本当作已经投递。
33
+
34
+ 相关源码:`Microi.Server/Microi.V8Engine/Extend/Email/V8Email.cs`。
@@ -1,154 +1,154 @@
1
- ---
2
- name: job-engine
3
- description: Microi 定时任务与可靠后台任务规范。用于配置 Microi.Job、Quartz 和接口引擎任务,设计多节点租约、幂等、重试、停机排空、恢复、进度与验收。
4
- ---
5
-
6
- > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
7
-
8
- # Microi Job 定时与后台任务
9
-
10
- ## 何时使用
11
-
12
- - 周期扫描、补偿、归档:`Microi.Job`
13
- - 用户触发的长耗时安装/导入/同步:菜单后台任务
14
- - 可靠跨服务异步:MQ + outbox/inbox
15
- - 请求内等待外部结果:`await`,不要创建后台线程
16
-
17
- 禁止用后端 `setTimeout`、`Task.Run`、`static bool` 或本机定时器承载可靠业务。
18
-
19
- ## 平台对象
20
-
21
- Quartz 管理能力包含查询、添加、更新、暂停、恢复、删除任务。任务配置、接口引擎代码和执行日志属于控制面,只允许 `Level >= 9999` 维护;业务用户只能触发明确授权的后台动作。
22
-
23
- 任务通常调用稳定的 `ApiEngineKey`。接口引擎返回 `Code=1` 只表示本次执行成功,不代表调度系统可忽略重试与幂等。
24
-
25
- ## 多节点设计
26
-
27
- ### 新旧平台共库过渡:停用新版调度
28
-
29
- - 系统设置“开发配置”的 `DisableTaskScheduling`(停用任务调度)默认 `0`,缺字段、空值也按正常调度处理;只有已实现此能力的新版后端识别它。字段由“系统设置”应用和 SaaS 空库基础包交付,不写租户配置值,不逐条 Pause/修改任务状态。
30
- - 开启时在 Quartz 领取触发器、处理 Misfire 之前按租户过滤;领取后、真正触发前重新读取系统设置缓存。禁止仅在 `IJob.Execute`、Listener veto 或业务 V8 入口 return:共享 Quartz 可能已经推进 NextFireTime,造成旧版漏执行。
31
- - 集群故障恢复也不得清理停用租户的在途记录或创建其补偿触发器。Quartz 以故障节点为单位清理记录,所以同一故障节点混有被停用租户时,新版推迟该故障节点整组恢复,交给旧节点或关闭开关后处理;其它健康节点仍正常领取。
32
- - 正常保存系统设置在事务提交后失效缓存,下一次调度检查生效,不用重启;不是强制中断,已经开始的任务允许完成。缓存/配置读取失败拒绝该租户的新领取,不影响其它健康租户;Redis/失效通知异常时不能承诺硬实时。
33
- - 停用期间只读观察周期计划,不推进共享触发器;每个“租户 + Job + Trigger + 计划时间”写一条 `diy_schedule_job_log`,包含 `Status=Skipped`、`Executed=false`、`Reason=SystemTaskSchedulingDisabled` 和中文说明。Redis 原子预留与数据库确定性主键共同防止多新版节点重复记录;日志说明仅代表新版未执行,旧版仍可能正常执行。不补跑业务、不补写进程停机历史;新增/修改计划的日志目录最多约 10 秒更新。
34
- - 普通接口调用、MQ 消费、升级/应用安装等持久后台任务不属于此开关的范围。手动触发 Quartz 任务仍经过门禁。
35
- - 交付顺序:先安装字段并打开开关,再让新版节点参与调度;确认旧版所有调度进程已停止且在途任务完成后,关闭开关交接。不同业务库分别设置,不能用一个租户的值控制全部租户。
36
- - 验收至少覆盖:默认兼容、开关实时读取、租户隔离、共享库旧节点继续领取、领取后开关变化不推进触发器、Misfire 不误推进、多节点日志去重;不得在真实生产任务上制造副作用做测试。
37
-
38
- 每个任务必须同时具备:
39
-
40
- 1. 分布式租约:Key 至少含 `OsClient + JobKey + 计划时间/业务分片`,有唯一持有者、TTL、续租和仅持有者释放。
41
- 2. 业务幂等:稳定 `IdempotencyKey/EventId`、数据库唯一约束或条件状态迁移。
42
- 3. 可恢复状态:待处理、处理中、成功、失败、下次重试时间写共享数据库/Redis/MQ。
43
- 4. fencing:锁可能过期的资金、库存等任务使用版本号/条件更新拒绝旧持有者写入。
44
-
45
- 锁只能减少并发,不能替代幂等。
46
-
47
- ## 任务骨架
48
-
49
- ```js
50
- // 接口引擎由 Job 调用;JobRunId/FireTime 由调度层传入
51
- var idempotencyKey = String(V8.Param.JobRunId || '');
52
- if (!idempotencyKey) return { Code: 0, Msg: '缺少 JobRunId' };
53
-
54
- // 推荐调用专用后端能力,以唯一约束抢占执行记录
55
- var claim = V8.FormEngine.AddFormData('job_execution', {
56
- JobKey: 'daily_order_summary',
57
- IdempotencyKey: idempotencyKey,
58
- Status: 'Running'
59
- });
60
- if (claim.Code !== 1) return { Code: 1, Msg: '已执行或正在执行' };
61
-
62
- // 分页处理;每个业务副作用仍需自己的幂等键
63
- return { Code: 1, Data: { IdempotencyKey: idempotencyKey } };
64
- ```
65
-
66
- 实际项目优先由数据库唯一索引和接口引擎事务完成抢占,不能仅用“先查再新增”。该唯一索引必须声明在 Manifest `tables[].indexes`,并用 `microi_create_table_index` 创建、`microi_get_table_indexes` 回读;禁止在 Job/V8 内手写 `CREATE INDEX`。任务扫描还应按实际 SQL 建立 `(OsClient, Status, NextRetryTime)` 或 `(OsClient, JobKey, ScheduleTime)` 等组合索引。
67
-
68
- ## 失败、重试与停机
69
-
70
- - 失败记录错误分类、重试次数和 `NextRetryTime`,采用有上限退避;永久错误进入人工处理。
71
- - 外部调用设置超时;无法确认对方是否成功时用业务幂等号查询,不盲目重发。
72
- - 服务停机先停止接单,再在有限宽限期排空或持久化;重启扫描未完成任务。
73
- - 若要求 `kill -9` 前也零丢失,业务成功响应前必须获得共享 outbox/MQ/WAL 持久化确认。
74
-
75
- ## 后台按钮
76
-
77
- 满足任一条件即按后台任务设计:预计超过 2 分钟、500 条以上、1000 个以上扇出子操作、100 次以上外部调用、总量未知且可能持续运行,或安装/初始化/批量导入/批量生成/全量同步/迁移/备份。预计超过 10 分钟时,仅设置 `RunBackground=true` 仍不够,必须按 checkpoint 分片,每片独立事务。
78
-
79
- 菜单按钮设置 `RunBackground/BackgroundTask/IsBackgroundTask=true` 和 `ApiEngineKey`,并配置 `BackgroundTaskOptions`:
80
-
81
- - `IdempotencyKey` 或 `IdempotencyKeyFields`:跨节点、重试和重复点击保持稳定。
82
- - `ConcurrencyKey`:DDL、安装等不能并行的工作使用同一租约组。
83
- - `BusinessTable + BusinessId`:关联业务记录。
84
- - `BusinessStatusField + BusinessTaskIdField`:业务记录至少标记“后台处理中”和任务 Id;推荐再配置 `BusinessProgressField + BusinessEtaField`。
85
-
86
- 按钮提交成功后,平台前端会通过当前用户的 `V8.FormEngine` 权限把业务记录标记为“后台处理中”并写入任务 Id;后台服务不能直接相信客户端字段名而绕过表单权限。接口引擎仍必须在最后一片或异常补偿中把该业务记录改成“已完成 / 失败 / 已取消”,并保留任务 Id 供详情追溯:
87
-
88
- ```js
89
- var task = V8.Param._BackgroundTask || {};
90
- if (task.BusinessTable && task.BusinessId) {
91
- var patch = { Id: task.BusinessId };
92
- patch[task.BusinessStatusField] = '后台处理中';
93
- patch[task.BusinessTaskIdField] = task.Id;
94
- V8.FormEngine.UptFormData(task.BusinessTable, patch);
95
- }
96
- ```
97
-
98
- 不得让通用后台服务按客户端传入的任意表名/字段名直接写库;需要脱离前端自动标记的专用任务,应在受控接口引擎中使用固定表名和固定字段名。
99
-
100
- 接口通过 `V8.Method.UpdateBackgroundTask({Current,Total,Msg,Log})` 上报已提交的真实工作量,`Log`/`AppendLog` 用于追加任务详情(不得包含密码、Token 或密钥)。平台按实际吞吐计算 `EstimatedEndTime`;总量未知时不传 `Total`,通知中心显示“不定进度/估算中”,禁止用固定 10%、阶段占位或计时器伪造进度。失败和取消停在最后真实进度,不得显示 100%。
101
-
102
- 分片接口在仍有后续工作时返回:
103
-
104
- ```js
105
- return {
106
- Code: 1,
107
- Data: {
108
- BackgroundTask: {
109
- HasMore: true,
110
- Checkpoint: { LastId: lastId },
111
- Current: committedCount,
112
- Total: totalCount,
113
- NextDelaySeconds: 1,
114
- Msg: '本批已提交,等待下一批'
115
- }
116
- }
117
- };
118
- ```
119
-
120
- 最后一片返回普通 `Code:1`。每个业务副作用还要用 `_BackgroundTaskIdempotencyKey + 业务行Id` 建唯一约束;`_BackgroundTaskFencingToken` 用于拒绝租约过期旧执行者的写入。
121
-
122
- ## 长任务的 Jint 预算
123
-
124
- 后台 Worker 最终仍调用接口引擎,因此每个执行片段都受 `Timeout`、`MaxStatements`、单层累计分配预算、根调用树累计分配预算、JavaScript 递归和接口嵌套深度限制。`LimitMemory=2048` 表示当前片段累计分配了多少托管字节,不表示实时占用或预留 2GB 物理内存。
125
-
126
- - 总任务运行 10 分钟、30 分钟或数小时是允许的;单个连续 Jint 调用不应承担全部时长。
127
- - 每片在预算内提交事务并返回 `HasMore + Checkpoint`;Worker 重新入队后会创建新的 Jint Engine,新片重新获得超时、语句和累计分配预算。
128
- - `V8.ApiEngine.Run` 的多层编排可以保留。新版父子单层分配隔离后,子接口不会被所有祖先重复计费,但根调用树仍有整体预算;循环调用由独立的嵌套深度上限终止。
129
- - 捕获失败时读取 `DataAppend.V8Limit.Code`。内存/调用树/语句/超时分别缩小批次,递归错误修复函数递归,嵌套深度错误检查循环编排;不要统一归因于服务器资源不足。
130
- - 可记录 `V8.Limits` 到脱敏诊断日志,但不要在每条业务数据上重复输出。
131
- - 接口引擎和表后端事件分别使用正向 `sys_apiengine.V8Limit`、`diy_table.V8Limit`;二者默认 `0`,不设置 Jint 单片预算,只有明确需要限制单片时才设为 `1` 并配置超时、语句、分配和递归值。后台任务仍优先 `HasMore + Checkpoint`,因为不限 Jint 预算不等于数据库长事务、进程常驻内存、取消、并发或节点故障风险消失。
132
-
133
- ## MCP 工作流
134
-
135
- 1. 读取表、接口引擎和现有任务。
136
- 2. 先设计幂等键、状态机、租约和补偿。
137
- 3. `microi_save_job` 保存任务,写入需明确确认。
138
- 4. 回读任务 cron、启用状态、Key、接口引擎。
139
- 5. 两节点同时触发、重复投递、持有者中止、Redis 故障和滚动升级验收。
140
-
141
- ## 验收清单
142
-
143
- - [ ] 任务配置仅管理员可改
144
- - [ ] 两节点同一时刻触发,业务副作用仅一次
145
- - [ ] 重复消息/请求不会重复扣减或生成流水
146
- - [ ] 锁持有者退出后可恢复,无永久死锁
147
- - [ ] 失败可重试、可追踪、可人工补偿
148
- - [ ] 新旧版本滚动共存,状态和消息合约兼容
149
- - [ ] 未知总量不显示假百分比;已知总量由 Current/Total 唯一推导
150
- - [ ] ETA 来自真实吞吐,样本不足时明确显示“估算中”
151
- - [ ] 业务记录可通过 BackgroundTaskId 跳转通知中心排查
152
- - [ ] 超过 10 分钟的任务有 checkpoint,重启后从最后已提交批次恢复
153
- - [ ] 单片低于超时/语句/累计分配预算,任务总时长不依赖放大单次接口上限
154
- - [ ] 嵌套接口没有循环调用,且错误日志包含结构化 `V8Limit` 分类和调用路径
1
+ ---
2
+ name: job-engine
3
+ description: Microi 定时任务与可靠后台任务规范。用于配置 Microi.Job、Quartz 和接口引擎任务,设计多节点租约、幂等、重试、停机排空、恢复、进度与验收。
4
+ ---
5
+
6
+ > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
7
+
8
+ # Microi Job 定时与后台任务
9
+
10
+ ## 何时使用
11
+
12
+ - 周期扫描、补偿、归档:`Microi.Job`
13
+ - 用户触发的长耗时安装/导入/同步:菜单后台任务
14
+ - 可靠跨服务异步:MQ + outbox/inbox
15
+ - 请求内等待外部结果:`await`,不要创建后台线程
16
+
17
+ 禁止用后端 `setTimeout`、`Task.Run`、`static bool` 或本机定时器承载可靠业务。
18
+
19
+ ## 平台对象
20
+
21
+ Quartz 管理能力包含查询、添加、更新、暂停、恢复、删除任务。任务配置、接口引擎代码和执行日志属于控制面,只允许 `Level >= 9999` 维护;业务用户只能触发明确授权的后台动作。
22
+
23
+ 任务通常调用稳定的 `ApiEngineKey`。接口引擎返回 `Code=1` 只表示本次执行成功,不代表调度系统可忽略重试与幂等。
24
+
25
+ ## 多节点设计
26
+
27
+ ### 新旧平台共库过渡:停用新版调度
28
+
29
+ - 系统设置“开发配置”的 `DisableTaskScheduling`(停用任务调度)默认 `0`,缺字段、空值也按正常调度处理;只有已实现此能力的新版后端识别它。字段由“系统设置”应用和 SaaS 空库基础包交付,不写租户配置值,不逐条 Pause/修改任务状态。
30
+ - 开启时在 Quartz 领取触发器、处理 Misfire 之前按租户过滤;领取后、真正触发前重新读取系统设置缓存。禁止仅在 `IJob.Execute`、Listener veto 或业务 V8 入口 return:共享 Quartz 可能已经推进 NextFireTime,造成旧版漏执行。
31
+ - 集群故障恢复也不得清理停用租户的在途记录或创建其补偿触发器。Quartz 以故障节点为单位清理记录,所以同一故障节点混有被停用租户时,新版推迟该故障节点整组恢复,交给旧节点或关闭开关后处理;其它健康节点仍正常领取。
32
+ - 正常保存系统设置在事务提交后失效缓存,下一次调度检查生效,不用重启;不是强制中断,已经开始的任务允许完成。缓存/配置读取失败拒绝该租户的新领取,不影响其它健康租户;Redis/失效通知异常时不能承诺硬实时。
33
+ - 停用期间只读观察周期计划,不推进共享触发器;每个“租户 + Job + Trigger + 计划时间”写一条 `diy_schedule_job_log`,包含 `Status=Skipped`、`Executed=false`、`Reason=SystemTaskSchedulingDisabled` 和中文说明。Redis 原子预留与数据库确定性主键共同防止多新版节点重复记录;日志说明仅代表新版未执行,旧版仍可能正常执行。不补跑业务、不补写进程停机历史;新增/修改计划的日志目录最多约 10 秒更新。
34
+ - 普通接口调用、MQ 消费、升级/应用安装等持久后台任务不属于此开关的范围。手动触发 Quartz 任务仍经过门禁。
35
+ - 交付顺序:先安装字段并打开开关,再让新版节点参与调度;确认旧版所有调度进程已停止且在途任务完成后,关闭开关交接。不同业务库分别设置,不能用一个租户的值控制全部租户。
36
+ - 验收至少覆盖:默认兼容、开关实时读取、租户隔离、共享库旧节点继续领取、领取后开关变化不推进触发器、Misfire 不误推进、多节点日志去重;不得在真实生产任务上制造副作用做测试。
37
+
38
+ 每个任务必须同时具备:
39
+
40
+ 1. 分布式租约:Key 至少含 `OsClient + JobKey + 计划时间/业务分片`,有唯一持有者、TTL、续租和仅持有者释放。
41
+ 2. 业务幂等:稳定 `IdempotencyKey/EventId`、数据库唯一约束或条件状态迁移。
42
+ 3. 可恢复状态:待处理、处理中、成功、失败、下次重试时间写共享数据库/Redis/MQ。
43
+ 4. fencing:锁可能过期的资金、库存等任务使用版本号/条件更新拒绝旧持有者写入。
44
+
45
+ 锁只能减少并发,不能替代幂等。
46
+
47
+ ## 任务骨架
48
+
49
+ ```js
50
+ // 接口引擎由 Job 调用;JobRunId/FireTime 由调度层传入
51
+ var idempotencyKey = String(V8.Param.JobRunId || '');
52
+ if (!idempotencyKey) return { Code: 0, Msg: '缺少 JobRunId' };
53
+
54
+ // 推荐调用专用后端能力,以唯一约束抢占执行记录
55
+ var claim = V8.FormEngine.AddFormData('job_execution', {
56
+ JobKey: 'daily_order_summary',
57
+ IdempotencyKey: idempotencyKey,
58
+ Status: 'Running'
59
+ });
60
+ if (claim.Code !== 1) return { Code: 1, Msg: '已执行或正在执行' };
61
+
62
+ // 分页处理;每个业务副作用仍需自己的幂等键
63
+ return { Code: 1, Data: { IdempotencyKey: idempotencyKey } };
64
+ ```
65
+
66
+ 实际项目优先由数据库唯一索引和接口引擎事务完成抢占,不能仅用“先查再新增”。该唯一索引必须声明在 Manifest `tables[].indexes`,并用 `microi_create_table_index` 创建、`microi_get_table_indexes` 回读;禁止在 Job/V8 内手写 `CREATE INDEX`。任务扫描还应按实际 SQL 建立 `(OsClient, Status, NextRetryTime)` 或 `(OsClient, JobKey, ScheduleTime)` 等组合索引。
67
+
68
+ ## 失败、重试与停机
69
+
70
+ - 失败记录错误分类、重试次数和 `NextRetryTime`,采用有上限退避;永久错误进入人工处理。
71
+ - 外部调用设置超时;无法确认对方是否成功时用业务幂等号查询,不盲目重发。
72
+ - 服务停机先停止接单,再在有限宽限期排空或持久化;重启扫描未完成任务。
73
+ - 若要求 `kill -9` 前也零丢失,业务成功响应前必须获得共享 outbox/MQ/WAL 持久化确认。
74
+
75
+ ## 后台按钮
76
+
77
+ 满足任一条件即按后台任务设计:预计超过 2 分钟、500 条以上、1000 个以上扇出子操作、100 次以上外部调用、总量未知且可能持续运行,或安装/初始化/批量导入/批量生成/全量同步/迁移/备份。预计超过 10 分钟时,仅设置 `RunBackground=true` 仍不够,必须按 checkpoint 分片,每片独立事务。
78
+
79
+ 菜单按钮设置 `RunBackground/BackgroundTask/IsBackgroundTask=true` 和 `ApiEngineKey`,并配置 `BackgroundTaskOptions`:
80
+
81
+ - `IdempotencyKey` 或 `IdempotencyKeyFields`:跨节点、重试和重复点击保持稳定。
82
+ - `ConcurrencyKey`:DDL、安装等不能并行的工作使用同一租约组。
83
+ - `BusinessTable + BusinessId`:关联业务记录。
84
+ - `BusinessStatusField + BusinessTaskIdField`:业务记录至少标记“后台处理中”和任务 Id;推荐再配置 `BusinessProgressField + BusinessEtaField`。
85
+
86
+ 按钮提交成功后,平台前端会通过当前用户的 `V8.FormEngine` 权限把业务记录标记为“后台处理中”并写入任务 Id;后台服务不能直接相信客户端字段名而绕过表单权限。接口引擎仍必须在最后一片或异常补偿中把该业务记录改成“已完成 / 失败 / 已取消”,并保留任务 Id 供详情追溯:
87
+
88
+ ```js
89
+ var task = V8.Param._BackgroundTask || {};
90
+ if (task.BusinessTable && task.BusinessId) {
91
+ var patch = { Id: task.BusinessId };
92
+ patch[task.BusinessStatusField] = '后台处理中';
93
+ patch[task.BusinessTaskIdField] = task.Id;
94
+ V8.FormEngine.UptFormData(task.BusinessTable, patch);
95
+ }
96
+ ```
97
+
98
+ 不得让通用后台服务按客户端传入的任意表名/字段名直接写库;需要脱离前端自动标记的专用任务,应在受控接口引擎中使用固定表名和固定字段名。
99
+
100
+ 接口通过 `V8.Method.UpdateBackgroundTask({Current,Total,Msg,Log})` 上报已提交的真实工作量,`Log`/`AppendLog` 用于追加任务详情(不得包含密码、Token 或密钥)。平台按实际吞吐计算 `EstimatedEndTime`;总量未知时不传 `Total`,通知中心显示“不定进度/估算中”,禁止用固定 10%、阶段占位或计时器伪造进度。失败和取消停在最后真实进度,不得显示 100%。
101
+
102
+ 分片接口在仍有后续工作时返回:
103
+
104
+ ```js
105
+ return {
106
+ Code: 1,
107
+ Data: {
108
+ BackgroundTask: {
109
+ HasMore: true,
110
+ Checkpoint: { LastId: lastId },
111
+ Current: committedCount,
112
+ Total: totalCount,
113
+ NextDelaySeconds: 1,
114
+ Msg: '本批已提交,等待下一批'
115
+ }
116
+ }
117
+ };
118
+ ```
119
+
120
+ 最后一片返回普通 `Code:1`。每个业务副作用还要用 `_BackgroundTaskIdempotencyKey + 业务行Id` 建唯一约束;`_BackgroundTaskFencingToken` 用于拒绝租约过期旧执行者的写入。
121
+
122
+ ## 长任务的 Jint 预算
123
+
124
+ 后台 Worker 最终仍调用接口引擎,因此每个执行片段都受 `Timeout`、`MaxStatements`、单层累计分配预算、根调用树累计分配预算、JavaScript 递归和接口嵌套深度限制。`LimitMemory=2048` 表示当前片段累计分配了多少托管字节,不表示实时占用或预留 2GB 物理内存。
125
+
126
+ - 总任务运行 10 分钟、30 分钟或数小时是允许的;单个连续 Jint 调用不应承担全部时长。
127
+ - 每片在预算内提交事务并返回 `HasMore + Checkpoint`;Worker 重新入队后会创建新的 Jint Engine,新片重新获得超时、语句和累计分配预算。
128
+ - `V8.ApiEngine.Run` 的多层编排可以保留。新版父子单层分配隔离后,子接口不会被所有祖先重复计费,但根调用树仍有整体预算;循环调用由独立的嵌套深度上限终止。
129
+ - 捕获失败时读取 `DataAppend.V8Limit.Code`。内存/调用树/语句/超时分别缩小批次,递归错误修复函数递归,嵌套深度错误检查循环编排;不要统一归因于服务器资源不足。
130
+ - 可记录 `V8.Limits` 到脱敏诊断日志,但不要在每条业务数据上重复输出。
131
+ - 接口引擎和表后端事件分别使用正向 `sys_apiengine.V8Limit`、`diy_table.V8Limit`;二者默认 `0`,不设置 Jint 单片预算,只有明确需要限制单片时才设为 `1` 并配置超时、语句、分配和递归值。后台任务仍优先 `HasMore + Checkpoint`,因为不限 Jint 预算不等于数据库长事务、进程常驻内存、取消、并发或节点故障风险消失。
132
+
133
+ ## MCP 工作流
134
+
135
+ 1. 读取表、接口引擎和现有任务。
136
+ 2. 先设计幂等键、状态机、租约和补偿。
137
+ 3. `microi_save_job` 保存任务,写入需明确确认。
138
+ 4. 回读任务 cron、启用状态、Key、接口引擎。
139
+ 5. 两节点同时触发、重复投递、持有者中止、Redis 故障和滚动升级验收。
140
+
141
+ ## 验收清单
142
+
143
+ - [ ] 任务配置仅管理员可改
144
+ - [ ] 两节点同一时刻触发,业务副作用仅一次
145
+ - [ ] 重复消息/请求不会重复扣减或生成流水
146
+ - [ ] 锁持有者退出后可恢复,无永久死锁
147
+ - [ ] 失败可重试、可追踪、可人工补偿
148
+ - [ ] 新旧版本滚动共存,状态和消息合约兼容
149
+ - [ ] 未知总量不显示假百分比;已知总量由 Current/Total 唯一推导
150
+ - [ ] ETA 来自真实吞吐,样本不足时明确显示“估算中”
151
+ - [ ] 业务记录可通过 BackgroundTaskId 跳转通知中心排查
152
+ - [ ] 超过 10 分钟的任务有 checkpoint,重启后从最后已提交批次恢复
153
+ - [ ] 单片低于超时/语句/累计分配预算,任务总时长不依赖放大单次接口上限
154
+ - [ ] 嵌套接口没有循环调用,且错误日志包含结构化 `V8Limit` 分类和调用路径
@@ -1,12 +1,22 @@
1
1
  ---
2
2
  name: message-notification
3
- description: 设计、实现、迁移和验收 Microi 多通道消息通知。用于涉及 wx_tpl_msg、mic_msgset、mic_msg_event_log、微信公众号或服务号模板消息、小程序跳转、短信、邮件、平台内部通知、V8.Notification、通知中心 SignalR、msg_event、消息幂等或通知应用商城交付的任务。
3
+ description: 设计、实现、迁移和验收 Microi 多通道消息通知与平台提醒。用于平台提醒、SaaS 系统提醒、试用到期、维护公告、定时弹窗、官方版本提醒、wx_tpl_msg、mic_msgset、mic_msg_event_log、公众号模板消息、短信、邮件、V8.Notification、SignalR、msg_event、消息幂等或通知应用商城交付。
4
4
  ---
5
5
 
6
6
  > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
7
7
 
8
8
  # Microi 消息通知
9
9
 
10
+ ## 统一配置入口与 MCP
11
+
12
+ - 安装同一个 `app.microi.message-notification` 应用后,统一从“系统引擎 → 消息通知”进入系统公告、业务通知与投递记录。禁止再建独立“系统提醒”应用或向 SaaS 表单添加入口。旧 `/xiaoxitongzhisz` 配置并入业务通知,原 `mic_msgset` 和历史数据保留。
13
+ - 先用当前用户自己的 MCP 调用 `microi_get_notification_context`,读取 `Capabilities / BusinessRules / BusinessRule / Reminders / Reminder / Recipients / Templates / Adapters / Logs / History`。`Adapters` 按关键词分页发现本租户已启用的接口 Key,不读取源码或密钥。用户和角色只在当前租户读取,跨租户/产品版本仅选择 `AllAccounts / SuperAdmins`,不得读取其它服务器角色。
14
+ - `microi_configure_business_notification` 的 `Validate` 不写入、不发送;`Save` 写原通知表,通过固定 `platform-message-notification-config` 接口编排。确认串为 `Save:<id或Key>`;修改必须传 `expectedRevision`,不能把密钥写进 `ChannelApiEngineMap`。
15
+ - `microi_manage_system_reminder` 提供 `Validate / Save / Publish / Withdraw`,确认串为 `<action>:<id或requestId>`。保存仅草稿;发布前核对用户已经授权的具体内容、范围与时间。保存/发布使用稳定 `requestId`,编辑/发布/撤回传最新 `expectedRevision`,超时先按原 Id/Key 回读,禁止换请求标识盲目新建。
16
+ - `AccountScope` 在本租户 `Users` 默认 `AllAccounts`,在 `Tenants / Editions` 默认 `SuperAdmins`;不要让已指定的普通帐号被默认管理员筛选误排除。用户显式指定的帐号范围优先。
17
+ - 配置接口只管理原表、校验引用和读取脱敏投递记录;实际发送继续调用 `msg_event`。`ConfigRevision` 缺省按 0 兼容旧记录,更新使用同事务条件写,失败不能覆盖别人修改。停用旧配置允许保留失效引用,再启用时重新核验。
18
+ - MCP 缺少上述工具时优先更新本机插件/CLI;当前宿主未重载可复用已有 `microi_run_engine` 调用同一固定接口,不另建临时维护引擎或绕过授权。明确区分本机工具打包成功与用户渠道已发布。
19
+
10
20
  ## 目标
11
21
 
12
22
  交付“配置可维护、事件先持久化、实时可降级、多节点不重复、租户不串线”的通知能力。支持微信公众号/服务号模板消息、短信、邮件和平台内部通知;小程序是公众号模板消息的跳转目标,不是独立的公众号发送主体。
@@ -115,6 +125,22 @@ await V8.Notification.MarkRead({ All: true });
115
125
 
116
126
  租户个性化仅写入 `platform-message-notification-custom-hook`(`CreateIfMissing`),默认正文必须精确为 `return { Code : 1 };`。运行时在 `BeforeChatRuntime / AfterChatRuntime` 调用 Hook:Before 失败在 Mongo 写前阻断,After 失败只告警。Hook 只接收 `Stage`、`SourceApiEngineKey`、`Action`、`ActorUserId`、`PeerUserId`、`MessageId`、`MessageType`;正文、头像、OpenId、Token 与其它秘密不得进入租户扩展。三项接口的源码顶部都要保留官方恢复/租户不覆盖提示,并在包合同测试中逐字核对独立源码、包内副本、所有权策略和 HTTP/匿名开关。
117
127
 
128
+ ## 平台提醒的使用与交付
129
+
130
+ - 居中可关闭的公告、试用到期与定时提醒统一从“系统引擎 → 消息通知 → 系统公告”配置,使用 `platform-reminder-runtime` 和内置 `microi-platform-service` 的 `/platform-reminders` 页面。在同一页面选择单个、多个或全部租户及用户;不得再向 SaaS 引擎添加提醒按钮、提醒 Tab 或嵌入组件,也不得改为 `TableChild` 或在 V8 中拼接复杂 HTML。
131
+ - 四张表分别是 `mci_platform_reminder` 草稿、`mci_platform_reminder_batch` 发布快照、`mci_platform_reminder_target` 接收映射和 `mci_platform_reminder_receipt` 关闭回执。普通客户端不能直接写表。保存草稿不发送;版本条件更新、批次稳定主键、接收映射与状态修改必须共享 `V8.DbTrans`,不要混用独立 `V8.Db.FromSql` 写入。
132
+ - `Users` 面向当前租户用户,`Tenants` 仅允许主租户选择当前环境和网络的启用子租户,`Editions` 仅由宿主现有 License 发放判断确定官方身份。官方选项需明确选择 `OpenSource / Personal / Enterprise`,不得默认给全部版本发送。请求中的用户、租户、官方标志和产品版本不构成授权。
133
+ - 试用提醒只绑定一个子租户,配置到期时间和提前分钟数,不改 License。所有提醒都必须有有效结束时间,支持 `Once / EveryEntry / AfterServerRestart`;定时支持一次、每日、每周和分钟间隔。每日/每周是固定时间间隔;时间传 UTC,界面显示浏览器时区;恢复上线不补弹所有历史周期。
134
+ - 后端三个 Managed Key 为 `platform-reminder-runtime / platform-reminder-official-feed / platform-reminder-tick`。运行时动作包括 `Capabilities / Recipients / List / Get / Validate / Save / Publish / Withdraw / History / Inbox / Presented / Acknowledge`。发布需草稿 Id、`ExpectedRevision` 和稳定 `RequestId`;每次进入模式的收件箱和回执需稳定的本页面 `EntryId`。
135
+ - `AccountScope=SuperAdmins` 由接收服务的真实 DiyToken、数据库用户和有效本地角色核验;`AllAccounts` 面向全部帐号。缺省字段保留旧公告的全部帐号语义;新 UI 和 MCP 的跨租户/版本默认范围为超级管理员。普通服务器不能伪造官方 License 发放身份。
136
+ - `AfterServerRestart` 用可信后端进程启动标识和主租户当前运行分区的共享 Redis 最新批次计算 occurrence,`Presented` 按数据库稳定回执主键抢占领取资格;同帐号多页面只有一个领取,刷新和重新登录不再次弹出。展示成功前回执应已持久化;响应丢失以同一个页面 `EntryId` 恢复,不以 localStorage 作为事实源。`ShownAt` 与 `ClosedAt` 分离,当前已领取弹窗需保留到关闭、撤回或过期。
137
+ - 超级管理员范围和重启频率的最低接收协议为 2;官方 feed 必须对协议 1 隐去此类公告,接收端出缓存后再次按当前身份裁剪。未知范围、异常协议或无法核验的启动批次失败关闭。重启频率不能再叠加周期计划;多节点滚动发布采用共享最新启动批次,验证负载切换不回退、不重复。
138
+ - 定时任务 `platform-reminder-tick` 每分钟只发送唤醒信号;权威计划与回执保存在数据库。前端监听 `ReceivePlatformReminder` 后回读,SignalR 正常约 60 秒对账、断线约 15 秒轮询并对错误退避;关闭失败重试、撤回和过期收回,禁止使用本机定时器或 localStorage 作为已读事实源。
139
+ - 跨服务器官方源由 `Microi.net` 固定请求 `api.itdos.com`,不允许任意 URL/重定向、不发送用户或密钥,按真实本地 License 筛选并缓存;官方源降级不得阻断本地提醒。匿名 feed 只暴露已发布的版本公告,不可读草稿、租户目标或回执。
140
+ - 官方“消息通知”包单一拥有配置接口 `platform-message-notification-config`、三个提醒接口、四表六索引、统一菜单、每分钟任务与当前内置微服务产物;SaaS 包同步统一菜单、基础空库结构和旧布局退役声明。先更新支持 `DiyFieldRetirements` 的商城,再安装新版 SaaS 包,清理旧入口且保留业务数据。商城包的内置微服务版本需同步。导出母版可能不带物理索引,按已验证 Manifest 补独立 `CREATE INDEX`,由安装器幂等检查;禁止发布测试提醒、真实接收人或回执数据。
141
+ - MCP 复用 `microi_get_db_schema / microi_generate_system / microi_admin_table_data / microi_save_engine_code / microi_run_engine`,以及在线应用发现、源码同步和流式发布工具;入口调整使用 `microi_update_module / microi_update_table / microi_delete_field`,写后回读确认不存在旧入口。
142
+ - 源码升级与应用安装缺一不可。验收覆盖正式 SDK 的 JSON 字符串响应、居中/拖动/关闭、每次刷新、单/多/全租户入口、权限隔离、重复发布、事务失败、到点/过期、断线轮询;多节点与实际其它服务器需要独立集成证据,不能由单机或模型测试替代。
143
+
118
144
  ## 最低验收
119
145
 
120
146
  1. 两个 MCP 租户的字段、数据源、物理索引和三段接口代码回读一致。
@@ -1,5 +1,5 @@
1
- interface:
2
- display_name: "Microi 消息通知"
3
- short_description: "设计、实现并验收租户安全的多通道与平台内部实时消息通知"
4
- brand_color: "#409EFF"
5
- default_prompt: "Use $message-notification to design and verify a tenant-safe Microi notification flow."
1
+ interface:
2
+ display_name: "Microi 消息通知"
3
+ short_description: "设计、实现并验收租户安全的多通道与平台内部实时消息通知"
4
+ brand_color: "#409EFF"
5
+ default_prompt: "Use $message-notification to design and verify a tenant-safe Microi notification flow."