@microi.net/cli 5.8.5 → 5.8.6

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 (211) 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/LICENSE +21 -21
  8. package/README.md +71 -71
  9. package/assets/build-meta.json +6 -6
  10. package/assets/feature-matrix.json +138 -138
  11. package/assets/logo.svg +4 -4
  12. package/cordis.patch.yml +1 -1
  13. package/package.json +1 -1
  14. package/scripts/codex-marketplace.json +20 -20
  15. package/scripts/mcp-codex-stdio-adapter.js +189 -189
  16. package/scripts/mcp-trae-windows-launcher.cmd +21 -21
  17. package/scripts/microi-cli-mcp.js +7 -7
  18. package/scripts/microi-cli.js +66 -65
  19. package/scripts/microi-codex-broker.js +450 -450
  20. package/scripts/microi-codex-router.js +618 -618
  21. package/scripts/microi-skills.meta.json +384 -384
  22. package/skills/.microi-skills-version.json +2 -2
  23. package/skills/.progressive-disclosure-manifest.json +3566 -3566
  24. package/skills/README.md +287 -287
  25. package/skills/ai-engine/SKILL.md +269 -265
  26. package/skills/ai-engine/agents/openai.yaml +4 -4
  27. package/skills/ai-engine/references/ai-employees.md +48 -48
  28. package/skills/ai-engine/references/self-hosted-digital-human.md +59 -59
  29. package/skills/ai-platform-governance/SKILL.md +177 -177
  30. package/skills/ai-platform-governance/references/progressive-01-/345/212/237/350/203/275/345/274/200/345/205/263.md +190 -190
  31. package/skills/app-store/SKILL.md +525 -525
  32. package/skills/app-store/agents/openai.yaml +4 -4
  33. package/skills/business-blueprint/SKILL.md +193 -193
  34. package/skills/datasource-engine/SKILL.md +93 -93
  35. package/skills/datasource-engine/agents/openai.yaml +4 -4
  36. package/skills/dos-orm/SKILL.md +97 -97
  37. package/skills/dos-orm/references/api-reference.md +229 -229
  38. package/skills/email-engine/SKILL.md +81 -81
  39. package/skills/email-engine/references/v8-email.md +34 -34
  40. package/skills/job-engine/SKILL.md +176 -176
  41. package/skills/job-engine/agents/openai.yaml +4 -4
  42. package/skills/message-notification/SKILL.md +156 -156
  43. package/skills/message-notification/agents/openai.yaml +5 -5
  44. package/skills/message-notification/references/contracts.md +102 -102
  45. package/skills/microi/SKILL.md +14 -14
  46. package/skills/microi-ai-app-auth.js +652 -652
  47. package/skills/microi-ai-application/SKILL.md +115 -115
  48. package/skills/microi-ai-application/agents/openai.yaml +4 -4
  49. package/skills/microi-ai-application/references/frontend-baseline.md +164 -164
  50. package/skills/microi-client-frontend/SKILL.md +244 -244
  51. 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 +144 -144
  52. 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 +196 -196
  53. 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 +167 -167
  54. package/skills/microi-codex/SKILL.md +102 -102
  55. package/skills/microi-codex-installer/SKILL.md +231 -231
  56. package/skills/microi-codex-installer/agents/openai.yaml +7 -7
  57. package/skills/microi-datasource-mapping/SKILL.md +122 -122
  58. package/skills/microi-db-schema/SKILL.md +175 -175
  59. package/skills/microi-db-schema/agents/openai.yaml +4 -4
  60. package/skills/microi-db-schema/references/core-tables.md +695 -695
  61. package/skills/microi-db-schema/references/form-component-options.md +256 -256
  62. package/skills/microi-db-schema/references/schema-overview.md +202 -202
  63. package/skills/microi-db-schema/references/schema.md +646 -646
  64. package/skills/microi-db-schema/references/table-catalog.md +1599 -1599
  65. package/skills/microi-deployment/SKILL.md +221 -221
  66. package/skills/microi-deployment/references/deployment-matrix.md +109 -109
  67. package/skills/microi-docs-coverage/SKILL.md +133 -133
  68. package/skills/microi-docs-coverage/references/capability-map.md +91 -91
  69. package/skills/microi-docs-coverage/scripts/audit-doc-skill-coverage.mjs +894 -894
  70. package/skills/microi-form-engine/SKILL.md +333 -333
  71. package/skills/microi-form-engine/references/component-catalog.md +218 -218
  72. package/skills/microi-form-engine/references/data-source-events.md +124 -124
  73. package/skills/microi-form-layout/SKILL.md +205 -205
  74. 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
  75. package/skills/microi-frontend-sdk/SKILL.md +194 -194
  76. 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 +176 -176
  77. package/skills/microi-left-right-layout/SKILL.md +141 -141
  78. package/skills/microi-microservice/SKILL.md +326 -324
  79. package/skills/microi-microservice/references/runtime-delivery.md +278 -278
  80. package/skills/microi-mobile-app-quality/SKILL.md +185 -185
  81. 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
  82. package/skills/microi-mobile-app-quality/references/progressive-02-9-/344/270/273/351/242/230/345/210/207/346/215/242/345/277/205/351/241/273/347/234/237/345/256/236/344/270/224/345/205/250/345/261/200/347/224/237/346/225/210.md +128 -128
  83. package/skills/microi-solution-quotation/SKILL.md +78 -78
  84. package/skills/microi-solution-quotation/agents/openai.yaml +4 -4
  85. package/skills/microi-solution-quotation/scripts/build_solution_quote.py +296 -296
  86. package/skills/microi-sso/SKILL.md +92 -92
  87. package/skills/microi-sso/references/acceptance.md +49 -49
  88. package/skills/microi-sso/references/configuration-and-security.md +53 -53
  89. package/skills/microi-sso/references/inbound.md +53 -53
  90. package/skills/microi-sso/references/outbound.md +39 -39
  91. package/skills/microi-system-delivery/SKILL.md +137 -137
  92. package/skills/microi-system-delivery/references/progressive-01-/346/240/207/345/207/206/345/267/245/344/275/234/346/265/201.md +193 -193
  93. 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 +217 -217
  94. package/skills/microi-ui/SKILL.md +192 -192
  95. package/skills/microi-ui/references/progressive-01-/347/247/273/345/212/250/347/253/257/345/234/272/346/231/257/350/223/235/345/233/276.md +183 -183
  96. package/skills/microi-uniapp-frontend/SKILL.md +193 -193
  97. 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 +225 -225
  98. 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 +154 -154
  99. package/skills/microi.v8.js +1921 -1921
  100. package/skills/module-engine/SKILL.md +255 -255
  101. package/skills/module-engine/references/module-config.md +204 -204
  102. package/skills/ocr-engine/SKILL.md +113 -113
  103. package/skills/ocr-engine/agents/openai.yaml +4 -4
  104. package/skills/page-engine/SKILL.md +206 -206
  105. package/skills/page-engine/examples/compact-dashboard.json +1444 -1444
  106. 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 +234 -234
  107. 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 +60 -60
  108. package/skills/performance-testing/SKILL.md +221 -221
  109. package/skills/playwright-e2e/SKILL.md +196 -196
  110. 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 +173 -173
  111. 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 +183 -183
  112. package/skills/playwright-e2e/references/progressive-03-microi-helper-/346/250/241/346/235/277.md +221 -221
  113. package/skills/playwright-e2e/references/progressive-04-ci-/345/273/272/350/256/256.md +115 -115
  114. package/skills/print-engine/SKILL.md +259 -259
  115. package/skills/production-readonly-audit/SKILL.md +41 -41
  116. package/skills/report-engine/SKILL.md +71 -71
  117. package/skills/report-engine/agents/openai.yaml +4 -4
  118. package/skills/scripts/optimize-progressive-disclosure.mjs +204 -204
  119. package/skills/scripts/refresh-progressive-disclosure.mjs +64 -64
  120. package/skills/scripts/sync-embedded-skills.mjs +46 -46
  121. package/skills/scripts/validate-progressive-disclosure.mjs +57 -57
  122. package/skills/search-engine/SKILL.md +75 -75
  123. package/skills/search-engine/agents/openai.yaml +4 -4
  124. package/skills/spider-engine/SKILL.md +190 -190
  125. package/skills/system-observability/SKILL.md +248 -248
  126. package/skills/system-observability/references/memory-incident-triage.md +77 -77
  127. package/skills/translate-engine/SKILL.md +140 -140
  128. package/skills/translate-engine/agents/openai.yaml +4 -4
  129. package/skills/ui-design/SKILL.md +223 -223
  130. package/skills/ui-design/assets/pattern-showcase/app.js +54 -54
  131. package/skills/ui-design/assets/pattern-showcase/index.html +163 -163
  132. package/skills/ui-design/assets/pattern-showcase/styles.css +311 -311
  133. package/skills/ui-design/assets/templates/MCI-DESIGN.md +206 -206
  134. package/skills/ui-design/references/design-pattern-library.md +184 -184
  135. package/skills/ui-design/references/mci-design-contract.md +163 -163
  136. package/skills/ui-design/references/motion-and-media.md +78 -78
  137. package/skills/ui-design/references/product-flow-recipes.md +94 -94
  138. package/skills/ui-design/references/progressive-01-/351/242/234/350/211/262/344/275/223/347/263/273-css-variables-/346/224/257/346/214/201/344/270/273/351/242/230/345/210/207/346/215/242.md +218 -218
  139. package/skills/ui-design/references/progressive-02-/345/255/227/344/275/223.md +164 -164
  140. package/skills/ui-design/references/progressive-03-/345/212/250/346/225/210/350/247/204/350/214/203-/344/270/260/345/257/214/344/275/206/344/270/215/345/215/241.md +235 -235
  141. package/skills/ui-design/references/progressive-04-/347/273/204/344/273/266/351/243/216/346/240/274/351/200/237/346/237/245.md +152 -152
  142. package/skills/ui-design/references/progressive-05-/347/247/273/345/212/250/347/253/257/344/270/223/347/224/250/350/247/204/350/214/203.md +238 -238
  143. package/skills/ui-design/references/progressive-06-/344/270/273/351/242/230/345/210/207/346/215/242/345/256/236/347/216/260.md +194 -194
  144. package/skills/ui-design/references/progressive-07-/351/200/237/346/237/245-/344/273/216/345/244/264/346/220/255/345/273/272/344/270/200/344/270/252/347/247/273/345/212/250/347/253/257/351/241/265/351/235/242.md +207 -207
  145. package/skills/ui-design/references/progressive-08-/350/241/250/345/215/225/345/210/206/347/273/204/350/247/204/350/214/203-tabs-vs-collapsegroup-/345/274/272/345/210/266.md +142 -142
  146. package/skills/uniapp-mall-assets/SKILL.md +176 -176
  147. package/skills/unity-integration/SKILL.md +171 -171
  148. package/skills/unity-integration/agents/openai.yaml +4 -4
  149. package/skills/unity-integration/references/ai-app-delivery.md +119 -119
  150. package/skills/unity-integration/references/sdk-api.md +82 -82
  151. package/skills/unity-integration/references/toolbox-migration.md +66 -66
  152. package/skills/unity-integration/references/webgl-hosting.md +57 -57
  153. package/skills/v8-api-config/SKILL.md +388 -388
  154. package/skills/v8-cache-pattern/SKILL.md +312 -312
  155. package/skills/v8-crud-api/SKILL.md +178 -178
  156. 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 +226 -226
  157. package/skills/v8-crud-api/references/progressive-02-where-/346/235/241/344/273/266/350/257/255/346/263/225/351/200/237/346/237/245.md +49 -49
  158. package/skills/v8-debugging/SKILL.md +284 -284
  159. package/skills/v8-explorer-tree/SKILL.md +228 -228
  160. package/skills/v8-export-import/SKILL.md +219 -219
  161. 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 +211 -211
  162. package/skills/v8-export-import/references/progressive-02-powerpoint-/345/257/274/345/207/272.md +202 -202
  163. 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 +42 -42
  164. package/skills/v8-file-upload/SKILL.md +284 -284
  165. 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 +263 -263
  166. 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 +161 -161
  167. package/skills/v8-formengine-http/SKILL.md +238 -238
  168. package/skills/v8-frontend-events/SKILL.md +180 -180
  169. package/skills/v8-frontend-events/references/bluetooth-print-api.md +135 -135
  170. package/skills/v8-frontend-events/references/bluetooth-print.md +258 -258
  171. package/skills/v8-frontend-events/references/progressive-01-/345/210/227/350/241/250/344/272/213/344/273/266.md +219 -219
  172. package/skills/v8-http-integration/SKILL.md +182 -182
  173. package/skills/v8-http-integration/references/progressive-01-get-/350/257/267/346/261/202.md +220 -220
  174. 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 +44 -44
  175. package/skills/v8-image-processing/SKILL.md +190 -190
  176. package/skills/v8-image-processing/agents/openai.yaml +4 -4
  177. package/skills/v8-image-processing/references/api-reference.md +623 -623
  178. package/skills/v8-menu-buttons/SKILL.md +186 -186
  179. package/skills/v8-menu-buttons/references/progressive-01-2-/346/214/211/351/222/256/345/257/271/350/261/241-schema.md +222 -222
  180. 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
  181. 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 +104 -104
  182. package/skills/v8-mongodb/SKILL.md +200 -200
  183. package/skills/v8-mq-mqtt/SKILL.md +176 -176
  184. package/skills/v8-mq-mqtt/references/mqtt-production.md +342 -342
  185. package/skills/v8-mq-mqtt/references/progressive-01-v8-mqtt-iot-/347/211/251/350/201/224/347/275/221.md +181 -181
  186. package/skills/v8-mq-mqtt/scripts/check-mqtt-skill-coverage.mjs +203 -203
  187. package/skills/v8-saas-multi-tenant/SKILL.md +305 -305
  188. package/skills/v8-security/SKILL.md +210 -210
  189. package/skills/v8-security/references/progressive-01-2-/346/235/203/351/231/220/346/240/241/351/252/214.md +200 -200
  190. package/skills/v8-security/references/progressive-02-7-/346/227/245/345/277/227/350/256/260/345/275/225.md +160 -160
  191. package/skills/v8-sql-query/SKILL.md +302 -302
  192. package/skills/v8-table-event/SKILL.md +176 -176
  193. 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 +216 -216
  194. 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 +46 -46
  195. package/skills/v8-tcp-integration/SKILL.md +147 -147
  196. package/skills/v8-tcp-integration/agents/openai.yaml +4 -4
  197. package/skills/v8-template-engine/SKILL.md +167 -167
  198. package/skills/v8-utilities/SKILL.md +104 -104
  199. package/skills/v8-utilities/references/client-api-index.md +143 -143
  200. package/skills/v8-utilities/references/platform-http-routes.md +83 -83
  201. package/skills/v8-utilities/references/server-api-index.md +188 -188
  202. package/skills/v8-workflow/SKILL.md +252 -252
  203. package/skills/v8-workflow/references/progressive-01-/350/212/202/347/202/271/345/274/200/345/247/213-v8-/344/272/213/344/273/266.md +180 -180
  204. package/skills/v8-workflow/references/workflow-configuration.md +49 -49
  205. package/skills/vision-engine/SKILL.md +160 -160
  206. package/skills/vision-engine/agents/openai.yaml +4 -4
  207. package/skills/vision-engine/references/architecture-and-acceptance.md +194 -194
  208. package/skills/workspace-conventions/SKILL.md +273 -273
  209. 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 +209 -209
  210. 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 +217 -217
  211. 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 +27 -27
@@ -1,217 +1,217 @@
1
- # microi-system-delivery 详细参考 2
2
-
3
- > 按需读取;本文件由 SKILL.md 的原章节无损拆分。
4
-
5
- <!-- microi-progressive:chunk id=microi-system-delivery-006 sha256=4b999e29e04c192319690a886ba25bb8952d5cc1910db8fa151b583d599b2be5 -->
6
- ## 自动化测试必须覆盖的坑
7
-
8
- ### 后端统一测试与发布门禁
9
-
10
- - 官方或社区独立业务应用、游戏和客户项目在应用自己的 `tests/` 或独立测试工程维护回归,由应用自己的测试及发布入口执行;不得通过直接放文件、转调包装或自动扫描加入平台 Quick/Full。官方商城发布不使业务应用变为平台内置能力。平台 SDK、商城协议、安装器及通用缺陷的最小回归仍由平台负责。
11
-
12
- - 每个平台新功能或 Bug 修复必须提供对应回归用例;平台 C# 进入 `Microi.Tests`,平台前端与内置资源/V8 测试进入平台 Node 自动发现范围。修复先保留失败证据,再跑成功、边界、异常、权限及旧格式兼容用例;不能仅添加字符串存在断言替代行为测试。
13
- - `run-node-regressions.mjs` 自动发现 `Microi.Tests`、`OfficialApplications/Resource`、`Microi.Client/tests` 的确定性测试。新文件无法分类即失败;Playwright 用例必须走真实浏览器入口,不能用 Node 执行后把跳过当通过。所有计数需回读,0 用例、失败、取消、skipped、todo 均拒绝发布。
14
- - 仅推送模式也必须取得发布锁并执行 Full。源码候选哈希、构建上下文哈希与 `release-artifact.mjs` 回执必须一致,且每个 Docker push 前再验证;无回执的历史产物不允许上传。文档专用模式不运行无关后端业务测试。
15
- - 测试评审按身份/权限、多租户隔离、CRUD/事务、V8 同步异步与 `return/V8.Result`、存储安全、缓存/任务幂等、升级回滚、应用包幂等、浏览器登录/目标路由、发布脚本失败关闭分类盘点。新增能力补所在分类,不承诺一轮测试覆盖所有未知业务。
16
-
17
- - 吾码后端统一测试入口是 `Microi.Server/Microi.Tests/Microi.Tests.csproj`,
18
- 不得重新创建 `Dos.Common.Tests`、`Dos.ORM.Tests` 等分散入口。
19
- - 日常源码验证运行
20
- `Microi.Server/Microi.Tests/run-tests.ps1 -Mode Quick`。Quick 只做
21
- 单元/组件回归,不连接远端、不写数据库,不能称为“全量生产验收”。
22
- - 发布 API 前运行 `-Mode Full`。默认提供隔离测试租户、专用测试表、
23
- 测试 ApiEngine、测试 Token,并显式设置
24
- `MICROI_TEST_ALLOW_WRITES=YES`。只有用户明确授权时才可对真实租户执行;
25
- 真实租户默认只做登录和只读烟测,写入必须限定到名称/说明明确为自动化
26
- 测试用途的专用表,并使用唯一前缀、`finally` 清理和清理回读。
27
- - Full 至少覆盖完整 Release 构建、FormEngine 单条/批量/按条件 CRUD、
28
- 查询和计数、ApiEngine GET/JSON POST、API 实际启动与健康检查、真实登录、
29
- 匿名系统配置脱敏、清理回读、NuGet 漏洞/弃用审计。NuGet 全面升级后不能
30
- 只看编译;必须捕获程序集 ABI 不一致、旧连接串枚举值失效等启动/运行时问题。
31
- 新增后端公共操作时,同步扩展统一测试入口和 FullStack 闭环。
32
- - 真实账号、密码和 Token 只能来自进程环境变量、CI Secret 或已被 Git 忽略
33
- 的本机配置;不得写入 `Microi.Tests`、README、命令行参数、TRX、覆盖率报告
34
- 或失败消息。测试输出还要验证私有 `appsettings.*.json` 未被复制发布。
35
- - 交付报告必须分别写明:源码检查、项目/解决方案构建、Quick 结果、
36
- FullStack 结果、两节点分布式故障结果。未提供测试环境而未运行 Full,
37
- 必须明确写“未运行”,不能用 Quick 通过代替。
38
- - 即使 Full 通过,涉及定时任务、消息消费、共享缓存、迁移或滚动发布时,
39
- 仍需两个节点连接同一 Redis/数据库,覆盖重复投递、锁持有者退出、
40
- Redis/MongoDB 短暂故障、响应前重启和新旧版本共存。
41
-
42
- ### 登录与账号密码
43
-
44
- - E2E 必须支持提前录入测试账号密码:`PW_TEST_ACCOUNT`、`PW_TEST_PASSWORD`、`PW_LOGIN_ENGINE`。
45
- - 登录优先调用租户登录接口拿 Token,再注入 localStorage/sessionStorage/Cookie。
46
- - 仍需保留 UI 登录兜底,验证真实表单可用。
47
- - 注册成功后应按业务要求自动登录时,必须测试 token 和用户信息已写入本地存储。
48
- - 移动端可支持历史登录账号列表、记住密码、删除本地历史账号,但测试报告不能泄露密码。
49
-
50
- ### 截图与人眼复核
51
-
52
- 每次完整自动化测试都必须截图,不只失败截图。
53
-
54
- 强制截图页面:
55
-
56
- - 首页/工作台
57
- - 登录/注册
58
- - 核心列表页
59
- - 核心详情页
60
- - 提交/支付/审批/确认页面
61
- - 我的/个人中心
62
- - PC 管理端关键菜单
63
- - H5 在 PC 宽屏下的移动端模拟壳
64
-
65
- 每张截图要人工 `view_image` 复核:图片是否真实显示、文字是否看得清、底部菜单是否可见、是否横向溢出、按钮是否被遮挡、状态徽章是否正确。
66
-
67
- ### 网络与接口契约
68
-
69
- - 拦截全部请求,404、5xx、CORS/ORB、图片加载失败、字符串 `null`、空响应、非 JSON 全部失败。
70
- - 页面出现“请求失败”“网络错误”“开发中”“待开发”“null”等文案,默认失败。
71
- - 扫描源码禁止残留 `开发中|待开发`。
72
- - 所有 `callEngine('xxx')` 必须有接口契约测试覆盖:HTTP ok、标准 DosResult、必要字段非空。
73
-
74
- ### 真实业务闭环
75
-
76
- 不能只测页面能打开。至少选择一条客户验收主线跑通:
77
-
78
- 1. 准备测试数据。
79
- 2. 登录。
80
- 3. 执行真实用户动作。
81
- 4. 等待对应接口响应。
82
- 5. 后端查询状态变化。
83
- 6. 前端刷新后状态正确。
84
- 7. 清理测试数据。
85
-
86
- 交易/资产类系统要覆盖:创建资源、上架/提交、支付/上传凭证、审核/确认、状态流转、超时取消、再次流转、记录明细。
87
-
88
- ### 低代码详情页与字段按钮
89
-
90
- 低代码后台模块验收不能只停留在列表页。涉及 `diy_table.Tabs`、字段 `Tab`、`TableChild`、字段级 `Button`、字段 V8Code、菜单按钮 V8Code 的模块,E2E 必须打开至少一条真实详情,逐个切换表单 Tab,并点击详情内字段按钮或关联子表开关。
91
-
92
- - 校验每个可见 Tab 都有可见字段或可见子表内容,不能只检查 `Tabs` JSON 合法。
93
- - 校验字段按钮 V8Code 中引用的字段名真实存在,尤其是历史 `TableChildxxx`、`Textxxx`、`Buttonxxx` 重命名后不能遗留旧引用。
94
- - 字段按钮点击后必须守卫前端错误提示、`pageerror`、控制台 `TypeError/ReferenceError/SyntaxError`,并截图保留展开后的关联子表。
95
- - 详情页测试选择器要限定在当前表格操作列和当前详情弹层内部,避免误点侧边菜单或其它同名按钮。
96
- - `TableChild` 验收必须在父记录 A 新增/编辑/删除多条子记录,再打开父记录 B 验证
97
- 不串数据且不能跨父记录操作;同时回读子表外键、隐藏子菜单和组合索引。
98
- - `JoinForm` 验收必须确认目标表与当前表不同,`JoinFieldName` 的值确实是目标记录 Id,
99
- 并分别覆盖空 Id 与有效 Id 的渲染行为。
100
-
101
- ### 视觉与布局
102
-
103
- - 必须检查横向滚动条。
104
- - 必须检查底部 tabBar / 侧边菜单 / 顶部导航是否可见。
105
- - 必须检查文字对比度,尤其是筛选条件、小标签、退出登录、状态文字、渐变背景上的小字。
106
- - 金额、数量、积分等大数字必须格式化为万、百万、千万、亿等可读形式,不能撑破卡片。
107
- - 移动端 H5 在 PC 浏览器必须自动模拟移动端宽度。
108
-
109
- ### 资源与隐私文件
110
-
111
- - 公开图片走 FileServer/CDN。
112
- - 私有图片必须先通过 `/apiengine/platform-private-file-url` 携带权威资源上下文换取短期签名 URL;签发失败时禁止回退裸路径。
113
- - 上传接口必须通用,不能在平台 HDFS 控制器写某项目“只允许支付凭证或实名认证图片”这类硬编码。
114
- - iOS Safari 上传后要验证表单字段不丢失,上传组件不能重置整张表单。
115
-
116
- ### 商品资料同步
117
-
118
- - 从本地商品资料目录同步到低代码表时,不要只靠标题模糊匹配目录或复用最近一条记录;必须使用显式映射、唯一编码或人工确认后的目录清单。
119
- - 同步前先回读目标表枚举字段、价格字段、主图字段、详情富文本字段和状态字段,确认写入值与平台字段 KeyValue 一致。
120
- - 图片上传遇到 5xx、网关超时或 OSS/HDFS 临时失败必须重试,最终回读 `MainImg`、详情富文本、价格比例、专区/分类、上下架状态,不能只看接口返回成功。
121
- - 缺少主图素材的商品不能默认上架;要补齐素材后再上架,或明确下架,避免移动端出现“商品图”等占位图。
122
- - 商品同步后必须用真实前端列表和详情页截图复核:列表主图真实显示,详情富文本可见,价格比例正确,页面没有横向溢出或占位图。
123
-
124
- ### 交易资产与奖励流水
125
-
126
- - 业务编号、卡号、券码、提货码等展示给用户的短码必须以方案文档/字段说明为准;不要用手机号、日期、ULID 或长前缀自行拼接。若文档要求短随机码,写入主表后必须同步所有历史/订单/奖励等冗余编号字段。
127
- - 奖励记录和真实资产流水要分层:`reward_log` / `commission_log` 可以记录待结算权益,`point_log` / `balance_log` 只能记录已真实影响余额的流水。
128
- - 若业务存在“待入账/已入账”,待入账记录不得写资产流水,不得增加余额;从待入账转已入账时必须同时更新状态、写资产流水、更新余额,并保证幂等,避免重复入账。
129
- - 分佣/返点必须只有一个触发点。若规则定义为“扣服务费时结算”,确认收款、订单完成、后台修复脚本都不得再重复生成同类奖励。
130
- - 层级奖励要先写清楚接收人选择规则:直推、间推、团队/品牌补贴类奖励是否逐层发、是否只给最近达标人、团队人数是否含自己、单笔是否封顶。实现后用至少一条真实链路验证 Pending 和 Settled 两种状态。
131
- - 团队/分润人数统计必须明确资格口径,例如是否只统计已认证、已激活、有效状态用户。若业务规则要求认证门槛,未认证小号不得计入直推、间推、团队总人数、奖励门槛或入账门槛。
132
- - 每次修复资金/资产业务规则后,必须同步更新项目蓝图/方案文档中的触发点、计算公式、字段口径和验收方式,不能只改代码或只在对话里说明。
133
-
134
- <!-- /microi-progressive:chunk -->
135
- <!-- microi-progressive:chunk id=microi-system-delivery-007 sha256=67fa060b6520a80e41818ac0974c0b38ff3171c97a1c558a01667b854865fa7a -->
136
- ## 复盘记录格式
137
-
138
- 每次用户手工测出问题,修复后都要把问题写入对应通用 Skill,格式如下:
139
-
140
- ```md
141
- ### 复盘:问题标题
142
-
143
- - 触发场景:用户如何发现。
144
- - 根因:平台/MCP/插件/前端/业务哪个环节漏了。
145
- - 通用规则:以后所有项目都要怎样避免。
146
- - 自动化检查:哪个测试或截图能提前发现。
147
- ```
148
-
149
- 不要只在本次项目文档或记忆里记录;能通用的经验必须沉淀到 `microi.skills`。如果发现的是 VS Code 插件、MCP、Microi.Client、V8、FormEngine、Playwright 或性能测试的通用坑,必须更新对应 Skill 或新增 Skill,让插件下一次打包后能同步给所有用户。
150
-
151
- ### 复盘:授权文件已生效但插件仍缓存开源版
152
-
153
- - 触发场景:授权管理接口已经返回个人版或企业版,相关插件仍提示开源版;重启服务后也可能因授权文件挂载、写入或数据库恢复晚于插件首次检查而复现。
154
- - 根因:宿主授权接口与功能插件各自持有静态授权状态或各自重新验签;当插件来自旧 NuGet、独立程序集上下文或残留发布文件时,两边即使读取同一文件也可能长期分叉。让插件“自行再验一次”仍然保留了两套事实源,不能根治。
155
- - 通用规则:宿主必须提供唯一的 DI 授权服务,负责缓存刷新、HID、有效期和 RSA 签名验证;所有 Controller、AI、工作流等付费功能只读取这个实例,插件禁止自行缓存或再次创建 `LicenseValidator`。授权验证接口必须返回功能实际读取的 `OnlineFeatureLicensed/ProductType` 与宿主、插件程序集版本。核心插件接口应包含授权状态契约,使旧插件混入新发布包时直接启动/类型加载失败并暴露版本不一致,禁止静默退回开源版。
156
- - 自动化检查:先以无授权状态启动,再写入或挂载有效签名文件,验证统一服务限频刷新后授权接口与真实付费功能同时恢复;替换为旧插件 DLL 时启动必须失败或健康检查明确报版本不兼容,不能出现“Verify=Enterprise、功能=OpenSource”。无效签名、错误 HID、过期文件必须继续拒绝。
157
-
158
- ### 复盘:全局版本已升级但基础应用并未完整安装
159
-
160
- - 触发场景:客户旧库的 `ServerVersion` 已被后续步骤推进,但应用商城、导入器、菜单权限或关键元数据仍缺失;客户服务器不通外网时,重启也无法自愈。
161
- - 根因:升级器把全局版本号当成所有步骤成功的证明,单步失败后仍继续执行并更新版本;基础应用只依赖在线资源,且完整性检查继续走可能已经失真的 FormEngine 元数据。
162
- - 通用规则:后端发布包必须内置可启动的基础应用基线,在线资源只能整组校验成功后作为最新版覆盖,断网或任一资源失败时整组回退;迁移步骤必须失败即停且失败时禁止推进版本。导入器、必要表、菜单和权限等启动前置能力要独立做幂等完整性检查,老库检查以参数化物理表只读查询为准,不能只依赖全局版本或低代码元数据。
163
- - 自动化检查:选择一个版本号偏高但故意缺基础应用的旧库,以禁止外网模式启动,验证后端自动安装基础应用、管理员可见并打开应用商城、插件列表接口可拉取;再次冷启动不得重复导入。再注入任一步骤失败,验证后续步骤不执行且 `ServerVersion` 不前进。
164
-
165
- 流式应用发布等当前运行时入口若会直接查询新增物理字段,其扩展型结构不能只挂在
166
- `ServerVersion` 条件升级链里。必须在后台启动服务的共享分布式升级租约内、入口接流量前
167
- 独立幂等维护,并在版本链之前回读验证;历史版本号漂移或更早无关迁移失败时也要自愈。
168
- 自动化至少构造“版本号已高但发布字段缺失”的旧库并并发启动两个节点,断言只扩展一次、
169
- 没有永久锁,随后流式发布预检和首个文件写入不再出现缺列错误。
170
-
171
- ### 复盘:平台升级覆盖客户菜单的移动端显隐
172
-
173
- - 触发场景:旧租户切换到新版后端并执行自动升级后,移动端工作台整棵菜单消失;顶级 `sys_menu.AppDisplay` 为 `NULL` 或被升级包写成 `0` 时,所有下级菜单即使为 `1` 也无法展示。
174
- - 根因:旧 `UptSysMenu` 部分更新接口读取旧菜单后又丢弃旧实体,重新创建非空 `int` 字段默认为 `0` 的 `SysMenu` 再全字段更新;仅修改排序或父级也会把未传的 `Display/AppDisplay` 清零。历史加列迁移的不可重入多语句 SQL、应用包全量覆盖目标菜单,以及移动端把 `NULL/未配置` 当作隐藏,都会进一步放大影响。
175
- - 通用规则:实体型部分更新必须把非空参数合并到已读取的旧实体,禁止新建实体后全字段更新;新增菜单的 `Display/AppDisplay` 默认均为 `1`。移动端只有明确的 `0/false` 才表示隐藏,`NULL/未配置` 按兼容可见处理;升级开始前先把 `NULL` 按同一行 `Display` 归一,再快照所有既有菜单的 `AppDisplay`,升级结束无论成功失败都要恢复发生变化的旧菜单。应用包只能给新增菜单写包内显隐值,更新既有菜单时必须保留目标库 `Display/AppDisplay`。加列迁移必须按“查列、单条加列、单条回填”幂等执行。
176
- - 自动化检查:先用只含 `Id/Sort/ParentId` 的旧菜单更新请求验证 `Display/AppDisplay` 不变,并验证新增菜单默认双端可见。再构造含 `AppDisplay=NULL/0/1`、顶级和子级菜单的旧库,运行升级并验证空值按 `Display` 归一、既有 `0/1` 原样保留、新增包菜单采用包内值;升级中途失败时快照仍恢复。应用包导入测试必须断言存在 `preserve_existing_menu_visibility_` 保护标记,移动端测试必须覆盖 `undefined/null/0/"0"/false/1` 六种输入。
177
-
178
- ### 复盘:Compose 升级脚本按目录推导 project 后误判旧容器不存在
179
-
180
- - 触发场景:客户历史服务由另一个工作目录或显式 project name 启动;升级脚本虽然拿到现存 `docker-compose.yml`,但执行 `docker compose -p <目录名> ps -q <服务>` 返回空,随后误报旧容器不存在。继续用错误 project 启动还会与旧容器的宿主机端口冲突。
181
- - 根因:把 Compose 文件路径或当前目录推导出的 project name 当成运行态事实源,没有从现有容器的 `com.docker.compose.project` 标签回读真实 project,也没有用宿主机 published port 和 service 标签交叉定位旧容器。
182
- - 通用规则:生产 Compose 升级先按目标 published port、当前 project、`com.docker.compose.service` 三层发现唯一运行容器,并校验服务标签或镜像身份;再读取并复用其 `com.docker.compose.project`。完成原 yml 和旧镜像不可变备份、拉取并校验新镜像后,先检查所有新增服务的宿主机发布端口;端口可顺延时必须设置明确起点、步长和有限重试上限,把最终端口写入实际 Compose 与审计记录,确认可用后才停止旧容器。启动瞬间再次发生端口竞争时,只重试冲突服务;非端口错误立即回滚。再由同一 project 执行 `up --force-recreate`,且不在新镜像就绪和端口预检通过前删除旧容器。后续手工拉取 `latest` 做日常更新时,必须把当前编排、实际 project、发布端口以及 API/前端两个运行镜像 ID 同时备份并打不可变回滚标签;失败时回到本次更新前的两个镜像,禁止误用首次跨版本升级的旧基线。Compose v2 的 `version is obsolete` 只可在命令成功时作为已知非致命告警过滤,其它 stderr 和非零退出码必须保留。
183
- - 自动化检查:模拟当前 project 查询为空、目标宿主机端口仍有旧 API、容器标签带另一个 project 的场景;断言脚本识别旧容器、保存并复用真实 project、在覆盖 yml 前完成备份、拉取校验后执行 stop,并覆盖新增端口连续占用时按上限顺延、重试耗尽时旧服务不停止,以及新服务启动失败后的自动还原。日常更新另测 API/前端双镜像拉取、当前动态端口保持、强制重建成功,以及任一重建/健康检查失败后两个镜像都恢复到本次更新前的 ID。
184
-
185
- ### 复盘:新旧 Compose 双版本并行部署误伤旧服务或产生重叠网络
186
-
187
- - 通用规则:需要保留旧版本并并行安装新版本时,新版必须使用独立 Compose 文件、独立 project 和独立 service 名;旧编排与旧容器在安装路径中只读。新版若必须保持原内网通信,应从旧容器回读并校验实际 Docker 网络,再通过 `external` 网络引用其真实名称,禁止由第二个 project 重复声明同一 IPAM 子网。动态端口必须写回 API 自身公开地址及前端 `ApiBase`;先启动并确认 API,再启动前端。失败清理只能 `down` 新 project,完成后还要回读旧端口对应的容器 ID 和运行状态,确认未被替换。并行项目后续更新必须使用另一份专用命令,固定读取新版 Compose/project/service,保留现场动态端口,备份新版 API/前端两个运行镜像 ID 并打不可变标签;先更新 API、再更新前端,任一步失败时只恢复新版双镜像,禁止复用会读取旧编排的历史日常更新脚本。进程、端口和 project 隔离不代表数据隔离;若新旧后端共用数据库、Redis 或租户,新版迁移、缓存与基础数据变化仍可能影响旧版,交付时必须明确警告并准备数据库级恢复方案。
188
- - 自动化检查:模拟新版起始端口连续占用、新版 API 启动失败和前端健康检查失败;断言旧 yml 字节不变、旧容器未执行 stop/rm/recreate、新版使用独立 project、实际 API 端口同时写入 `AuthServer` 与 `ApiBase`、新版 API 先于前端启动,失败时只清理新 project,并保存端口、网络、镜像 ID 和失败日志。并行日常更新另测动态端口不变、API/前端按序重建、任一服务失败后两个镜像都恢复到本次更新前的 ID,且旧端口容器 ID 始终不变。
189
-
190
- ### 复盘:容器已删除但残留 Compose 文件阻止安全重装
191
-
192
- - 触发场景:用户删除某个独立 Compose project 的全部容器后重新执行一键安装,脚本只因目标 yml 仍存在就报错退出;用户不得不手工删除文件,且容易误删其它编排。
193
- - 根因:安装保护只检查文件存在性,没有区分“仍有运行/停止容器的活跃环境”“容器已清空但本交付 yml 残留”和“身份不明的其它 yml”。
194
- - 通用规则:可重装脚本应先用 `docker ps -a` 按 project 标签检查全部运行及停止容器;只要存在任何容器就拒绝覆盖。容器为零但目标 yml 存在时,必须确认它是普通文件,校验预期 service、镜像和 `docker compose config`,保存 SHA-256 并归档原文件后才允许重新生成;身份不符、符号链接或语法错误一律停止。不得直接 `rm -f` 未确认身份的生产 yml。
195
- - 自动化检查:先安装并留下有效 yml,再模拟容器全部被删除,断言重复安装会归档旧 yml、保存哈希、重新选端口并保持旧项目不变;再模拟仍有停止容器,断言安装拒绝继续且原 yml 字节不变。
196
-
197
- ### 复盘:现场 Compose 文件名或 project 漂移导致专用更新脚本误报不存在
198
-
199
- - 触发场景:运维人员手工调整端口、外网 API 地址或重启脚本后,Compose 文件出现历史拼写变体,或容器被目录默认 project 启动;更新脚本仍硬编码标准文件名和初始 project,先报编排不存在,修正文件名后又可能报找不到容器。
200
- - 根因:把首次安装时的文件名和 project 当成长期不变事实,没有从当前磁盘与运行容器标签回读现场状态。
201
- - 通用规则:更新脚本应优先采用显式参数;未显式指定时可兼容已知历史文件名,但两个候选同时存在必须停止,禁止猜测。Compose 文件负责配置事实,运行容器的 `com.docker.compose.project` 与 `com.docker.compose.service` 标签负责运行态事实;应先按 service 标签唯一定位运行容器,再分别回读真实 project,并用各自 project 执行 `compose ps/port/up`。若 API 与前端历史上分属不同 project,更新和回滚可在服务身份唯一、project 合法且未显式限定 project 的前提下分别原地执行,禁止通过删除、迁移或改名强行合并拓扑。更新只拉镜像与重建,不得为了适配现场漂移而重新生成或覆盖端口、AuthServer、ApiBase 和网络配置。
202
- - 自动化检查:覆盖仅标准文件、仅历史拼写文件、两个文件并存、运行 project 使用安装默认值、运行 project 使用目录默认值、API/前端 project 不一致六类场景;断言兼容分支保留现场 yml 字节和动态端口,分别记录 API/前端 project,并在跨 project 成功与失败回滚路径中都使用各自 project;文件歧义及显式 project 不匹配仍应失败关闭。
203
-
204
- ### 复盘:一键安装脚本仍直接拉取海外镜像或工具二进制
205
-
206
- - 触发场景:国内服务器能够拉取平台自有镜像,但 Docker Hub、GitHub、`dl.min.io` 等海外源超时;某个可选服务镜像或安装后的初始化工具下载失败,导致整套一键安装中途退出。
207
- - 根因:只迁移了 Redis、MySQL 等主要服务镜像,没有把 Compose 中的全部 `image:`、变量镜像和 `curl/wget` 二进制依赖纳入同一份交付清单;辅助 CLI 仍被当作临时下载项,且本机单架构 `docker pull/tag/push` 被误认为已完整复制上游多架构镜像。
208
- - 通用规则:发布一键安装脚本前必须盘点全部容器镜像和运行期下载 URL。海外服务镜像与辅助 CLI 优先按上游固定版本完整复制到平台国内仓库,脚本引用固定版本标签;适合容器化的 CLI 用短生命周期工具容器执行,并把临时配置目录及时清理。迁移时先核对上游 manifest digest 和平台列表,再保留所有受支持架构及 attestation,禁止用仅 `linux/amd64` 的本地推送冒充多架构镜像。
209
- - 自动化检查:静态扫描安装脚本,断言业务 `image:` 不再引用未批准的海外仓库、关键初始化不再依赖海外二进制直链;对国内固定标签执行远端 manifest 回读和真实 `docker pull`,核对 digest、平台和容器内版本;运行完整 `bash -n`,并用隔离临时服务跑通辅助 CLI 的连接、写入和回读闭环,最后确认测试容器、网络、卷均已清理。
210
-
211
- ### 复盘:程序能启动但 Obfuscar 找不到共享框架程序集
212
-
213
- - 触发场景:框架依赖型 `dotnet publish` 的程序冒烟启动正常,但 Obfuscar 处理某个插件 DLL 时报告 `Unable to resolve dependency: Microsoft.Extensions.*`;此前同一脚本可用,插件新增 `BackgroundService`、Hosted Service 或其它共享框架类型后开始失败。
214
- - 根因:ASP.NET Core 运行时从 `Microsoft.AspNetCore.App` / `Microsoft.NETCore.App` 共享框架加载程序集,这些 DLL 默认不复制到 framework-dependent 的发布目录;Obfuscar 是离线元数据处理器,只搜索 `InPath` 时无法解析新增基类。同时,插件直接使用的 NuGet API 若只由其它项目传递带入,项目依赖契约也不完整。
215
- - 通用规则:项目直接使用的包必须在自身 `.csproj` 声明直接 `PackageReference`,但不能把“补 NuGet 引用”误当作 Obfuscar 搜索路径修复。混淆脚本应从发布目录的 `runtimeconfig.json` 读取目标 .NET 主版本,再从 `dotnet --list-runtimes` 动态选择同主版本的最新 `Microsoft.AspNetCore.App` 和 `Microsoft.NETCore.App` 目录,生成绝对路径 `AssemblySearchPath`;禁止硬编码补丁版本,也不要为了混淆把共享框架 DLL 强行复制进最终发布目录。错误提示应保留 Obfuscar 的真实依赖解析错误,不能统一误报“工具未安装”。
216
- - 自动化检查:使用实际 Git Bash 执行脚本语法检查;定向构建插件并检查 nupkg 明确包含直接依赖;对全部受保护 DLL 执行混淆并验证哈希变化;最后必须启动混淆后的发布目录,断言插件注入、平台初始化和 Kestrel 监听成功,且日志不存在 `FileNotFoundException`、`TypeLoadException`、`Unable to resolve dependency` 或 `Could not load file or assembly`。
217
- <!-- /microi-progressive:chunk -->
1
+ # microi-system-delivery 详细参考 2
2
+
3
+ > 按需读取;本文件由 SKILL.md 的原章节无损拆分。
4
+
5
+ <!-- microi-progressive:chunk id=microi-system-delivery-006 sha256=4b999e29e04c192319690a886ba25bb8952d5cc1910db8fa151b583d599b2be5 -->
6
+ ## 自动化测试必须覆盖的坑
7
+
8
+ ### 后端统一测试与发布门禁
9
+
10
+ - 官方或社区独立业务应用、游戏和客户项目在应用自己的 `tests/` 或独立测试工程维护回归,由应用自己的测试及发布入口执行;不得通过直接放文件、转调包装或自动扫描加入平台 Quick/Full。官方商城发布不使业务应用变为平台内置能力。平台 SDK、商城协议、安装器及通用缺陷的最小回归仍由平台负责。
11
+
12
+ - 每个平台新功能或 Bug 修复必须提供对应回归用例;平台 C# 进入 `Microi.Tests`,平台前端与内置资源/V8 测试进入平台 Node 自动发现范围。修复先保留失败证据,再跑成功、边界、异常、权限及旧格式兼容用例;不能仅添加字符串存在断言替代行为测试。
13
+ - `run-node-regressions.mjs` 自动发现 `Microi.Tests`、`OfficialApplications/Resource`、`Microi.Client/tests` 的确定性测试。新文件无法分类即失败;Playwright 用例必须走真实浏览器入口,不能用 Node 执行后把跳过当通过。所有计数需回读,0 用例、失败、取消、skipped、todo 均拒绝发布。
14
+ - 仅推送模式也必须取得发布锁并执行 Full。源码候选哈希、构建上下文哈希与 `release-artifact.mjs` 回执必须一致,且每个 Docker push 前再验证;无回执的历史产物不允许上传。文档专用模式不运行无关后端业务测试。
15
+ - 测试评审按身份/权限、多租户隔离、CRUD/事务、V8 同步异步与 `return/V8.Result`、存储安全、缓存/任务幂等、升级回滚、应用包幂等、浏览器登录/目标路由、发布脚本失败关闭分类盘点。新增能力补所在分类,不承诺一轮测试覆盖所有未知业务。
16
+
17
+ - 吾码后端统一测试入口是 `Microi.Server/Microi.Tests/Microi.Tests.csproj`,
18
+ 不得重新创建 `Dos.Common.Tests`、`Dos.ORM.Tests` 等分散入口。
19
+ - 日常源码验证运行
20
+ `Microi.Server/Microi.Tests/run-tests.ps1 -Mode Quick`。Quick 只做
21
+ 单元/组件回归,不连接远端、不写数据库,不能称为“全量生产验收”。
22
+ - 发布 API 前运行 `-Mode Full`。默认提供隔离测试租户、专用测试表、
23
+ 测试 ApiEngine、测试 Token,并显式设置
24
+ `MICROI_TEST_ALLOW_WRITES=YES`。只有用户明确授权时才可对真实租户执行;
25
+ 真实租户默认只做登录和只读烟测,写入必须限定到名称/说明明确为自动化
26
+ 测试用途的专用表,并使用唯一前缀、`finally` 清理和清理回读。
27
+ - Full 至少覆盖完整 Release 构建、FormEngine 单条/批量/按条件 CRUD、
28
+ 查询和计数、ApiEngine GET/JSON POST、API 实际启动与健康检查、真实登录、
29
+ 匿名系统配置脱敏、清理回读、NuGet 漏洞/弃用审计。NuGet 全面升级后不能
30
+ 只看编译;必须捕获程序集 ABI 不一致、旧连接串枚举值失效等启动/运行时问题。
31
+ 新增后端公共操作时,同步扩展统一测试入口和 FullStack 闭环。
32
+ - 真实账号、密码和 Token 只能来自进程环境变量、CI Secret 或已被 Git 忽略
33
+ 的本机配置;不得写入 `Microi.Tests`、README、命令行参数、TRX、覆盖率报告
34
+ 或失败消息。测试输出还要验证私有 `appsettings.*.json` 未被复制发布。
35
+ - 交付报告必须分别写明:源码检查、项目/解决方案构建、Quick 结果、
36
+ FullStack 结果、两节点分布式故障结果。未提供测试环境而未运行 Full,
37
+ 必须明确写“未运行”,不能用 Quick 通过代替。
38
+ - 即使 Full 通过,涉及定时任务、消息消费、共享缓存、迁移或滚动发布时,
39
+ 仍需两个节点连接同一 Redis/数据库,覆盖重复投递、锁持有者退出、
40
+ Redis/MongoDB 短暂故障、响应前重启和新旧版本共存。
41
+
42
+ ### 登录与账号密码
43
+
44
+ - E2E 必须支持提前录入测试账号密码:`PW_TEST_ACCOUNT`、`PW_TEST_PASSWORD`、`PW_LOGIN_ENGINE`。
45
+ - 登录优先调用租户登录接口拿 Token,再注入 localStorage/sessionStorage/Cookie。
46
+ - 仍需保留 UI 登录兜底,验证真实表单可用。
47
+ - 注册成功后应按业务要求自动登录时,必须测试 token 和用户信息已写入本地存储。
48
+ - 移动端可支持历史登录账号列表、记住密码、删除本地历史账号,但测试报告不能泄露密码。
49
+
50
+ ### 截图与人眼复核
51
+
52
+ 每次完整自动化测试都必须截图,不只失败截图。
53
+
54
+ 强制截图页面:
55
+
56
+ - 首页/工作台
57
+ - 登录/注册
58
+ - 核心列表页
59
+ - 核心详情页
60
+ - 提交/支付/审批/确认页面
61
+ - 我的/个人中心
62
+ - PC 管理端关键菜单
63
+ - H5 在 PC 宽屏下的移动端模拟壳
64
+
65
+ 每张截图要人工 `view_image` 复核:图片是否真实显示、文字是否看得清、底部菜单是否可见、是否横向溢出、按钮是否被遮挡、状态徽章是否正确。
66
+
67
+ ### 网络与接口契约
68
+
69
+ - 拦截全部请求,404、5xx、CORS/ORB、图片加载失败、字符串 `null`、空响应、非 JSON 全部失败。
70
+ - 页面出现“请求失败”“网络错误”“开发中”“待开发”“null”等文案,默认失败。
71
+ - 扫描源码禁止残留 `开发中|待开发`。
72
+ - 所有 `callEngine('xxx')` 必须有接口契约测试覆盖:HTTP ok、标准 DosResult、必要字段非空。
73
+
74
+ ### 真实业务闭环
75
+
76
+ 不能只测页面能打开。至少选择一条客户验收主线跑通:
77
+
78
+ 1. 准备测试数据。
79
+ 2. 登录。
80
+ 3. 执行真实用户动作。
81
+ 4. 等待对应接口响应。
82
+ 5. 后端查询状态变化。
83
+ 6. 前端刷新后状态正确。
84
+ 7. 清理测试数据。
85
+
86
+ 交易/资产类系统要覆盖:创建资源、上架/提交、支付/上传凭证、审核/确认、状态流转、超时取消、再次流转、记录明细。
87
+
88
+ ### 低代码详情页与字段按钮
89
+
90
+ 低代码后台模块验收不能只停留在列表页。涉及 `diy_table.Tabs`、字段 `Tab`、`TableChild`、字段级 `Button`、字段 V8Code、菜单按钮 V8Code 的模块,E2E 必须打开至少一条真实详情,逐个切换表单 Tab,并点击详情内字段按钮或关联子表开关。
91
+
92
+ - 校验每个可见 Tab 都有可见字段或可见子表内容,不能只检查 `Tabs` JSON 合法。
93
+ - 校验字段按钮 V8Code 中引用的字段名真实存在,尤其是历史 `TableChildxxx`、`Textxxx`、`Buttonxxx` 重命名后不能遗留旧引用。
94
+ - 字段按钮点击后必须守卫前端错误提示、`pageerror`、控制台 `TypeError/ReferenceError/SyntaxError`,并截图保留展开后的关联子表。
95
+ - 详情页测试选择器要限定在当前表格操作列和当前详情弹层内部,避免误点侧边菜单或其它同名按钮。
96
+ - `TableChild` 验收必须在父记录 A 新增/编辑/删除多条子记录,再打开父记录 B 验证
97
+ 不串数据且不能跨父记录操作;同时回读子表外键、隐藏子菜单和组合索引。
98
+ - `JoinForm` 验收必须确认目标表与当前表不同,`JoinFieldName` 的值确实是目标记录 Id,
99
+ 并分别覆盖空 Id 与有效 Id 的渲染行为。
100
+
101
+ ### 视觉与布局
102
+
103
+ - 必须检查横向滚动条。
104
+ - 必须检查底部 tabBar / 侧边菜单 / 顶部导航是否可见。
105
+ - 必须检查文字对比度,尤其是筛选条件、小标签、退出登录、状态文字、渐变背景上的小字。
106
+ - 金额、数量、积分等大数字必须格式化为万、百万、千万、亿等可读形式,不能撑破卡片。
107
+ - 移动端 H5 在 PC 浏览器必须自动模拟移动端宽度。
108
+
109
+ ### 资源与隐私文件
110
+
111
+ - 公开图片走 FileServer/CDN。
112
+ - 私有图片必须先通过 `/apiengine/platform-private-file-url` 携带权威资源上下文换取短期签名 URL;签发失败时禁止回退裸路径。
113
+ - 上传接口必须通用,不能在平台 HDFS 控制器写某项目“只允许支付凭证或实名认证图片”这类硬编码。
114
+ - iOS Safari 上传后要验证表单字段不丢失,上传组件不能重置整张表单。
115
+
116
+ ### 商品资料同步
117
+
118
+ - 从本地商品资料目录同步到低代码表时,不要只靠标题模糊匹配目录或复用最近一条记录;必须使用显式映射、唯一编码或人工确认后的目录清单。
119
+ - 同步前先回读目标表枚举字段、价格字段、主图字段、详情富文本字段和状态字段,确认写入值与平台字段 KeyValue 一致。
120
+ - 图片上传遇到 5xx、网关超时或 OSS/HDFS 临时失败必须重试,最终回读 `MainImg`、详情富文本、价格比例、专区/分类、上下架状态,不能只看接口返回成功。
121
+ - 缺少主图素材的商品不能默认上架;要补齐素材后再上架,或明确下架,避免移动端出现“商品图”等占位图。
122
+ - 商品同步后必须用真实前端列表和详情页截图复核:列表主图真实显示,详情富文本可见,价格比例正确,页面没有横向溢出或占位图。
123
+
124
+ ### 交易资产与奖励流水
125
+
126
+ - 业务编号、卡号、券码、提货码等展示给用户的短码必须以方案文档/字段说明为准;不要用手机号、日期、ULID 或长前缀自行拼接。若文档要求短随机码,写入主表后必须同步所有历史/订单/奖励等冗余编号字段。
127
+ - 奖励记录和真实资产流水要分层:`reward_log` / `commission_log` 可以记录待结算权益,`point_log` / `balance_log` 只能记录已真实影响余额的流水。
128
+ - 若业务存在“待入账/已入账”,待入账记录不得写资产流水,不得增加余额;从待入账转已入账时必须同时更新状态、写资产流水、更新余额,并保证幂等,避免重复入账。
129
+ - 分佣/返点必须只有一个触发点。若规则定义为“扣服务费时结算”,确认收款、订单完成、后台修复脚本都不得再重复生成同类奖励。
130
+ - 层级奖励要先写清楚接收人选择规则:直推、间推、团队/品牌补贴类奖励是否逐层发、是否只给最近达标人、团队人数是否含自己、单笔是否封顶。实现后用至少一条真实链路验证 Pending 和 Settled 两种状态。
131
+ - 团队/分润人数统计必须明确资格口径,例如是否只统计已认证、已激活、有效状态用户。若业务规则要求认证门槛,未认证小号不得计入直推、间推、团队总人数、奖励门槛或入账门槛。
132
+ - 每次修复资金/资产业务规则后,必须同步更新项目蓝图/方案文档中的触发点、计算公式、字段口径和验收方式,不能只改代码或只在对话里说明。
133
+
134
+ <!-- /microi-progressive:chunk -->
135
+ <!-- microi-progressive:chunk id=microi-system-delivery-007 sha256=67fa060b6520a80e41818ac0974c0b38ff3171c97a1c558a01667b854865fa7a -->
136
+ ## 复盘记录格式
137
+
138
+ 每次用户手工测出问题,修复后都要把问题写入对应通用 Skill,格式如下:
139
+
140
+ ```md
141
+ ### 复盘:问题标题
142
+
143
+ - 触发场景:用户如何发现。
144
+ - 根因:平台/MCP/插件/前端/业务哪个环节漏了。
145
+ - 通用规则:以后所有项目都要怎样避免。
146
+ - 自动化检查:哪个测试或截图能提前发现。
147
+ ```
148
+
149
+ 不要只在本次项目文档或记忆里记录;能通用的经验必须沉淀到 `microi.skills`。如果发现的是 VS Code 插件、MCP、Microi.Client、V8、FormEngine、Playwright 或性能测试的通用坑,必须更新对应 Skill 或新增 Skill,让插件下一次打包后能同步给所有用户。
150
+
151
+ ### 复盘:授权文件已生效但插件仍缓存开源版
152
+
153
+ - 触发场景:授权管理接口已经返回个人版或企业版,相关插件仍提示开源版;重启服务后也可能因授权文件挂载、写入或数据库恢复晚于插件首次检查而复现。
154
+ - 根因:宿主授权接口与功能插件各自持有静态授权状态或各自重新验签;当插件来自旧 NuGet、独立程序集上下文或残留发布文件时,两边即使读取同一文件也可能长期分叉。让插件“自行再验一次”仍然保留了两套事实源,不能根治。
155
+ - 通用规则:宿主必须提供唯一的 DI 授权服务,负责缓存刷新、HID、有效期和 RSA 签名验证;所有 Controller、AI、工作流等付费功能只读取这个实例,插件禁止自行缓存或再次创建 `LicenseValidator`。授权验证接口必须返回功能实际读取的 `OnlineFeatureLicensed/ProductType` 与宿主、插件程序集版本。核心插件接口应包含授权状态契约,使旧插件混入新发布包时直接启动/类型加载失败并暴露版本不一致,禁止静默退回开源版。
156
+ - 自动化检查:先以无授权状态启动,再写入或挂载有效签名文件,验证统一服务限频刷新后授权接口与真实付费功能同时恢复;替换为旧插件 DLL 时启动必须失败或健康检查明确报版本不兼容,不能出现“Verify=Enterprise、功能=OpenSource”。无效签名、错误 HID、过期文件必须继续拒绝。
157
+
158
+ ### 复盘:全局版本已升级但基础应用并未完整安装
159
+
160
+ - 触发场景:客户旧库的 `ServerVersion` 已被后续步骤推进,但应用商城、导入器、菜单权限或关键元数据仍缺失;客户服务器不通外网时,重启也无法自愈。
161
+ - 根因:升级器把全局版本号当成所有步骤成功的证明,单步失败后仍继续执行并更新版本;基础应用只依赖在线资源,且完整性检查继续走可能已经失真的 FormEngine 元数据。
162
+ - 通用规则:后端发布包必须内置可启动的基础应用基线,在线资源只能整组校验成功后作为最新版覆盖,断网或任一资源失败时整组回退;迁移步骤必须失败即停且失败时禁止推进版本。导入器、必要表、菜单和权限等启动前置能力要独立做幂等完整性检查,老库检查以参数化物理表只读查询为准,不能只依赖全局版本或低代码元数据。
163
+ - 自动化检查:选择一个版本号偏高但故意缺基础应用的旧库,以禁止外网模式启动,验证后端自动安装基础应用、管理员可见并打开应用商城、插件列表接口可拉取;再次冷启动不得重复导入。再注入任一步骤失败,验证后续步骤不执行且 `ServerVersion` 不前进。
164
+
165
+ 流式应用发布等当前运行时入口若会直接查询新增物理字段,其扩展型结构不能只挂在
166
+ `ServerVersion` 条件升级链里。必须在后台启动服务的共享分布式升级租约内、入口接流量前
167
+ 独立幂等维护,并在版本链之前回读验证;历史版本号漂移或更早无关迁移失败时也要自愈。
168
+ 自动化至少构造“版本号已高但发布字段缺失”的旧库并并发启动两个节点,断言只扩展一次、
169
+ 没有永久锁,随后流式发布预检和首个文件写入不再出现缺列错误。
170
+
171
+ ### 复盘:平台升级覆盖客户菜单的移动端显隐
172
+
173
+ - 触发场景:旧租户切换到新版后端并执行自动升级后,移动端工作台整棵菜单消失;顶级 `sys_menu.AppDisplay` 为 `NULL` 或被升级包写成 `0` 时,所有下级菜单即使为 `1` 也无法展示。
174
+ - 根因:旧 `UptSysMenu` 部分更新接口读取旧菜单后又丢弃旧实体,重新创建非空 `int` 字段默认为 `0` 的 `SysMenu` 再全字段更新;仅修改排序或父级也会把未传的 `Display/AppDisplay` 清零。历史加列迁移的不可重入多语句 SQL、应用包全量覆盖目标菜单,以及移动端把 `NULL/未配置` 当作隐藏,都会进一步放大影响。
175
+ - 通用规则:实体型部分更新必须把非空参数合并到已读取的旧实体,禁止新建实体后全字段更新;新增菜单的 `Display/AppDisplay` 默认均为 `1`。移动端只有明确的 `0/false` 才表示隐藏,`NULL/未配置` 按兼容可见处理;升级开始前先把 `NULL` 按同一行 `Display` 归一,再快照所有既有菜单的 `AppDisplay`,升级结束无论成功失败都要恢复发生变化的旧菜单。应用包只能给新增菜单写包内显隐值,更新既有菜单时必须保留目标库 `Display/AppDisplay`。加列迁移必须按“查列、单条加列、单条回填”幂等执行。
176
+ - 自动化检查:先用只含 `Id/Sort/ParentId` 的旧菜单更新请求验证 `Display/AppDisplay` 不变,并验证新增菜单默认双端可见。再构造含 `AppDisplay=NULL/0/1`、顶级和子级菜单的旧库,运行升级并验证空值按 `Display` 归一、既有 `0/1` 原样保留、新增包菜单采用包内值;升级中途失败时快照仍恢复。应用包导入测试必须断言存在 `preserve_existing_menu_visibility_` 保护标记,移动端测试必须覆盖 `undefined/null/0/"0"/false/1` 六种输入。
177
+
178
+ ### 复盘:Compose 升级脚本按目录推导 project 后误判旧容器不存在
179
+
180
+ - 触发场景:客户历史服务由另一个工作目录或显式 project name 启动;升级脚本虽然拿到现存 `docker-compose.yml`,但执行 `docker compose -p <目录名> ps -q <服务>` 返回空,随后误报旧容器不存在。继续用错误 project 启动还会与旧容器的宿主机端口冲突。
181
+ - 根因:把 Compose 文件路径或当前目录推导出的 project name 当成运行态事实源,没有从现有容器的 `com.docker.compose.project` 标签回读真实 project,也没有用宿主机 published port 和 service 标签交叉定位旧容器。
182
+ - 通用规则:生产 Compose 升级先按目标 published port、当前 project、`com.docker.compose.service` 三层发现唯一运行容器,并校验服务标签或镜像身份;再读取并复用其 `com.docker.compose.project`。完成原 yml 和旧镜像不可变备份、拉取并校验新镜像后,先检查所有新增服务的宿主机发布端口;端口可顺延时必须设置明确起点、步长和有限重试上限,把最终端口写入实际 Compose 与审计记录,确认可用后才停止旧容器。启动瞬间再次发生端口竞争时,只重试冲突服务;非端口错误立即回滚。再由同一 project 执行 `up --force-recreate`,且不在新镜像就绪和端口预检通过前删除旧容器。后续手工拉取 `latest` 做日常更新时,必须把当前编排、实际 project、发布端口以及 API/前端两个运行镜像 ID 同时备份并打不可变回滚标签;失败时回到本次更新前的两个镜像,禁止误用首次跨版本升级的旧基线。Compose v2 的 `version is obsolete` 只可在命令成功时作为已知非致命告警过滤,其它 stderr 和非零退出码必须保留。
183
+ - 自动化检查:模拟当前 project 查询为空、目标宿主机端口仍有旧 API、容器标签带另一个 project 的场景;断言脚本识别旧容器、保存并复用真实 project、在覆盖 yml 前完成备份、拉取校验后执行 stop,并覆盖新增端口连续占用时按上限顺延、重试耗尽时旧服务不停止,以及新服务启动失败后的自动还原。日常更新另测 API/前端双镜像拉取、当前动态端口保持、强制重建成功,以及任一重建/健康检查失败后两个镜像都恢复到本次更新前的 ID。
184
+
185
+ ### 复盘:新旧 Compose 双版本并行部署误伤旧服务或产生重叠网络
186
+
187
+ - 通用规则:需要保留旧版本并并行安装新版本时,新版必须使用独立 Compose 文件、独立 project 和独立 service 名;旧编排与旧容器在安装路径中只读。新版若必须保持原内网通信,应从旧容器回读并校验实际 Docker 网络,再通过 `external` 网络引用其真实名称,禁止由第二个 project 重复声明同一 IPAM 子网。动态端口必须写回 API 自身公开地址及前端 `ApiBase`;先启动并确认 API,再启动前端。失败清理只能 `down` 新 project,完成后还要回读旧端口对应的容器 ID 和运行状态,确认未被替换。并行项目后续更新必须使用另一份专用命令,固定读取新版 Compose/project/service,保留现场动态端口,备份新版 API/前端两个运行镜像 ID 并打不可变标签;先更新 API、再更新前端,任一步失败时只恢复新版双镜像,禁止复用会读取旧编排的历史日常更新脚本。进程、端口和 project 隔离不代表数据隔离;若新旧后端共用数据库、Redis 或租户,新版迁移、缓存与基础数据变化仍可能影响旧版,交付时必须明确警告并准备数据库级恢复方案。
188
+ - 自动化检查:模拟新版起始端口连续占用、新版 API 启动失败和前端健康检查失败;断言旧 yml 字节不变、旧容器未执行 stop/rm/recreate、新版使用独立 project、实际 API 端口同时写入 `AuthServer` 与 `ApiBase`、新版 API 先于前端启动,失败时只清理新 project,并保存端口、网络、镜像 ID 和失败日志。并行日常更新另测动态端口不变、API/前端按序重建、任一服务失败后两个镜像都恢复到本次更新前的 ID,且旧端口容器 ID 始终不变。
189
+
190
+ ### 复盘:容器已删除但残留 Compose 文件阻止安全重装
191
+
192
+ - 触发场景:用户删除某个独立 Compose project 的全部容器后重新执行一键安装,脚本只因目标 yml 仍存在就报错退出;用户不得不手工删除文件,且容易误删其它编排。
193
+ - 根因:安装保护只检查文件存在性,没有区分“仍有运行/停止容器的活跃环境”“容器已清空但本交付 yml 残留”和“身份不明的其它 yml”。
194
+ - 通用规则:可重装脚本应先用 `docker ps -a` 按 project 标签检查全部运行及停止容器;只要存在任何容器就拒绝覆盖。容器为零但目标 yml 存在时,必须确认它是普通文件,校验预期 service、镜像和 `docker compose config`,保存 SHA-256 并归档原文件后才允许重新生成;身份不符、符号链接或语法错误一律停止。不得直接 `rm -f` 未确认身份的生产 yml。
195
+ - 自动化检查:先安装并留下有效 yml,再模拟容器全部被删除,断言重复安装会归档旧 yml、保存哈希、重新选端口并保持旧项目不变;再模拟仍有停止容器,断言安装拒绝继续且原 yml 字节不变。
196
+
197
+ ### 复盘:现场 Compose 文件名或 project 漂移导致专用更新脚本误报不存在
198
+
199
+ - 触发场景:运维人员手工调整端口、外网 API 地址或重启脚本后,Compose 文件出现历史拼写变体,或容器被目录默认 project 启动;更新脚本仍硬编码标准文件名和初始 project,先报编排不存在,修正文件名后又可能报找不到容器。
200
+ - 根因:把首次安装时的文件名和 project 当成长期不变事实,没有从当前磁盘与运行容器标签回读现场状态。
201
+ - 通用规则:更新脚本应优先采用显式参数;未显式指定时可兼容已知历史文件名,但两个候选同时存在必须停止,禁止猜测。Compose 文件负责配置事实,运行容器的 `com.docker.compose.project` 与 `com.docker.compose.service` 标签负责运行态事实;应先按 service 标签唯一定位运行容器,再分别回读真实 project,并用各自 project 执行 `compose ps/port/up`。若 API 与前端历史上分属不同 project,更新和回滚可在服务身份唯一、project 合法且未显式限定 project 的前提下分别原地执行,禁止通过删除、迁移或改名强行合并拓扑。更新只拉镜像与重建,不得为了适配现场漂移而重新生成或覆盖端口、AuthServer、ApiBase 和网络配置。
202
+ - 自动化检查:覆盖仅标准文件、仅历史拼写文件、两个文件并存、运行 project 使用安装默认值、运行 project 使用目录默认值、API/前端 project 不一致六类场景;断言兼容分支保留现场 yml 字节和动态端口,分别记录 API/前端 project,并在跨 project 成功与失败回滚路径中都使用各自 project;文件歧义及显式 project 不匹配仍应失败关闭。
203
+
204
+ ### 复盘:一键安装脚本仍直接拉取海外镜像或工具二进制
205
+
206
+ - 触发场景:国内服务器能够拉取平台自有镜像,但 Docker Hub、GitHub、`dl.min.io` 等海外源超时;某个可选服务镜像或安装后的初始化工具下载失败,导致整套一键安装中途退出。
207
+ - 根因:只迁移了 Redis、MySQL 等主要服务镜像,没有把 Compose 中的全部 `image:`、变量镜像和 `curl/wget` 二进制依赖纳入同一份交付清单;辅助 CLI 仍被当作临时下载项,且本机单架构 `docker pull/tag/push` 被误认为已完整复制上游多架构镜像。
208
+ - 通用规则:发布一键安装脚本前必须盘点全部容器镜像和运行期下载 URL。海外服务镜像与辅助 CLI 优先按上游固定版本完整复制到平台国内仓库,脚本引用固定版本标签;适合容器化的 CLI 用短生命周期工具容器执行,并把临时配置目录及时清理。迁移时先核对上游 manifest digest 和平台列表,再保留所有受支持架构及 attestation,禁止用仅 `linux/amd64` 的本地推送冒充多架构镜像。
209
+ - 自动化检查:静态扫描安装脚本,断言业务 `image:` 不再引用未批准的海外仓库、关键初始化不再依赖海外二进制直链;对国内固定标签执行远端 manifest 回读和真实 `docker pull`,核对 digest、平台和容器内版本;运行完整 `bash -n`,并用隔离临时服务跑通辅助 CLI 的连接、写入和回读闭环,最后确认测试容器、网络、卷均已清理。
210
+
211
+ ### 复盘:程序能启动但 Obfuscar 找不到共享框架程序集
212
+
213
+ - 触发场景:框架依赖型 `dotnet publish` 的程序冒烟启动正常,但 Obfuscar 处理某个插件 DLL 时报告 `Unable to resolve dependency: Microsoft.Extensions.*`;此前同一脚本可用,插件新增 `BackgroundService`、Hosted Service 或其它共享框架类型后开始失败。
214
+ - 根因:ASP.NET Core 运行时从 `Microsoft.AspNetCore.App` / `Microsoft.NETCore.App` 共享框架加载程序集,这些 DLL 默认不复制到 framework-dependent 的发布目录;Obfuscar 是离线元数据处理器,只搜索 `InPath` 时无法解析新增基类。同时,插件直接使用的 NuGet API 若只由其它项目传递带入,项目依赖契约也不完整。
215
+ - 通用规则:项目直接使用的包必须在自身 `.csproj` 声明直接 `PackageReference`,但不能把“补 NuGet 引用”误当作 Obfuscar 搜索路径修复。混淆脚本应从发布目录的 `runtimeconfig.json` 读取目标 .NET 主版本,再从 `dotnet --list-runtimes` 动态选择同主版本的最新 `Microsoft.AspNetCore.App` 和 `Microsoft.NETCore.App` 目录,生成绝对路径 `AssemblySearchPath`;禁止硬编码补丁版本,也不要为了混淆把共享框架 DLL 强行复制进最终发布目录。错误提示应保留 Obfuscar 的真实依赖解析错误,不能统一误报“工具未安装”。
216
+ - 自动化检查:使用实际 Git Bash 执行脚本语法检查;定向构建插件并检查 nupkg 明确包含直接依赖;对全部受保护 DLL 执行混淆并验证哈希变化;最后必须启动混淆后的发布目录,断言插件注入、平台初始化和 Kestrel 监听成功,且日志不存在 `FileNotFoundException`、`TypeLoadException`、`Unable to resolve dependency` 或 `Could not load file or assembly`。
217
+ <!-- /microi-progressive:chunk -->