@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,13 +1,13 @@
1
1
  ---
2
- name: performance-testing
3
- description: Microi 高并发、性能压力测试规范。用于对 ApiEngine、V8 事件、FormEngine CRUD、VS Code 插件性能页、压力/尖峰/长稳测试、报告、并发、吞吐、延迟分位和瓶颈诊断做压测。
4
- ---
2
+ name: performance-testing
3
+ description: Microi 高并发、性能压力测试规范。用于对 ApiEngine、V8 事件、FormEngine CRUD、VS Code 插件性能页、压力/尖峰/长稳测试、报告、并发、吞吐、延迟分位和瓶颈诊断做压测。
4
+ ---
5
5
 
6
6
  > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
7
-
8
- # Microi 高并发性能压力测试
9
-
10
- > 排查长任务时,严禁把“等待或执行超过 1 分钟”直接判定为失败;接口引擎、V8、表单写入、导入导出、批处理等合法长任务默认应支持 10 分钟以上,同步链路推荐 10 分钟,排队窗口推荐 30 分钟。
7
+
8
+ # Microi 高并发性能压力测试
9
+
10
+ > 排查长任务时,严禁把“等待或执行超过 1 分钟”直接判定为失败;接口引擎、V8、表单写入、导入导出、批处理等合法长任务默认应支持 10 分钟以上,同步链路推荐 10 分钟,排队窗口推荐 30 分钟。
11
11
 
12
12
  本 Skill 用于设计、实现和执行 Microi 吾码性能测试,覆盖接口引擎、V8 事件、FormEngine 表 CRUD、前端工作流与 VS Code 插件性能测试页。
13
13
 
@@ -93,96 +93,96 @@ POST /api/formengine/DelFormData
93
93
  - 支持保存 HTML 报告到 `.microi-performance/`,并可从 VS Code 打开。
94
94
  - 报告至少展示:完成、成功、失败、RPS、平均耗时、P95/P99、错误率、延迟分布、每秒趋势、错误 Top。
95
95
 
96
- ## 结果判定
97
-
98
- 性能测试不是只看 RPS。结论必须同时看:
96
+ ## 结果判定
97
+
98
+ 性能测试不是只看 RPS。结论必须同时看:
99
99
 
100
100
  - 错误率是否为 0 或低于目标阈值。
101
101
  - P95/P99 是否满足业务 SLA。
102
102
  - 是否出现连接超时、身份过期、数据库死锁、缓存穿透、外部接口超时。
103
103
  - 写入场景是否确实触发了 V8 事件并完成清理。
104
- - 长时间测试后内存、线程、连接池、Redis、数据库连接是否稳定。
105
-
106
- ## 用户行为日志队列压测
107
-
108
- 行为审计不能只测 MongoDB 写入速度,必须分开验证请求线程入队、后台批量持久化、故障 spool 和重放幂等:
109
-
110
- - 使用本地 Fake Mongo/测试库注入故障,不得为了验证日志队列让生产 MongoDB 停机。
111
- - 至少覆盖 10 万事件、100 以上并发生产者,报告入队吞吐和入队 P95/P99;入队阶段不得等待 MongoDB。
112
- - 模拟前若干批次写 MongoDB 失败,确认事件先进入 spool,恢复后按 `EventId` 幂等重放,最终唯一事件数必须等于入队成功数。
113
- - 在未满批次的 150ms 聚合窗口主动触发正常停机,确认已从 Channel 取出的局部批次仍会写 spool,重启后不丢失。
114
- - 验收同时检查 spool 剩余文件数、重复 EventId、队列内存计数、失败批次数和最后持久化时间;只看接口 HTTP 200 不算通过。
115
- - “有界 Channel + 无界 ConcurrentQueue 溢出区”仍然是无界队列,禁止作为保护方案。主队列和内存重试区都必须有硬容量;两者满时要同步写持久化 spool/WAL 形成回压,并断言 `EmergencySpooled` 可观测、`Dropped=0`。
116
- - 进程被强制结束、宿主机掉电等场景若要求绝对零丢失,必须采用外部持久消息队列或同步 WAL;内存 Channel 加异步 spool 只能保证 Mongo 故障和正常停机,不得宣称覆盖尚未落盘的强杀窗口。
117
-
118
- ## 网络流量可观测性与写入性能(强制)
119
-
120
- 查询动作、AI/MCP 调用、权限与数据解释边界统一读取 `../system-observability/SKILL.md`;本节只定义热路径和压测门禁。
121
-
122
- API 网络监控必须同时展示“网卡/容器网络命名空间计数”和“可归因 HTTP 请求体、响应体计数”,并明确两者不能直接画等号。Docker NetIO 还可能包含 TLS/HTTP 头、重传、数据库、Redis、MongoDB、对象存储、外部 HTTP 与容器内部通信;界面必须展示未归因差值、采样范围、节点、窗口和数据边界,禁止把差值伪装成某个帐号或接口的精确流量。
123
-
124
- - 请求热路径只做原子计数和有硬上限的分钟桶聚合;端点、IP、帐号、租户、内容类型等维度必须限制基数和保留 TOP N,禁止逐请求同步写 MySQL/MongoDB、同步序列化完整请求或创建无界队列。
125
- - 高频普通明细只驻留短窗口内存;大文件、可疑、错误或慢请求等有诊断价值的样本进入现有有界日志队列并异步批量写 MongoDB。Mongo 故障、队列满和停机语义继续遵守本 Skill 的 spool/WAL 规则。
126
- - 长期趋势写 MySQL 固定时间桶汇总(默认 5 分钟),按 `BucketStart + Node + DimensionType + DimensionKeyHash` 形成确定性幂等键,批量 upsert;查询必须命中“时间桶+维度+总字节”等索引,页面默认分页 15 条,不得扫描 Mongo 明细生成每次总览。
127
- - 禁止持久化 QueryString、Cookie、Token、Authorization、请求正文或响应正文。文件只记录经过清洗且有长度上限的文件名/扩展名/数量/字节;IP 必须标注是可信代理解析后的客户端 IP 还是直接连接 IP。
128
- - 验收至少覆盖:并发计数无负数、维度基数有界、敏感值不落盘、固定时间桶幂等重放、Mongo 故障不阻塞请求、匿名/登录用户区分、上传/下载字节、网卡重置/回绕、低流量和大流量样本、服务重启后的历史查询,以及开启监控前后 P95/P99、CPU、分配率和内存差异。
129
-
130
- ### 多节点与滚动重启压测
131
-
132
- - 至少启动两个 API/Worker 实例连接同一 Redis、业务数据库和 MongoDB,通过同一负载均衡入口并发施压;禁止用单进程内开两个对象冒充分布式验收。
133
- - 同一 `Microi.Job`/定时任务同时到点时,只允许一个节点取得带 TTL、持有者令牌和续租能力的租约;同时验证锁过期后接管、旧持有者不得释放新锁,以及业务幂等约束可阻止锁超时造成的重复副作用。
134
- - 对同一请求、消息和日志 `EventId` 做跨节点重复投递,最终数据库业务结果和审计事件都只能有一份;节点级本机去重不算通过。
135
- - 在队列有未完成工作、锁已取得、写库成功但响应未返回等时间点分别终止一个节点,再启动连接同一持久卷和共享存储的替代节点,验证 spool/outbox 自动恢复、共享状态不损坏、其余节点持续服务;节点身份由平台自动管理。
136
- - 做滚动升级时让新旧版本同时接流量,验证数据库、Redis 值、消息和 API 合约双向兼容;readiness 关闭后节点不得继续接收新工作,宽限期结束前应完成排空或可靠移交。
137
-
138
- ## 后台批处理与初始化任务防护
139
-
140
- 启动初始化、缓存预热、多语言同步、批量翻译、批量建索引、批量修复元数据这类后台任务,不能按普通接口逻辑无界并发执行。即使每个单次 SQL 都很快,几千条元数据逐条 `Get/Add/Upt`、多个租户同时 `Task.Run`、外部翻译超时堆积,也会把数据库连接池、MySQL `max_connections`、`max_connect_errors` 和线程池一起打满。
141
-
142
- 强制要求:
143
-
144
- - 全量后台任务必须有全局并发上限;多租户初始化默认按租户串行或小并发队列执行,不允许启动时对所有租户同时打满数据库。
145
- - 单租户内的后台 DB 写入要有租户级限流,不能和正常用户请求抢满连接池。
146
- - 批处理遇到 `too many connections`、`blocked because of many connection errors`、连接超时等数据库连接压力错误时,必须熔断退避一段时间,停止继续重试撞库。
147
- - 外部 HTTP/翻译/AI 调用必须有超时、并发阀门和失败降级,超时任务不能无限制堆到线程池。
148
- - 能预加载或缓存的元数据不要在循环里重复查库,例如树形根节点、字段结构、已有词条字典等。
149
- - 运行时缓存预热必须先做行数预算检查,只选择必要列并按稳定主键游标固定小分页,同时设置原始行数、字符/字节总预算和单 SQL 超时;只有全部读取成功后才能原子替换旧缓存。多语言缓存只加载租户实际启用的语言列;禁止 `SELECT * ... ToList()` 后再复制为字典,也不能在迁移或依赖检查失败后继续执行无界缓存加载。
150
- - 进度日志应按批次写入,避免每条数据都写日志表。
151
-
152
- ### API 进程内存熔断验收
153
-
154
- - 进程必须同时有软阈值和硬阈值。软阈值进入 readiness 失败并拒绝新业务请求;硬阈值连续命中后先有界停机,失控任务不响应取消时允许在宽限期后强制退出,不能等宿主机 OOM。
155
- - liveness 与 readiness 必须分开验证:内存压力下 liveness 仍可用于判断进程存活,readiness 必须让负载均衡摘除当前节点。
156
- - 启动 API、Node、浏览器自动化和长稳压测前后都要记录进程树 PID;每 15-30 秒采集 Working Set、Private Bytes、托管堆和整机可用内存,达到全机 95% 时立即终止本次测试进程树。
157
- - 进程内存熔断必须使用实际驻留内存(Windows Working Set / Linux RSS)作为压力指标。Linux 的 `PrivateMemorySize64` 可能包含 .NET GC 预留的巨大虚拟地址空间,只能用于辅助诊断,禁止与 Working Set 取较大值后作为拒绝请求或退出进程的依据。
158
- - 内存阈值不能固定为与机器规格无关的小常量。平台按 cgroup 容器限额或宿主机物理内存动态计算,软阈值为 95%、硬阈值为 98%,不再增加环境变量或 appsettings 参数;多节点或数据库共用宿主机时必须给每个容器设置独立 memory limit,防止各节点重复使用整机额度。
159
- - 内存修复不能只用“限制进程最大内存”代替根因治理。报告必须指出造成增长的具体对象/查询/队列,并分别验证根因边界和进程最后防线。
160
-
161
- ## 数据库连接压力防护
162
-
163
- 高并发问题不能只靠调大 MySQL `max_connections`。平台后端和 ORM 层必须把数据库连接视为受保护资源,所有普通接口、接口引擎、FormEngine、V8 事件、后台任务和批量导入都应该走统一连接打开入口。
164
-
165
- 强制要求:
166
-
167
- - ORM 层需要按连接串限制并发 `Open/OpenAsync`,避免瞬时 1 万个请求同时抢连接池或打爆 MySQL 握手。
168
- - 遇到 `Host ... is blocked because of many connection errors`、`too many connections`、连接池超时、连接超时等错误时,应短时间熔断退避,快速失败并停止继续撞库。
169
- - API 层需要对租户、用户、IP、重接口和写接口配置限流/并发阀门;压力超过阈值时返回明确的“系统繁忙/稍后重试”,不要无限排队。
170
- - 连接串的 `Max Pool Size` 不能所有租户默认写很大;要按单进程、租户数、读写库和 MySQL `max_connections` 统一核算。
171
- - 事务、`DbDataReader`、批量导入、后台任务必须确保连接按 `using/Dispose/Close` 释放;压测后要观察连接池、MySQL 当前连接数和等待线程是否回落。
172
-
173
- ## V8 / 接口引擎失控保护
174
-
175
- 接口引擎和表单 V8 事件属于用户可编程能力,必须默认假设会出现误写死循环、循环套循环查库、未分页大查询、外部接口长时间超时等问题。平台要在运行时给出硬保护,而不能只靠代码审查。
176
-
177
- 强制要求:
178
-
179
- - V8/Jint 默认超时、最大语句数、内存、递归深度必须保守;需要按租户或机器规格调整时统一在 SaaS 引擎 `sys_osclients` 的受控字段或接口引擎自身配置中维护,并由代码硬上限夹住。禁止为此新增 API 环境变量或 `appsettings` 节点。
180
- - V8Engine.Run 入口必须有全局、租户级、接口/事件级并发阀门;过载时返回 `Code=0` 和“系统繁忙,请稍后重试”,不要继续进入事务和数据库。
181
- - HTTP 入口应在进入 Controller 前做全局、租户、路由、接口引擎级背压;过载时直接返回 DosResult 风格 JSON,保证前端能弹出明确提示。
182
- - 接口引擎配置里的 Timeout、MaxStatements、LimitMemory、LimitRecursion 不能无限放大,必须被平台级最大值夹住。
183
- - 对外部 HTTP、AI、翻译、短信、第三方 ERP 这类慢操作,V8 扩展层必须设置超时和并发限制,不能把同步等待堆满线程池。
184
-
185
- ## 复盘写回规则
104
+ - 长时间测试后内存、线程、连接池、Redis、数据库连接是否稳定。
105
+
106
+ ## 用户行为日志队列压测
107
+
108
+ 行为审计不能只测 MongoDB 写入速度,必须分开验证请求线程入队、后台批量持久化、故障 spool 和重放幂等:
109
+
110
+ - 使用本地 Fake Mongo/测试库注入故障,不得为了验证日志队列让生产 MongoDB 停机。
111
+ - 至少覆盖 10 万事件、100 以上并发生产者,报告入队吞吐和入队 P95/P99;入队阶段不得等待 MongoDB。
112
+ - 模拟前若干批次写 MongoDB 失败,确认事件先进入 spool,恢复后按 `EventId` 幂等重放,最终唯一事件数必须等于入队成功数。
113
+ - 在未满批次的 150ms 聚合窗口主动触发正常停机,确认已从 Channel 取出的局部批次仍会写 spool,重启后不丢失。
114
+ - 验收同时检查 spool 剩余文件数、重复 EventId、队列内存计数、失败批次数和最后持久化时间;只看接口 HTTP 200 不算通过。
115
+ - “有界 Channel + 无界 ConcurrentQueue 溢出区”仍然是无界队列,禁止作为保护方案。主队列和内存重试区都必须有硬容量;两者满时要同步写持久化 spool/WAL 形成回压,并断言 `EmergencySpooled` 可观测、`Dropped=0`。
116
+ - 进程被强制结束、宿主机掉电等场景若要求绝对零丢失,必须采用外部持久消息队列或同步 WAL;内存 Channel 加异步 spool 只能保证 Mongo 故障和正常停机,不得宣称覆盖尚未落盘的强杀窗口。
117
+
118
+ ## 网络流量可观测性与写入性能(强制)
119
+
120
+ 查询动作、AI/MCP 调用、权限与数据解释边界统一读取 `../system-observability/SKILL.md`;本节只定义热路径和压测门禁。
121
+
122
+ API 网络监控必须同时展示“网卡/容器网络命名空间计数”和“可归因 HTTP 请求体、响应体计数”,并明确两者不能直接画等号。Docker NetIO 还可能包含 TLS/HTTP 头、重传、数据库、Redis、MongoDB、对象存储、外部 HTTP 与容器内部通信;界面必须展示未归因差值、采样范围、节点、窗口和数据边界,禁止把差值伪装成某个帐号或接口的精确流量。
123
+
124
+ - 请求热路径只做原子计数和有硬上限的分钟桶聚合;端点、IP、帐号、租户、内容类型等维度必须限制基数和保留 TOP N,禁止逐请求同步写 MySQL/MongoDB、同步序列化完整请求或创建无界队列。
125
+ - 高频普通明细只驻留短窗口内存;大文件、可疑、错误或慢请求等有诊断价值的样本进入现有有界日志队列并异步批量写 MongoDB。Mongo 故障、队列满和停机语义继续遵守本 Skill 的 spool/WAL 规则。
126
+ - 长期趋势写 MySQL 固定时间桶汇总(默认 5 分钟),按 `BucketStart + Node + DimensionType + DimensionKeyHash` 形成确定性幂等键,批量 upsert;查询必须命中“时间桶+维度+总字节”等索引,页面默认分页 15 条,不得扫描 Mongo 明细生成每次总览。
127
+ - 禁止持久化 QueryString、Cookie、Token、Authorization、请求正文或响应正文。文件只记录经过清洗且有长度上限的文件名/扩展名/数量/字节;IP 必须标注是可信代理解析后的客户端 IP 还是直接连接 IP。
128
+ - 验收至少覆盖:并发计数无负数、维度基数有界、敏感值不落盘、固定时间桶幂等重放、Mongo 故障不阻塞请求、匿名/登录用户区分、上传/下载字节、网卡重置/回绕、低流量和大流量样本、服务重启后的历史查询,以及开启监控前后 P95/P99、CPU、分配率和内存差异。
129
+
130
+ ### 多节点与滚动重启压测
131
+
132
+ - 至少启动两个 API/Worker 实例连接同一 Redis、业务数据库和 MongoDB,通过同一负载均衡入口并发施压;禁止用单进程内开两个对象冒充分布式验收。
133
+ - 同一 `Microi.Job`/定时任务同时到点时,只允许一个节点取得带 TTL、持有者令牌和续租能力的租约;同时验证锁过期后接管、旧持有者不得释放新锁,以及业务幂等约束可阻止锁超时造成的重复副作用。
134
+ - 对同一请求、消息和日志 `EventId` 做跨节点重复投递,最终数据库业务结果和审计事件都只能有一份;节点级本机去重不算通过。
135
+ - 在队列有未完成工作、锁已取得、写库成功但响应未返回等时间点分别终止一个节点,再启动连接同一持久卷和共享存储的替代节点,验证 spool/outbox 自动恢复、共享状态不损坏、其余节点持续服务;节点身份由平台自动管理。
136
+ - 做滚动升级时让新旧版本同时接流量,验证数据库、Redis 值、消息和 API 合约双向兼容;readiness 关闭后节点不得继续接收新工作,宽限期结束前应完成排空或可靠移交。
137
+
138
+ ## 后台批处理与初始化任务防护
139
+
140
+ 启动初始化、缓存预热、多语言同步、批量翻译、批量建索引、批量修复元数据这类后台任务,不能按普通接口逻辑无界并发执行。即使每个单次 SQL 都很快,几千条元数据逐条 `Get/Add/Upt`、多个租户同时 `Task.Run`、外部翻译超时堆积,也会把数据库连接池、MySQL `max_connections`、`max_connect_errors` 和线程池一起打满。
141
+
142
+ 强制要求:
143
+
144
+ - 全量后台任务必须有全局并发上限;多租户初始化默认按租户串行或小并发队列执行,不允许启动时对所有租户同时打满数据库。
145
+ - 单租户内的后台 DB 写入要有租户级限流,不能和正常用户请求抢满连接池。
146
+ - 批处理遇到 `too many connections`、`blocked because of many connection errors`、连接超时等数据库连接压力错误时,必须熔断退避一段时间,停止继续重试撞库。
147
+ - 外部 HTTP/翻译/AI 调用必须有超时、并发阀门和失败降级,超时任务不能无限制堆到线程池。
148
+ - 能预加载或缓存的元数据不要在循环里重复查库,例如树形根节点、字段结构、已有词条字典等。
149
+ - 运行时缓存预热必须先做行数预算检查,只选择必要列并按稳定主键游标固定小分页,同时设置原始行数、字符/字节总预算和单 SQL 超时;只有全部读取成功后才能原子替换旧缓存。多语言缓存只加载租户实际启用的语言列;禁止 `SELECT * ... ToList()` 后再复制为字典,也不能在迁移或依赖检查失败后继续执行无界缓存加载。
150
+ - 进度日志应按批次写入,避免每条数据都写日志表。
151
+
152
+ ### API 进程内存熔断验收
153
+
154
+ - 进程必须同时有软阈值和硬阈值。软阈值进入 readiness 失败并拒绝新业务请求;硬阈值连续命中后先有界停机,失控任务不响应取消时允许在宽限期后强制退出,不能等宿主机 OOM。
155
+ - liveness 与 readiness 必须分开验证:内存压力下 liveness 仍可用于判断进程存活,readiness 必须让负载均衡摘除当前节点。
156
+ - 启动 API、Node、浏览器自动化和长稳压测前后都要记录进程树 PID;每 15-30 秒采集 Working Set、Private Bytes、托管堆和整机可用内存,达到全机 95% 时立即终止本次测试进程树。
157
+ - 进程内存熔断必须使用实际驻留内存(Windows Working Set / Linux RSS)作为压力指标。Linux 的 `PrivateMemorySize64` 可能包含 .NET GC 预留的巨大虚拟地址空间,只能用于辅助诊断,禁止与 Working Set 取较大值后作为拒绝请求或退出进程的依据。
158
+ - 内存阈值不能固定为与机器规格无关的小常量。平台按 cgroup 容器限额或宿主机物理内存动态计算,软阈值为 95%、硬阈值为 98%,不再增加环境变量或 appsettings 参数;多节点或数据库共用宿主机时必须给每个容器设置独立 memory limit,防止各节点重复使用整机额度。
159
+ - 内存修复不能只用“限制进程最大内存”代替根因治理。报告必须指出造成增长的具体对象/查询/队列,并分别验证根因边界和进程最后防线。
160
+
161
+ ## 数据库连接压力防护
162
+
163
+ 高并发问题不能只靠调大 MySQL `max_connections`。平台后端和 ORM 层必须把数据库连接视为受保护资源,所有普通接口、接口引擎、FormEngine、V8 事件、后台任务和批量导入都应该走统一连接打开入口。
164
+
165
+ 强制要求:
166
+
167
+ - ORM 层需要按连接串限制并发 `Open/OpenAsync`,避免瞬时 1 万个请求同时抢连接池或打爆 MySQL 握手。
168
+ - 遇到 `Host ... is blocked because of many connection errors`、`too many connections`、连接池超时、连接超时等错误时,应短时间熔断退避,快速失败并停止继续撞库。
169
+ - API 层需要对租户、用户、IP、重接口和写接口配置限流/并发阀门;压力超过阈值时返回明确的“系统繁忙/稍后重试”,不要无限排队。
170
+ - 连接串的 `Max Pool Size` 不能所有租户默认写很大;要按单进程、租户数、读写库和 MySQL `max_connections` 统一核算。
171
+ - 事务、`DbDataReader`、批量导入、后台任务必须确保连接按 `using/Dispose/Close` 释放;压测后要观察连接池、MySQL 当前连接数和等待线程是否回落。
172
+
173
+ ## V8 / 接口引擎失控保护
174
+
175
+ 接口引擎和表单 V8 事件属于用户可编程能力,必须默认假设会出现误写死循环、循环套循环查库、未分页大查询、外部接口长时间超时等问题。平台要在运行时给出硬保护,而不能只靠代码审查。
176
+
177
+ 强制要求:
178
+
179
+ - V8/Jint 默认超时、最大语句数、内存、递归深度必须保守;需要按租户或机器规格调整时统一在 SaaS 引擎 `sys_osclients` 的受控字段或接口引擎自身配置中维护,并由代码硬上限夹住。禁止为此新增 API 环境变量或 `appsettings` 节点。
180
+ - V8Engine.Run 入口必须有全局、租户级、接口/事件级并发阀门;过载时返回 `Code=0` 和“系统繁忙,请稍后重试”,不要继续进入事务和数据库。
181
+ - HTTP 入口应在进入 Controller 前做全局、租户、路由、接口引擎级背压;过载时直接返回 DosResult 风格 JSON,保证前端能弹出明确提示。
182
+ - 接口引擎配置里的 Timeout、MaxStatements、LimitMemory、LimitRecursion 不能无限放大,必须被平台级最大值夹住。
183
+ - 对外部 HTTP、AI、翻译、短信、第三方 ERP 这类慢操作,V8 扩展层必须设置超时和并发限制,不能把同步等待堆满线程池。
184
+
185
+ ## 复盘写回规则
186
186
 
187
187
  每次压测暴露通用问题后,把经验写回最贴近的 Skill:
188
188
 
@@ -191,31 +191,31 @@ API 网络监控必须同时展示“网卡/容器网络命名空间计数”和
191
191
  - 前端弹层、主题、表格搜索等 UI 运行时坑 -> `microi-client-frontend/SKILL.md`。
192
192
  - 插件/MCP 能力缺口 -> 本 Skill、`playwright-e2e` 或 `microi-system-delivery`。
193
193
 
194
- 本地 memory 只能作为临时笔记;对用户和其他安装插件的人有价值的规则,必须进入 `microi.skills`。
195
-
196
- ## 长任务限流原则
197
-
198
- 吾码经常承载大型业务系统,接口引擎、初始化任务、批量导入、批量修复、ERP/第三方同步等场景可能需要处理上万条数据,正常执行时间可能超过 5 分钟。平台保护不能简单把“执行时间长”判定为异常,也不能默认短等待后快速失败。
199
-
200
- 强制要求:
201
- - 长任务保护的核心是“并发阀门 + 排队限流 + 可配置超时”,不是粗暴拒绝。
202
- - 接口引擎/V8 默认执行窗口应能覆盖常见长任务,默认建议不少于 10 分钟;私有部署需要放宽时使用 SaaS 引擎 `sys_osclients` 的动态运行配置或接口引擎自身配置,并受平台代码硬上限约束,不得新增 API 环境变量或 `appsettings` 节点。
203
- - 入口限流对接口引擎/V8 应使用长排队窗口;只有排队窗口耗尽、请求被客户端取消、或平台资源已进入保护熔断时,才返回“系统繁忙/正在排队,请稍后重试”。
204
- - 不允许为了保护数据库而误杀合法批处理。真正需要治理的是无界并发、循环套循环查库、未分页大查询、外部接口无限等待和连接泄漏。
205
- - 对确实超过 HTTP/网关可承受时间的任务,应改造为后台任务/MQ/进度日志模式;后台任务进度优先通过吾码标准 WebSocket/SignalR 推送,不要让前端频繁轮询接口。但这属于交互形态升级,不应影响同步接口引擎的兼容性。
206
- - 应用商城安装、初始化多语言、批量导入、批量修复、跨系统同步等用户明确需要等待进度的操作,优先做成后台任务。前端按钮使用 `DiyCommon.ApiEngine.RunBackground` 或菜单按钮后台任务字段,后端接口引擎通过 `V8.Method.UpdateBackgroundTask({ Progress, Message, Total, Current })` 持续上报。
207
- - 后台任务必须有任务标题、状态、进度、耗时、错误摘要和清理/取消能力。取消只表示“请求停止后续步骤”,不能强行中断已经写入中的数据库事务。
208
-
209
- ## 恶意访问与雪崩防护
210
-
211
- 高并发保护要区分“合法排队”和“恶意攻击”。一个合法接口执行 5 分钟不代表攻击;一个 IP 在很短时间内疯狂请求、扫描不存在接口、反复触发 4xx/5xx,才应进入安全防护。
212
-
213
- 强制要求:
214
- - HTTP 层应提供全局、租户、路由、接口引擎/V8 等并发阀门,用于排队和保护资源;IP 层安全防护只用于识别高频恶意请求,不要替代业务并发治理。
215
- - 恶意访问记录不应每次请求都同步写数据库。最近访问明细可先保存在内存或专用轻量存储,真正封禁、解封、攻击识别事件才写系统日志和 `mci_` 安全表;必要的访问明细也要异步、采样或只记录可疑/拦截请求。
216
- - 自动封禁必须有白名单、自动解封时间、手动解封接口和系统日志记录;封禁响应要返回 DosResult 风格 JSON,让前端能明确提示。
217
- - 部署在 Nginx/网关后时,必须明确是否信任 `X-Forwarded-For`;公网直连且无法保证 Header 可信时,应使用真实 `RemoteIpAddress`。
218
- - 安全阈值默认要保守,避免误伤同一公司出口 NAT 下的正常用户;需要更激进的策略时应交给网关/WAF 或私有部署配置调整。
219
- - 系统级安全防护表必须使用 `mci_` 前缀,例如 `mci_security_attack_event`、`mci_security_ip_block`、`mci_security_access_log`。业务系统表不要使用 `mci_` 前缀。
220
- - 攻击事件落库必须做原因去重和时间窗合并,不要把同一个 IP、同一个原因、同一个时间窗的失败原因重复写成上万条记录。
221
- - 不能把“接口执行时间长”“排队时间长”“后台任务运行 5 分钟以上”单独作为恶意攻击依据。恶意判断主要看短时间高频请求、异常状态码爆发、扫描不存在路径、命中封禁后继续请求等行为。
194
+ 本地 memory 只能作为临时笔记;对用户和其他安装插件的人有价值的规则,必须进入 `microi.skills`。
195
+
196
+ ## 长任务限流原则
197
+
198
+ 吾码经常承载大型业务系统,接口引擎、初始化任务、批量导入、批量修复、ERP/第三方同步等场景可能需要处理上万条数据,正常执行时间可能超过 5 分钟。平台保护不能简单把“执行时间长”判定为异常,也不能默认短等待后快速失败。
199
+
200
+ 强制要求:
201
+ - 长任务保护的核心是“并发阀门 + 排队限流 + 可配置超时”,不是粗暴拒绝。
202
+ - 接口引擎/V8 默认执行窗口应能覆盖常见长任务,默认建议不少于 10 分钟;私有部署需要放宽时使用 SaaS 引擎 `sys_osclients` 的动态运行配置或接口引擎自身配置,并受平台代码硬上限约束,不得新增 API 环境变量或 `appsettings` 节点。
203
+ - 入口限流对接口引擎/V8 应使用长排队窗口;只有排队窗口耗尽、请求被客户端取消、或平台资源已进入保护熔断时,才返回“系统繁忙/正在排队,请稍后重试”。
204
+ - 不允许为了保护数据库而误杀合法批处理。真正需要治理的是无界并发、循环套循环查库、未分页大查询、外部接口无限等待和连接泄漏。
205
+ - 对确实超过 HTTP/网关可承受时间的任务,应改造为后台任务/MQ/进度日志模式;后台任务进度优先通过吾码标准 WebSocket/SignalR 推送,不要让前端频繁轮询接口。但这属于交互形态升级,不应影响同步接口引擎的兼容性。
206
+ - 应用商城安装、初始化多语言、批量导入、批量修复、跨系统同步等用户明确需要等待进度的操作,优先做成后台任务。前端按钮使用 `DiyCommon.ApiEngine.RunBackground` 或菜单按钮后台任务字段,后端接口引擎通过 `V8.Method.UpdateBackgroundTask({ Progress, Message, Total, Current })` 持续上报。
207
+ - 后台任务必须有任务标题、状态、进度、耗时、错误摘要和清理/取消能力。取消只表示“请求停止后续步骤”,不能强行中断已经写入中的数据库事务。
208
+
209
+ ## 恶意访问与雪崩防护
210
+
211
+ 高并发保护要区分“合法排队”和“恶意攻击”。一个合法接口执行 5 分钟不代表攻击;一个 IP 在很短时间内疯狂请求、扫描不存在接口、反复触发 4xx/5xx,才应进入安全防护。
212
+
213
+ 强制要求:
214
+ - HTTP 层应提供全局、租户、路由、接口引擎/V8 等并发阀门,用于排队和保护资源;IP 层安全防护只用于识别高频恶意请求,不要替代业务并发治理。
215
+ - 恶意访问记录不应每次请求都同步写数据库。最近访问明细可先保存在内存或专用轻量存储,真正封禁、解封、攻击识别事件才写系统日志和 `mci_` 安全表;必要的访问明细也要异步、采样或只记录可疑/拦截请求。
216
+ - 自动封禁必须有白名单、自动解封时间、手动解封接口和系统日志记录;封禁响应要返回 DosResult 风格 JSON,让前端能明确提示。
217
+ - 部署在 Nginx/网关后时,必须明确是否信任 `X-Forwarded-For`;公网直连且无法保证 Header 可信时,应使用真实 `RemoteIpAddress`。
218
+ - 安全阈值默认要保守,避免误伤同一公司出口 NAT 下的正常用户;需要更激进的策略时应交给网关/WAF 或私有部署配置调整。
219
+ - 系统级安全防护表必须使用 `mci_` 前缀,例如 `mci_security_attack_event`、`mci_security_ip_block`、`mci_security_access_log`。业务系统表不要使用 `mci_` 前缀。
220
+ - 攻击事件落库必须做原因去重和时间窗合并,不要把同一个 IP、同一个原因、同一个时间窗的失败原因重复写成上万条记录。
221
+ - 不能把“接口执行时间长”“排队时间长”“后台任务运行 5 分钟以上”单独作为恶意攻击依据。恶意判断主要看短时间高频请求、异常状态码爆发、扫描不存在路径、命中封禁后继续请求等行为。
@@ -1,6 +1,6 @@
1
- ---
1
+ ---
2
2
  name: playwright-e2e
3
- description: 按 Microi 系统真实业务逻辑进行 Playwright 全自动化、全面测试。用于测试 PC Vue、本地多 ApiBase/OsClient 独立浏览器上下文、远端运行目标识别、前端微服务菜单切换与 keep-alive/LRU、uni-app H5、网站、界面引擎、移动商城、ApiEngine/FormEngine 契约、登录流程、写入闭环、网络防护、截图、报告和 Playwright Test for VSCode 集成。
3
+ description: 按 Microi 系统真实业务逻辑进行 Playwright 全自动化、全面测试。用于测试 PC Vue、本地多 ApiBase/OsClient 独立浏览器上下文、远端运行目标识别、前端微服务菜单切换与 keep-alive/LRU、uni-app H5、网站、界面引擎、移动商城、ApiEngine/FormEngine 契约、登录流程、写入闭环、网络防护、截图、报告和 Playwright Test for VSCode 集成。
4
4
  ---
5
5
 
6
6
  > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
@@ -47,15 +47,15 @@ AI 在工作区内生成的**一次性临时脚本、诊断文件、截图、测
47
47
  |------|---------|
48
48
  | 一次性 Python/JS/PS1 脚本 | `<workspace-root>/.tmp/` |
49
49
  | 诊断截图、调试输出 | `<workspace-root>/.tmp/screenshots/` 或子目录 |
50
- | E2E 测试产物(Microi.VSCode 插件生成) | `<workspace-root>/.microi-e2e/` |
51
- | AI 一次性 Playwright 脚本、截图、日志、报告 | `<workspace-root>/.tmp/`、`<workspace-root>/.tmp/screenshots/`、`<workspace-root>/.tmp/reports/` |
50
+ | E2E 测试产物(Microi.VSCode 插件生成) | `<workspace-root>/.microi-e2e/` |
51
+ | AI 一次性 Playwright 脚本、截图、日志、报告 | `<workspace-root>/.tmp/`、`<workspace-root>/.tmp/screenshots/`、`<workspace-root>/.tmp/reports/` |
52
52
  | 性能测试报告 | `<workspace-root>/.microi-performance/`(仅限此目录) |
53
53
 
54
54
  **禁止在根目录创建的文件类型**:`*.mjs`、`*.py`、`*.ps1`、`*.sh`(一次性脚本)、`*.png`、`screenshots/`、`node_modules/`(无 package.json 时)、`obj/`(非 .NET 项目文件)、`dark-mode-*/`、`test-*/` 等临时目录。
55
55
 
56
- `.tmp/` 目录已在 `.gitignore` 中排除,AI 可以在此自由创建临时文件。任务完成后如无价值可以不清理,也可以整体删除该目录。
57
-
58
- **2026-06 强制补充**:AI 手写的一次性 Playwright 验证脚本、运行日志、截图和报告只能写到工作区根目录 `.tmp/`。不要写到 `Microi.Client/`、`Microi.Server/`、`microi.doc/` 或其它子项目目录,即使这些目录已有 `tests/` 目录也不例外。只有 Microi.VSCode 插件正式初始化的可复用 E2E 工程,才使用 `.microi-e2e/`。
56
+ `.tmp/` 目录已在 `.gitignore` 中排除,AI 可以在此自由创建临时文件。任务完成后如无价值可以不清理,也可以整体删除该目录。
57
+
58
+ **2026-06 强制补充**:AI 手写的一次性 Playwright 验证脚本、运行日志、截图和报告只能写到工作区根目录 `.tmp/`。不要写到 `Microi.Client/`、`Microi.Server/`、`microi.doc/` 或其它子项目目录,即使这些目录已有 `tests/` 目录也不例外。只有 Microi.VSCode 插件正式初始化的可复用 E2E 工程,才使用 `.microi-e2e/`。
59
59
 
60
60
  <!-- /microi-progressive:chunk -->
61
61
  <!-- microi-progressive:chunk id=playwright-e2e-003 sha256=69b8842a221a0de60f8605c5059deee391be0f16f0b6cbc5ddfb3cfd210268db -->
@@ -93,87 +93,87 @@ PW_BROWSER_CHANNEL=msedge
93
93
 
94
94
  常用业务变量:
95
95
 
96
- ```bash
97
- PW_LOGIN_ENGINE=member_login
98
- PW_TEST_ACCOUNT=<从本地配置读取或用环境变量覆盖>
99
- PW_TEST_PASSWORD=<从本地配置读取或用环境变量覆盖>
100
- PW_HOME_PATH=/#/pages/index/index
101
- ```
102
-
96
+ ```bash
97
+ PW_LOGIN_ENGINE=member_login
98
+ PW_TEST_ACCOUNT=<从本地配置读取或用环境变量覆盖>
99
+ PW_TEST_PASSWORD=<从本地配置读取或用环境变量覆盖>
100
+ PW_HOME_PATH=/#/pages/index/index
101
+ ```
102
+
103
103
  <!-- /microi-progressive:chunk -->
104
104
  <!-- microi-progressive:chunk id=playwright-e2e-005 sha256=a66696c3263f060d0b7be309a527fca6a9bad95dd534eabbe84f1b6539770d8e -->
105
- ## 本地测试账号自动发现
106
-
107
- 当没有显式传入 `PW_TEST_ACCOUNT` / `PW_TEST_PASSWORD` / `MICROI_OSCLIENT` 时,AI 不要把账号密码写入后端配置来制造旁路:
108
-
109
- 1. 读取 `Microi.Server/Microi.net.Api/.microi-local`,取得当前环境名。
110
- 2. 账号密码只从用户本轮明确提供、`PW_TEST_ACCOUNT` / `PW_TEST_PASSWORD`、CI Secret 或既有受保护登录态取得;`appsettings.*.json` 不再保存测试账号密码。
111
- 3. 这些值只作为自动化进程的登录输入或接口请求参数使用。日志、最终回复、截图说明、报告和异常消息中必须写成 `<redacted>` 或“本地配置凭据”,不要展开真实账号密码、Token、连接串或 Redis 密码。
112
- 4. 如果凭据不存在或登录失败,再报告具体阻塞点,例如“未提供受保护测试凭据”“本地后端未启动”“登录接口返回 Code=0”,不要泛泛说无法测试。
113
-
114
- ### 跨 ApiBase / OsClient 本地自动化(强制)
115
-
116
- 1. 复用工作区唯一的 `61500` Vite 服务,但每组 `ApiBase + OsClient` 创建独立
117
- `browser.newContext()`;禁止在同一个 context 的多个 Page 中混测不同租户。
118
- 2. 本地入口固定把参数放在 `#` 前:
119
- `http://localhost:61500/?OsClient=${encodeURIComponent(osClient)}&ApiBase=${encodeURIComponent(apiBase)}#/route`。
120
- URL 参数应覆盖 `index.html`、`src/config.json`、Pinia 和 localStorage。
121
- 3. 页面初始化后读取 `window.__MICROI_RUNTIME_ENDPOINT__`,断言实际 ApiBase/OsClient 与测试目标
122
- 完全一致再登录或点击业务。该对象不得包含 Token。
123
- 4. 从线上地址复现时,先在一次性独立 context 读取上述对象;旧版回退到页面全局值、
124
- `localStorage['microi.net']` 和域名租户解析。不能根据标题猜租户,也不能复用线上 context 跑本地。
125
- 5. 人工第二租户至少使用无痕窗口;多个无痕窗口可能共享同一临时会话,更多并行目标使用独立
126
- Profile/`--user-data-dir`。自动化收尾只关闭自己创建的 context/browser。
127
-
128
- <!-- /microi-progressive:chunk -->
105
+ ## 本地测试账号自动发现
106
+
107
+ 当没有显式传入 `PW_TEST_ACCOUNT` / `PW_TEST_PASSWORD` / `MICROI_OSCLIENT` 时,AI 不要把账号密码写入后端配置来制造旁路:
108
+
109
+ 1. 读取 `Microi.Server/Microi.net.Api/.microi-local`,取得当前环境名。
110
+ 2. 账号密码只从用户本轮明确提供、`PW_TEST_ACCOUNT` / `PW_TEST_PASSWORD`、CI Secret 或既有受保护登录态取得;`appsettings.*.json` 不再保存测试账号密码。
111
+ 3. 这些值只作为自动化进程的登录输入或接口请求参数使用。日志、最终回复、截图说明、报告和异常消息中必须写成 `<redacted>` 或“本地配置凭据”,不要展开真实账号密码、Token、连接串或 Redis 密码。
112
+ 4. 如果凭据不存在或登录失败,再报告具体阻塞点,例如“未提供受保护测试凭据”“本地后端未启动”“登录接口返回 Code=0”,不要泛泛说无法测试。
113
+
114
+ ### 跨 ApiBase / OsClient 本地自动化(强制)
115
+
116
+ 1. 复用工作区唯一的 `61500` Vite 服务,但每组 `ApiBase + OsClient` 创建独立
117
+ `browser.newContext()`;禁止在同一个 context 的多个 Page 中混测不同租户。
118
+ 2. 本地入口固定把参数放在 `#` 前:
119
+ `http://localhost:61500/?OsClient=${encodeURIComponent(osClient)}&ApiBase=${encodeURIComponent(apiBase)}#/route`。
120
+ URL 参数应覆盖 `index.html`、`src/config.json`、Pinia 和 localStorage。
121
+ 3. 页面初始化后读取 `window.__MICROI_RUNTIME_ENDPOINT__`,断言实际 ApiBase/OsClient 与测试目标
122
+ 完全一致再登录或点击业务。该对象不得包含 Token。
123
+ 4. 从线上地址复现时,先在一次性独立 context 读取上述对象;旧版回退到页面全局值、
124
+ `localStorage['microi.net']` 和域名租户解析。不能根据标题猜租户,也不能复用线上 context 跑本地。
125
+ 5. 人工第二租户至少使用无痕窗口;多个无痕窗口可能共享同一临时会话,更多并行目标使用独立
126
+ Profile/`--user-data-dir`。自动化收尾只关闭自己创建的 context/browser。
127
+
128
+ <!-- /microi-progressive:chunk -->
129
129
  <!-- microi-progressive:chunk id=playwright-e2e-006 sha256=6aeefebda3a9e598564c53c2f8028a4ccefe2291c4c7c7ae4781ca15fb5d0697 -->
130
- ## 后端改动后的 E2E 前置动作
131
-
132
- 如果本轮任务修改过 `Microi.Server/**` 后端源码、配置、控制器、服务、依赖项目或接口行为,跑 Playwright、页面截图、接口验收或前后端联调前,必须先按 `workspace-conventions` 的“后端代码改动后的重启验收”完成:
133
-
134
- 1. 编译后端。
135
- 2. 停止旧的本地 `Microi.net.Api` 进程。
136
- 3. 在 `Microi.Server/Microi.net.Api` 目录用 `dotnet run --launch-profile Microi.net.Api` 重新启动。
137
- 4. 从 launch profile 回读实际地址(当前标准工作区为 `https://localhost:61501`),验证端口已监听并且进程未立即崩溃。
138
-
139
- 不要只说“代码已编译”或“需要用户自己重启后端”;除非用户明确要求不要中断当前服务,否则 AI 要主动完成重启。
140
-
130
+ ## 后端改动后的 E2E 前置动作
131
+
132
+ 如果本轮任务修改过 `Microi.Server/**` 后端源码、配置、控制器、服务、依赖项目或接口行为,跑 Playwright、页面截图、接口验收或前后端联调前,必须先按 `workspace-conventions` 的“后端代码改动后的重启验收”完成:
133
+
134
+ 1. 编译后端。
135
+ 2. 停止旧的本地 `Microi.net.Api` 进程。
136
+ 3. 在 `Microi.Server/Microi.net.Api` 目录用 `dotnet run --launch-profile Microi.net.Api` 重新启动。
137
+ 4. 从 launch profile 回读实际地址(当前标准工作区为 `https://localhost:61501`),验证端口已监听并且进程未立即崩溃。
138
+
139
+ 不要只说“代码已编译”或“需要用户自己重启后端”;除非用户明确要求不要中断当前服务,否则 AI 要主动完成重启。
140
+
141
141
  <!-- /microi-progressive:chunk -->
142
142
  <!-- microi-progressive:chunk id=playwright-e2e-007 sha256=8776ce89491f11cbf6c6e6e9ef0cd430aa21efc60c1dbe1559ec9e905c5d0a9e -->
143
- ## 服务自启动纪律(必做)
144
-
145
- 执行自动化测试、截图巡检、接口引擎回读、`/apiengine/{key}` 验收时,如果本地后端或前端不可达,不能把 `fetch failed`、`ECONNREFUSED`、`000 Failed to connect`、端口无人监听当作任务终点。必须先自动启动所需服务,再继续完整验证。
146
-
147
- 同一工作区有多个 AI 对话时,服务自启动还必须遵守共享生命周期:
148
-
149
- - 先检查 `.tmp/microi-process-state/release.lock`。发布锁存在时禁止 Playwright `webServer`、
150
- 自愈脚本或 AI 重新抢占 `61500/61501`;等待发布结束后重新检查。
151
- - 端口健康且 PID/命令行属于当前工作区时直接复用,不得每个对话都无条件“先杀再启动”。
152
- 必须重载源码时才串行重启,并在状态播报中说明旧/新 PID。
153
- - 本地长期后端使用项目目录中的 `dotnet run --launch-profile Microi.net.Api`,禁止把
154
- `bin/Release/net10.0` 或 `bin/Release/publish` 的 DLL 作为长期测试服务,否则会锁住
155
- 一键发布的 Release 输出。
156
- - 一次性测试要关闭自己创建的 browser/context 和临时 webServer。VS Code 持有的
157
- `playwright test-server` 与用户 Edge/Chrome 不属于孤儿清理;禁止按进程名结束所有
158
- `node/dotnet/chrome/msedge`。
159
- - 只读盘点或精确停止使用 `Microi.Server/tools/Microi.LocalProcessManager.ps1` 的
160
- `Status`、`StopBackend`、`StopFrontend`,不能让用户在任务管理器里猜 PID。
161
-
162
- 默认本地后端:
163
-
164
- ```powershell
165
- Push-Location Microi.Server/Microi.net.Api
166
- dotnet run --launch-profile Microi.net.Api
167
- Pop-Location
168
- ```
169
-
170
- 普通本地启动不要手动设置 `ASPNETCORE_ENVIRONMENT` / `DOTNET_ENVIRONMENT`;后端会读取 `Microi.Server/Microi.net.Api/.microi-local`,再加载对应的 `appsettings.{Env}.json`。如果测试脚本显式注入环境变量,则以脚本注入为准。
143
+ ## 服务自启动纪律(必做)
144
+
145
+ 执行自动化测试、截图巡检、接口引擎回读、`/apiengine/{key}` 验收时,如果本地后端或前端不可达,不能把 `fetch failed`、`ECONNREFUSED`、`000 Failed to connect`、端口无人监听当作任务终点。必须先自动启动所需服务,再继续完整验证。
146
+
147
+ 同一工作区有多个 AI 对话时,服务自启动还必须遵守共享生命周期:
148
+
149
+ - 先检查 `.tmp/microi-process-state/release.lock`。发布锁存在时禁止 Playwright `webServer`、
150
+ 自愈脚本或 AI 重新抢占 `61500/61501`;等待发布结束后重新检查。
151
+ - 端口健康且 PID/命令行属于当前工作区时直接复用,不得每个对话都无条件“先杀再启动”。
152
+ 必须重载源码时才串行重启,并在状态播报中说明旧/新 PID。
153
+ - 本地长期后端使用项目目录中的 `dotnet run --launch-profile Microi.net.Api`,禁止把
154
+ `bin/Release/net10.0` 或 `bin/Release/publish` 的 DLL 作为长期测试服务,否则会锁住
155
+ 一键发布的 Release 输出。
156
+ - 一次性测试要关闭自己创建的 browser/context 和临时 webServer。VS Code 持有的
157
+ `playwright test-server` 与用户 Edge/Chrome 不属于孤儿清理;禁止按进程名结束所有
158
+ `node/dotnet/chrome/msedge`。
159
+ - 只读盘点或精确停止使用 `Microi.Server/tools/Microi.LocalProcessManager.ps1` 的
160
+ `Status`、`StopBackend`、`StopFrontend`,不能让用户在任务管理器里猜 PID。
161
+
162
+ 默认本地后端:
163
+
164
+ ```powershell
165
+ Push-Location Microi.Server/Microi.net.Api
166
+ dotnet run --launch-profile Microi.net.Api
167
+ Pop-Location
168
+ ```
169
+
170
+ 普通本地启动不要手动设置 `ASPNETCORE_ENVIRONMENT` / `DOTNET_ENVIRONMENT`;后端会读取 `Microi.Server/Microi.net.Api/.microi-local`,再加载对应的 `appsettings.{Env}.json`。如果测试脚本显式注入环境变量,则以脚本注入为准。
171
171
 
172
172
  默认 PC 前端:
173
173
 
174
174
  ```powershell
175
175
  Push-Location Microi.Client
176
- npm run dev -- --host 0.0.0.0 --port 61500
176
+ npm run dev -- --host 0.0.0.0 --port 61500
177
177
  Pop-Location
178
178
  ```
179
179
 
@@ -182,12 +182,12 @@ uni-app H5 或移动端前端按项目自身命令启动,例如 `npm run dev:h
182
182
  执行顺序:先检查端口/健康接口是否可达;不可达则用后台终端启动;等待服务输出监听地址;再重试接口同步、页面打开、Playwright 截图和断言。只有启动命令失败、缺少依赖、数据库连接失败、端口冲突无法自动换端口且无替代配置时,才算真正阻塞,并且要报告具体失败命令和错误。
183
183
 
184
184
  <!-- /microi-progressive:chunk -->
185
- ## 详细参考路由(渐进披露)
186
-
187
- ### 菜单微服务生命周期验收(强制)
188
-
189
- 菜单型 MicroService 使用 `runtime-keep-alive` 单一缓存所有者。E2E 必须覆盖至少 3 条子路由连续切换 8 轮,确认返回后状态仍在、页面无永久骨架屏或空白;继续打开第 6 个实例,确认 LRU 只淘汰最久未使用的隐藏实例。还要观察 `appstate-change`:`afterhidden` 后后台任务应暂停,`aftershow` 后应幂等恢复;关闭 Tab、关闭其它/全部以及退出登录后,对应运行时必须被销毁。
190
-
185
+ ## 详细参考路由(渐进披露)
186
+
187
+ ### 菜单微服务生命周期验收(强制)
188
+
189
+ 菜单型 MicroService 使用 `runtime-keep-alive` 单一缓存所有者。E2E 必须覆盖至少 3 条子路由连续切换 8 轮,确认返回后状态仍在、页面无永久骨架屏或空白;继续打开第 6 个实例,确认 LRU 只淘汰最久未使用的隐藏实例。还要观察 `appstate-change`:`afterhidden` 后后台任务应暂停,`aftershow` 后应幂等恢复;关闭 Tab、关闭其它/全部以及退出登录后,对应运行时必须被销毁。
190
+
191
191
  仅在当前任务涉及对应主题时读取;下列文件合计保留了原 SKILL.md 的全部详细知识。
192
192
 
193
193
  - [references/progressive-01-全自动登录-免验证码-但不免密码-必读.md](references/progressive-01-全自动登录-免验证码-但不免密码-必读.md):全自动登录(免验证码,但不免密码)——必读;表单引擎卡死/递归更新全自动化诊断;移动端视觉与资源验收;测试证据必须绑定需求编号;移动端/H5 回归纪律