@microi.net/cli 4.6.2

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 (112) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +66 -0
  3. package/dist/mcp-codex-stdio-adapter.js +189 -0
  4. package/dist/mcp-server.js +972 -0
  5. package/dist/mcp-trae-windows-launcher.cmd +21 -0
  6. package/dist/microi-cli-mcp.js +7 -0
  7. package/dist/microi-cli.js +1645 -0
  8. package/dist/microi-skills.meta.json +335 -0
  9. package/dist/microi.skills/.microi-skills-version.json +6 -0
  10. package/dist/microi.skills/README.md +276 -0
  11. package/dist/microi.skills/ai-engine/SKILL.md +140 -0
  12. package/dist/microi.skills/ai-engine/agents/openai.yaml +4 -0
  13. package/dist/microi.skills/app-store/SKILL.md +105 -0
  14. package/dist/microi.skills/app-store/agents/openai.yaml +4 -0
  15. package/dist/microi.skills/business-blueprint/SKILL.md +184 -0
  16. package/dist/microi.skills/datasource-engine/SKILL.md +89 -0
  17. package/dist/microi.skills/datasource-engine/agents/openai.yaml +4 -0
  18. package/dist/microi.skills/dos-orm/SKILL.md +76 -0
  19. package/dist/microi.skills/dos-orm/references/api-reference.md +229 -0
  20. package/dist/microi.skills/job-engine/SKILL.md +141 -0
  21. package/dist/microi.skills/job-engine/agents/openai.yaml +4 -0
  22. package/dist/microi.skills/message-notification/SKILL.md +113 -0
  23. package/dist/microi.skills/message-notification/agents/openai.yaml +6 -0
  24. package/dist/microi.skills/message-notification/references/contracts.md +99 -0
  25. package/dist/microi.skills/microi-ai-app-auth.js +651 -0
  26. package/dist/microi.skills/microi-ai-application/SKILL.md +80 -0
  27. package/dist/microi.skills/microi-ai-application/agents/openai.yaml +4 -0
  28. package/dist/microi.skills/microi-ai-application/references/frontend-baseline.md +164 -0
  29. package/dist/microi.skills/microi-client-frontend/SKILL.md +562 -0
  30. package/dist/microi.skills/microi-datasource-mapping/SKILL.md +108 -0
  31. package/dist/microi.skills/microi-db-schema/SKILL.md +170 -0
  32. package/dist/microi.skills/microi-db-schema/agents/openai.yaml +4 -0
  33. package/dist/microi.skills/microi-db-schema/references/core-tables.md +695 -0
  34. package/dist/microi.skills/microi-db-schema/references/form-component-options.md +256 -0
  35. package/dist/microi.skills/microi-db-schema/references/schema-overview.md +203 -0
  36. package/dist/microi.skills/microi-db-schema/references/schema.md +647 -0
  37. package/dist/microi.skills/microi-db-schema/references/table-catalog.md +1607 -0
  38. package/dist/microi.skills/microi-deployment/SKILL.md +117 -0
  39. package/dist/microi.skills/microi-deployment/references/deployment-matrix.md +94 -0
  40. package/dist/microi.skills/microi-docs-coverage/SKILL.md +91 -0
  41. package/dist/microi.skills/microi-docs-coverage/references/capability-map.md +65 -0
  42. package/dist/microi.skills/microi-docs-coverage/scripts/audit-doc-skill-coverage.mjs +887 -0
  43. package/dist/microi.skills/microi-form-engine/SKILL.md +159 -0
  44. package/dist/microi.skills/microi-form-engine/references/component-catalog.md +116 -0
  45. package/dist/microi.skills/microi-form-engine/references/data-source-events.md +117 -0
  46. package/dist/microi.skills/microi-form-layout/SKILL.md +373 -0
  47. package/dist/microi.skills/microi-frontend-sdk/SKILL.md +304 -0
  48. package/dist/microi.skills/microi-left-right-layout/SKILL.md +132 -0
  49. package/dist/microi.skills/microi-microservice/SKILL.md +115 -0
  50. package/dist/microi.skills/microi-microservice/references/runtime-delivery.md +145 -0
  51. package/dist/microi.skills/microi-mobile-app-quality/SKILL.md +436 -0
  52. package/dist/microi.skills/microi-solution-quotation/SKILL.md +76 -0
  53. package/dist/microi.skills/microi-solution-quotation/agents/openai.yaml +4 -0
  54. package/dist/microi.skills/microi-solution-quotation/scripts/build_solution_quote.py +296 -0
  55. package/dist/microi.skills/microi-system-delivery/SKILL.md +446 -0
  56. package/dist/microi.skills/microi-ui/SKILL.md +321 -0
  57. package/dist/microi.skills/microi-uniapp-frontend/SKILL.md +483 -0
  58. package/dist/microi.skills/microi.v8.js +1758 -0
  59. package/dist/microi.skills/module-engine/SKILL.md +131 -0
  60. package/dist/microi.skills/module-engine/references/module-config.md +174 -0
  61. package/dist/microi.skills/page-engine/SKILL.md +397 -0
  62. package/dist/microi.skills/performance-testing/SKILL.md +207 -0
  63. package/dist/microi.skills/playwright-e2e/SKILL.md +769 -0
  64. package/dist/microi.skills/print-engine/SKILL.md +237 -0
  65. package/dist/microi.skills/production-readonly-audit/SKILL.md +39 -0
  66. package/dist/microi.skills/report-engine/SKILL.md +69 -0
  67. package/dist/microi.skills/report-engine/agents/openai.yaml +4 -0
  68. package/dist/microi.skills/search-engine/SKILL.md +73 -0
  69. package/dist/microi.skills/search-engine/agents/openai.yaml +4 -0
  70. package/dist/microi.skills/spider-engine/SKILL.md +188 -0
  71. package/dist/microi.skills/translate-engine/SKILL.md +91 -0
  72. package/dist/microi.skills/translate-engine/agents/openai.yaml +4 -0
  73. package/dist/microi.skills/ui-design/SKILL.md +1575 -0
  74. package/dist/microi.skills/ui-design/assets/pattern-showcase/app.js +54 -0
  75. package/dist/microi.skills/ui-design/assets/pattern-showcase/index.html +163 -0
  76. package/dist/microi.skills/ui-design/assets/pattern-showcase/styles.css +311 -0
  77. package/dist/microi.skills/ui-design/assets/templates/MCI-DESIGN.md +98 -0
  78. package/dist/microi.skills/ui-design/references/design-pattern-library.md +171 -0
  79. package/dist/microi.skills/ui-design/references/mci-design-contract.md +84 -0
  80. package/dist/microi.skills/ui-design/references/motion-and-media.md +71 -0
  81. package/dist/microi.skills/ui-design/references/product-flow-recipes.md +94 -0
  82. package/dist/microi.skills/uniapp-mall-assets/SKILL.md +105 -0
  83. package/dist/microi.skills/v8-api-config/SKILL.md +272 -0
  84. package/dist/microi.skills/v8-cache-pattern/SKILL.md +286 -0
  85. package/dist/microi.skills/v8-crud-api/SKILL.md +398 -0
  86. package/dist/microi.skills/v8-debugging/SKILL.md +279 -0
  87. package/dist/microi.skills/v8-explorer-tree/SKILL.md +224 -0
  88. package/dist/microi.skills/v8-export-import/SKILL.md +590 -0
  89. package/dist/microi.skills/v8-file-upload/SKILL.md +497 -0
  90. package/dist/microi.skills/v8-formengine-http/SKILL.md +218 -0
  91. package/dist/microi.skills/v8-frontend-events/SKILL.md +349 -0
  92. package/dist/microi.skills/v8-frontend-events/references/bluetooth-print-api.md +107 -0
  93. package/dist/microi.skills/v8-frontend-events/references/bluetooth-print.md +185 -0
  94. package/dist/microi.skills/v8-http-integration/SKILL.md +379 -0
  95. package/dist/microi.skills/v8-image-processing/SKILL.md +187 -0
  96. package/dist/microi.skills/v8-image-processing/agents/openai.yaml +4 -0
  97. package/dist/microi.skills/v8-image-processing/references/api-reference.md +620 -0
  98. package/dist/microi.skills/v8-menu-buttons/SKILL.md +661 -0
  99. package/dist/microi.skills/v8-mongodb/SKILL.md +149 -0
  100. package/dist/microi.skills/v8-mq-mqtt/SKILL.md +227 -0
  101. package/dist/microi.skills/v8-saas-multi-tenant/SKILL.md +193 -0
  102. package/dist/microi.skills/v8-security/SKILL.md +417 -0
  103. package/dist/microi.skills/v8-sql-query/SKILL.md +290 -0
  104. package/dist/microi.skills/v8-table-event/SKILL.md +385 -0
  105. package/dist/microi.skills/v8-template-engine/SKILL.md +165 -0
  106. package/dist/microi.skills/v8-utilities/SKILL.md +79 -0
  107. package/dist/microi.skills/v8-utilities/references/client-api-index.md +136 -0
  108. package/dist/microi.skills/v8-utilities/references/platform-http-routes.md +80 -0
  109. package/dist/microi.skills/v8-utilities/references/server-api-index.md +129 -0
  110. package/dist/microi.skills/v8-workflow/SKILL.md +322 -0
  111. package/dist/microi.skills/workspace-conventions/SKILL.md +479 -0
  112. package/package.json +40 -0
@@ -0,0 +1,140 @@
1
+ ---
2
+ name: ai-engine
3
+ description: Microi AI 引擎、模型代理、NL2SQL/NL2V8 与知识库规范。用于模型路由、密钥和订阅配额、Schema/Skill 关键词检索与可选向量融合、提示词安全、流式响应、租户隔离和验收。
4
+ ---
5
+
6
+ # Microi AI Engine
7
+
8
+ ## 能力
9
+
10
+ 平台 AI 包含聊天/流式聊天、模型代理、模型路由、订阅配额、NL2SQL、NL2V8、数据库 Schema 关键词检索、可选向量融合和 V8 Skill 文档检索。AI 输出是建议,不是授权;执行 SQL、V8 或 MCP 写入前仍走平台权限与确认。
11
+
12
+ 当前入口并不共用一条检索链路:普通 `Chat/ChatStream` 使用服务端会话上下文和固定核心规范 Prompt;`NL2SQL` 使用当前租户 Schema 双模式检索;`NL2V8` 使用 Skill 镜像与当前租户 Schema 双模式检索。默认模式不依赖 Ollama、`nomic-embed-text` 或 Qdrant;只有显式开启向量数据库时才增加向量通道。`Microi.Server/Microi.AI` 不是 MCP Host,没有注册 MCP Tools,也没有处理 `tool_calls` 的代理循环。MCP Server 目前由 Codex、Copilot、Cursor、Claude Code 等外部宿主调用。禁止仅凭 Prompt 中出现“使用 MCP”就声称在线 AI 已经执行工具。
13
+
14
+ 未来若给平台在线 AI 增加工具调用,优先在 `Microi.AI` 内建立受限 Tool Gateway,复用 FormEngine、V8McpLogic 等后端服务的授权入口;不要让后端使用超级管理员 Token 再请求自己的 MCP。每次工具调用必须继承当前用户、`OsClient`、Token/权限快照和审计上下文,模型只能提出调用建议,服务端仍负责参数白名单、写操作确认、幂等、步数/时长/结果大小上限和权威回读。工具返回的数据继续按不可信内容处理,不能反向覆盖系统规则。
15
+
16
+ ## 代码分层
17
+
18
+ AI 业务统一实现在 `Microi.Server/Microi.AI`。`Microi.Server/Microi.net.Api` 只是 HTTP、SSE 与 SignalR 传输层,可以做路由、请求绑定、读取认证中间件产生的可信用户/租户、传递取消信号和写响应,但不能承载模型选择、Schema/Skill 检索、NL2SQL 授权与执行、提示词编排、代理路由、供应商密钥、额度计量、订阅支付状态或 AI 工作流。
19
+
20
+ - Controller、Hub 只调用 `IMicroiAI`、`AiProxyService`、`SubscriptionService`、`AiWorkflowService` 等 `Microi.AI` 门面,不直接查询 `mic_ai` / `mic_sub_order`,不接触上游密钥和向量基础设施。
21
+ - “授权 + 执行”必须由领域门面原子完成,不能让接口层先生成可伪造的 `AllowedTables` 或遗漏某一步。
22
+ - AI 的 Qdrant/Ollama/Embedding 配置、Schema 初始化和其它生命周期任务由 `AddMicroiAI()` 在模块内自注册;API 的 `Program.cs` 只负责调用模块注册。
23
+ - `Microi.Core` 只承载跨模块契约和模型。新增入口时先扩展 AI 领域服务,再添加薄 Controller/Hub 适配,禁止复制业务流程。
24
+
25
+ ## 模型与密钥
26
+
27
+ - 模型 Provider、Endpoint、ApiKey、AuthPrefix 和上游模型 Id 只保存在服务端受保护配置。
28
+ - 普通用户使用平台签发的受限 API Key/订阅身份,不能枚举或读取上游密钥。
29
+ - 当前计量记录除问题摘要外还可能持久化完整 `Question`、`Answer`,部分诊断日志也会输出问题或摘要。处理现有版本时必须把这些字段视为敏感业务数据,限制查询权限和留存;不要声称已经全面脱敏。
30
+ - 发布目标是日志只记录 trace id、模型、耗时、token 计数和状态,Prompt/Answer 按租户策略脱敏,密码、Token、连接串和完整业务数据不落日志。该目标必须用源码和真实数据回读证明。
31
+ - OpenAI 代理流式接口会传递 HTTP 请求取消信号;普通 `ChatStream` 与 `NL2V8` 当前主要使用内部超时 Token。不要声称浏览器断开一定立即终止上游调用或计费。
32
+
33
+ ## 跨端 AI 助手与商城交付
34
+
35
+ - PC 与移动端复用 `mci_ai_data_assistant`。`Bootstrap` 返回的 `Enabled`、`Models`、`AllowedDomains` 和 `Prompts` 是跨端共同事实源;快捷问题来自启用的 `mci_ai_data_domain.PromptExamples`,前端不能维护另一套固定文案。
36
+ - 普通角色必须匹配启用的 `mci_ai_role_policy`。只有后端可信的 `V8.CurrentUser.Level >= 9999` 可以在新安装租户缺少角色策略时获得安全兜底:从目标租户动态读取已启用业务域和模型,范围为 `All`,仍保持 `AllowRawSql=false`、敏感字段默认关闭。不得相信客户端提交的 Level、角色名或账号名。
37
+ - 商城包不能携带发布租户的角色 Id、模型 Id 或密钥;应携带业务域定义和接口引擎,由安装后的目标租户动态发现自己的启用模型。发布后回读 `sys_microistore.AppVersion/AppPakcet`,并真实执行 `Bootstrap` 验证超级管理员可用、模型非空、快捷问题存在。
38
+
39
+ ## Schema 检索双模式
40
+
41
+ ### 默认关键词模式
42
+
43
+ `mic_ai.EnableVectorDatabase` 缺失、`null`、空值或 `0` 均表示关闭;只有显式启用才进入向量模式。旧数据库没有该字段时必须保持可用,不能因为读取不到开关而尝试连接历史向量配置。
44
+
45
+ 关闭时必须完整跳过 Embedding/Ollama/Qdrant 的客户端创建、连接、初始化、同步和搜索;初始化、刷新或同步 Schema 的入口只维护关键词索引。不能先连接向量服务再根据开关丢弃结果,也不能让向量服务不可用拖慢默认 AI 对话。
46
+
47
+ 默认检索链路:
48
+
49
+ 1. 用当前 `mic_ai` 对话模型输出结构化 JSON 关键词,覆盖表名、表说明、菜单名、字段名和字段说明;模型输出只用于召回,不能直接变成 SQL 或扩大权限。
50
+ 2. 大模型扩词超时、异常或格式无效时,使用问题原文和确定性的中文 2/3 字滑窗分词回退,不依赖另一个本地文本模型。
51
+ 3. 从当前 `OsClient` 的 `diy_table`、`diy_field` 和 `sys_menu` 构建 Schema 关键词索引;查询时必须带入服务端授权产生的精确 `AllowedTables`,空白名单失败关闭。
52
+ 4. 对授权候选表按表名、表说明、菜单名、字段名和字段说明加权排序,再回读命中表的准确字段元数据构建 Prompt;候选表名不能替代真实字段。
53
+ 5. SQL 生成后仍执行来源表白名单、只读语句、行数、超时和其它 NL2SQL 安全校验。检索命中不是授权。
54
+
55
+ Schema 索引缓存按 `OsClient` 隔离,使用 FormEngine 授权/结构版本作为 Key 的一部分:共享 Redis 用于跨节点复用,进程内短 TTL 只能做可丢失的 L1 优化。结构或菜单权限更新必须推进版本或显式刷新;Redis 不可用时回源数据库,不沿用版本未知的旧索引。不要为每次对话扫描 500~1200 张表和全部字段,也不要创建按用户永久复制的全量索引。
56
+
57
+ ### 可选向量融合模式
58
+
59
+ `EnableVectorDatabase=1` 时仍先执行关键词通道,再惰性连接 Embedding/Ollama/Qdrant,按当前租户检索向量候选并进行关键词/向量融合。向量结果仍需与服务端 `AllowedTables` 取交集;Qdrant、Embedding 或 Ollama 初始化/搜索失败时安全回退到关键词结果,不应让已可用的默认链路失败。
60
+
61
+ 返回数据用 `SchemaSearchMode` 标明实际使用的通道:`keyword` 表示纯关键词或向量失败回退,`hybrid-vector` 表示本次确实使用了关键词/向量融合;`SchemaCandidateCount` 只返回授权后的候选数量,不暴露未授权表名或字段。
62
+
63
+ 向量配置统一放在 `mic_ai` 的“向量数据库(可选)”Tab:`EnableVectorDatabase`、`EmbeddingApiUrl`、`QdrantHost`、`QdrantPort`、`QdrantApiKey`、`VectorTopK`、`VectorScoreThreshold`。密钥只在服务端读取;未启用时这些地址和凭据不得参与任何网络请求。
64
+
65
+ ## NL2SQL
66
+
67
+ ### 当前实现边界
68
+
69
+ 1. `ServerAuthorizationApplied`、`ServerMaxRows` 同时使用 Newtonsoft.Json 和 System.Text.Json 的 `JsonIgnore`,只能由 Controller 写入。执行层要求授权标记为真且精确表白名单非空;客户端 `AllowedTables` 最多只能缩小服务端范围,不能扩大权限。
70
+ 2. 服务端候选表只取当前租户 `diy_table` 中未删除、非平台受保护的业务表。某角色从未保存过 AI 策略时,为兼容老数据库,只使用其现有 FormEngine `List` 读取权限中的无行级范围业务表;一旦存在该角色策略记录(包括显式禁用),就严格要求启用、`All/全部数据`、开启 `AllowRawSql`。两种路径都必须与缓存的 FormEngine 权限取交集,客户端名单只能继续收窄。
71
+ 3. Schema 关键词索引和可选向量 collection 均只在当前 `OsClient` 内使用;关键词排序与向量结果都会按服务端精确白名单过滤,未授权表不能进入生成 Prompt。
72
+ 4. 执行前使用词法门禁要求单条 `SELECT`,逐个验证每个 `FROM`/`JOIN` 来源表;拒绝注释、多语句、CTE、`UNION`、写操作、危险关键字/函数、变量赋值和逗号连接。
73
+ 5. 查询按 MySQL、PostgreSQL、SQLite、KingBase、SQL Server、Oracle、达梦等数据库类型注入或包裹 `MaxRows + 1` 行限制;服务器允许的 `MaxRows` 为 1..100,数据库命令超时为 30 秒,最终只返回授权的最大行数。
74
+ 6. 普通角色对目标表的 FormEngine 授权一旦带 `SqlWhere`/`SqlJoin` 等行级范围,该表会被通用 NL2SQL 拒绝,避免把表级可读误当成全表可读。
75
+
76
+ ### 剩余边界与使用规则
77
+
78
+ 1. 当前实现是严格词法分析与来源表白名单,不是完整 SQL AST;不能宣称已对所有字段、表达式和数据库方言完成 AST 级语义证明。
79
+ 2. 模型生成 SQL 中的动态值当前不会被服务端重写为数据库参数。不得把 NL2SQL 描述为“模型值已参数化”;涉及用户输入值、高风险条件或复杂查询时,改用显式参数化的业务 ApiEngine。
80
+ 3. 通用 NL2SQL 不执行菜单 `SqlWhere`/`SqlJoin`,因此不提供本人、部门、关联记录等行级查询。此类需求必须使用经过管理员审核、范围条件固定、参数化并记录审计的 ApiEngine。
81
+ 4. 只有通过明确 AI 角色策略、精确表配置和 FormEngine 表级读取授权的无行级范围查询才能进入通用 NL2SQL;任一范围无法证明时失败关闭。
82
+ 5. 自动化测试必须覆盖客户端伪造服务端标记、空白名单、未授权 `FROM`/`JOIN`、子查询、别名、大小写、注释、多语句、CTE、`UNION`、危险函数、各数据库行限制和超时。
83
+
84
+ 高风险、复杂方言或需要行级范围的查询应生成业务 ApiEngine 草稿供管理员审核,不直接执行通用 NL2SQL。
85
+
86
+ ## NL2V8
87
+
88
+ - 默认使用大模型关键词扩展、内置 `microi.skills` 关键词检索和当前租户 Schema 关键词索引;启用向量数据库后才增加 Skill/Schema 向量召回,失败回退到关键词结果。
89
+ - 检索官方 `microi.skills` 镜像与当前租户 Schema;前端/后端 API 必须区分。
90
+ - 生成代码遵守参数化 SQL、当前租户、事务、幂等、文件/SSRF 和控制面边界。
91
+ - 代码保存到 `sys_apiengine` 或表单 V8 前必须由管理员确认、语法检查、版本递增、回读和真实调用验证。
92
+ - AI 不得把 `_TrustedServerInvocation`、`Level`、角色名或 `_SysMenuId` 当可伪造参数。
93
+
94
+ ## 向量知识库
95
+
96
+ 向量知识库是可选增强,不是平台在线 AI 的必装依赖。未开启 `EnableVectorDatabase` 时,不部署 Ollama、`nomic-embed-text` 和 Qdrant 也必须完整支持关键词 Schema 检索、NL2SQL 与 NL2V8。
97
+
98
+ 吾码一键安装固定使用轻量默认模式,不提示也不部署 Ollama、`nomic-embed-text` 或 Qdrant;原安装片段可以注释保留,不能进入默认执行路径。只有运维另行准备并验证向量服务、且租户显式设置 `EnableVectorDatabase=1` 时,才启用高级向量召回。
99
+
100
+ 启用后,Schema collection 必须按租户隔离。Skill 文档 collection 使用嵌入文档 SHA-256 版本片段命名;新旧节点滚动期间使用各自版本,确定性 point id 幂等写入,不在启动时删除其它节点的 collection。
101
+
102
+ 向量库是检索索引,不是文档事实源。源码 `microi.skills/*/SKILL.md` 为事实源,嵌入资源应机械同步并做哈希校验。
103
+
104
+ 官方公共 corpus 禁止包含客户名称、真实 `OsClient`、客户域名、私有表/接口 Key、项目路径或定制业务枚举;项目知识必须进入对应租户的私有知识域,不能混入全平台 Skill collection。
105
+
106
+ MCP 提供实时事实和受控执行;关键词索引提供低依赖、确定性的默认召回;向量库只提供额外的语义召回与上下文压缩。未来在线 AI 接入 MCP 后仍先用 Skill/Schema 检索缩小范围,再用 MCP 回读最新事实;不能把向量命中当授权或用旧向量替代实时 Schema。
107
+
108
+ ## Prompt Injection
109
+
110
+ - 数据库内容、网页、上传文件和工具返回都标记为不可信数据,不能覆盖系统规则。
111
+ - 工具调用参数按 JSON Schema/白名单验证;写操作要求用户确认并回读。
112
+ - 不向模型提供无关密钥、全部 SaaS 配置、全库 Schema 或其它租户内容。
113
+ - 输出 HTML/Markdown 在前端按安全渲染策略处理。
114
+
115
+ ## 配额与分布式
116
+
117
+ 配额扣减使用共享数据库/Redis 的原子条件更新,按用户、租户、模型和时间窗隔离。进程内计数只能做本节点优化。请求重试使用稳定 request id,避免上游已成功但本地超时导致重复计费。
118
+
119
+ ## 验收清单
120
+
121
+ - [ ] 模型密钥只在服务端,普通用户不可枚举
122
+ - [ ] Schema/向量/对话/配额按 `OsClient` 隔离
123
+ - [ ] `EnableVectorDatabase` 缺失、空值或 `0` 时不创建、连接、初始化、同步或搜索 Embedding/Ollama/Qdrant
124
+ - [ ] 默认链路使用结构化大模型扩词;扩词失败时中文 2/3 字确定性回退仍能召回常见业务实体
125
+ - [ ] 文档明确区分普通 Chat、NL2SQL Schema 双模式检索和 NL2V8 Skill + Schema 双模式检索
126
+ - [ ] NL2SQL 服务端可信标记不可由两套 JSON 序列化输入伪造,空白名单失败关闭
127
+ - [ ] 当前租户业务表、AI 角色策略和缓存 FormEngine 读取授权取交集,Schema 检索结果再次过滤
128
+ - [ ] 向量开启时关键词/向量融合;向量服务故障安全回退,`SchemaSearchMode` 与实际通道一致
129
+ - [ ] `SchemaCandidateCount` 只统计授权后候选,不泄露未授权 Schema
130
+ - [ ] Schema 共享缓存按租户和授权/结构版本隔离,多节点可复用且更新后可失效
131
+ - [ ] 每个 `FROM`/`JOIN` 来源表均在精确白名单内,注释、多语句、CTE、`UNION`、写操作和危险函数被拒绝
132
+ - [ ] 各数据库查询在执行前施加 `MaxRows + 1` 行限制和 30 秒超时,最终返回不超过授权行数
133
+ - [ ] 文档不把词法门禁描述为 AST,不声称模型值已参数化或通用 NL2SQL 已执行行级 `SqlWhere`
134
+ - [ ] 带行级范围或高风险查询失败关闭,并改走审核、参数化和审计的业务 ApiEngine
135
+ - [ ] NL2V8 保存前有确认、语法、版本、回读和执行验证
136
+ - [ ] Prompt injection 不能调用未授权工具
137
+ - [ ] 未实现 MCP Tool/Agent Loop 时,界面和文档不会声称在线 AI 已执行 MCP
138
+ - [ ] 各流式入口分别验证断开取消或明确仅有超时,不做过度承诺
139
+ - [ ] Prompt/Answer 当前留存范围已披露;全面脱敏只能在真实实现并回读后声明
140
+ - [ ] 新旧节点知识库版本可共存
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "AI 引擎"
3
+ short_description: "配置模型、知识库、提示词、密钥边界、内容安全、配额与应用验收"
4
+ default_prompt: "使用 $ai-engine 设计并验收当前 Microi AI 能力。"
@@ -0,0 +1,105 @@
1
+ ---
2
+ name: app-store
3
+ description: Microi 应用商城开发、打包、安装和升级规范。用于官方/社区应用、Manifest、源码与构建产物、依赖、后台安装任务、租户隔离、增量升级、回滚和验收。
4
+ ---
5
+
6
+ # Microi 应用商城
7
+
8
+ ## 核心原则
9
+
10
+ 应用包是可审计、可重复安装、可增量升级的交付单元。运行类型使用 `ApplicationType`:普通平台包的新建默认值是 `Regular`,既有商城平台应用/通知仍使用 `Platform`,另外还有 `MicroService`、`UniApp`、`Web`;读取端必须兼容 `Regular/Platform`,不能在迁移完成前强制改单值。官方/社区来源使用 `PublisherType`。
11
+
12
+ `AppType` 是历史复用字段:旧包/接口曾把它用于官方/社区来源,也曾把它作为运行类型回退。新代码不能把 `AppType` 当事实源;只在读取旧数据时回退,写入新数据使用 `ApplicationType + PublisherType`。
13
+
14
+ 客户已有的全局 V8、表单配置、菜单、字段和自定义代码必须保留。升级采用存在性检查、差异合并和包隔离,禁止整表覆盖或把发布方租户数据原样复制到目标租户。
15
+
16
+ ## 包内容
17
+
18
+ - Manifest:应用 Key、版本、兼容平台版本、依赖和资源清单。
19
+ - 数据模型:表、字段、菜单、角色权限、接口引擎、事件、数据源、页面、打印、工作流、任务。
20
+ - 源码与构建:私有源码包与可部署构建包分离,记录 SHA-256。
21
+ - 安装/升级脚本:幂等、可恢复、可回读;不包含租户密钥、Token、连接串或 License keys。
22
+ - 迁移采用“先扩展、后迁移、再收缩”,支持新旧节点短暂并存。
23
+
24
+ ## 安装流程
25
+
26
+ 1. 校验签名/哈希、包版本、平台兼容性、依赖和磁盘/配额。
27
+ 2. 创建全局唯一 `InstallationId` 和稳定幂等键。
28
+ 3. 使用后台任务执行,阶段性持久化进度与 checkpoint。
29
+ 4. 按 Manifest 差异创建缺失资源;已有资源只更新包拥有且允许升级的属性。
30
+ 5. 写入成功后刷新共享缓存版本。
31
+ 6. 回读表、字段、引擎、菜单、权限、页面等关键资源。
32
+ 7. 做 HTTP、UI 和权限冒烟;成功后标记安装版本。
33
+
34
+ 安装中断后从 checkpoint 幂等恢复;不能依赖当前 API 节点内存。
35
+
36
+ ## 权限与租户
37
+
38
+ - 商城定义、安装、升级、卸载和应用源码只允许 `Level >= 9999`。
39
+ - 所有资源按目标 `OsClient` 写入;包内不能携带源租户 `OsClient`、数据库、Redis、对象存储、MQ/MQTT、AI 或第三方密钥。
40
+ - 按钮调用后台安装接口时,前端只传应用/版本/安装 Id;目标租户和管理员身份由 Token 确定。
41
+ - 卸载是破坏性操作,必须明确列出将删除/保留的资源、二次确认并优先软删除/归档业务数据。
42
+
43
+ ## MCP 工作流
44
+
45
+ 1. 安装/更新现成商城应用时,先调用 `microi_install_store_application` / `microi_update_store_application` 且不传 `confirmExecution`,核对目标租户、商城源、StoreId 和幂等请求 Id 的预检结果。
46
+ 2. 用户明确确认后,把 `confirmExecution` 精确设为 `StoreId`,提交真实持久化后台任务;只传 StoreId、版本和商城源定位信息,不通过 MCP/HTTP 传完整 `AppPakcet`。
47
+ 3. 自建应用或低代码系统先用 `microi_list_applications` / `microi_get_application_context` 盘点源码,再用 `microi_get_manifest_schema`、`microi_plan_system` 与 `microi_generate_system(dryRun:true)` 干跑。
48
+ 4. 安装任务必须回读至 `Succeeded`,再执行 `microi_validate_system`、远端资源回读和真实 UI 验收;仅返回 TaskId 不代表安装成功。
49
+
50
+ 已有 MicroService 优先新增页面/路由;没有时才创建、同步源码、发布构建。复杂安装交互使用 `V8.OpenAppDialog`,后台任务上报进度。
51
+
52
+ ## VS Code 本地应用与发布边界
53
+
54
+ - `AI应用` 本地树按每个一级目录的 `.microi-micro-app.json` 发现项目;只要 `osClient/apiBaseUrl` 与当前连接一致,就必须显示 `Web / UniApp / MicroService`,不得用 `runtime === "micro-app"` 过滤掉其它应用类型。无效清单应记录诊断,不能静默吞掉整个目录。
55
+ - “安装到当前租户”和“发布到应用商城(不安装)”是两个独立动作。商城发布只能同步 `sys_microistore`、应用源码/构建/版本元数据及安装包,不得新增或修改当前租户的 `sys_microiservice / sys_microiservice_page`;操作前后必须回读运行态确认未变化。
56
+ - 应用项目行必须直接显示商城发布入口,不能只藏在右键菜单;同时保留构建安装和源码同步状态入口。
57
+
58
+ ## 版本与回滚
59
+
60
+ - 版本号单调递增,保存变更清单和前后哈希。
61
+ - 公有发布必须同时保留两套入口:`/{OsClient}/ai-app-publish/{AppKey}/index.html` 永远指向最新版,`.../versions/{Version}/index.html` 永远保留该历史版本。先完整上传并逐字节验签不可变版本目录,再切换稳定入口。带 `data-microi-immutable-runtime` 的新入口通过版本目录解析全部资源,可先切换入口;旧入口仍在其它稳定资产之后切换。不能机械固定“入口永远最后”而破坏两种契约。
62
+ - stage 前回读并冻结应用的 `CurrentVersion + AppVersion`;finalize 必须同时传 `ExpectedCurrentVersion + ExpectedAppVersion`,在以不可变 AppId 加锁后再次 compare-and-set。缺失前置条件、AppId/AppKey 漂移或旧请求晚到一律失败关闭;重新发布必须重新盘点,不能静默回退。
63
+ - 新清单发布成功时,同应用 `dist/` 下不再出现的 active 文件元数据只能条件式改为可逆归档 scope,条件必须包含 AppId、路径、旧 scope 与版本;禁止删除 HDFS/数据库记录,也不得触碰 Private、非 `dist/` 或另一应用的行。
64
+ - 官网、二维码和用户分享只使用无版本号根入口,不追加 `v/apiBase/OsClient`。目标租户的 `ApiBase/OsClient` 在发布或安装时写入入口 HTML 的 `window.__MICROI_APP_CONTEXT__ / MICROI_API_BASE / MICROI_OS_CLIENT`;安装包不得沿用发布端运行上下文。
65
+ - 数据迁移通常只向前;回滚应用版本不能假设自动回滚业务数据。
66
+ - 更新失败保留原版本可运行资源,记录失败阶段;不要清空客户 V8 后再尝试恢复。
67
+ - 私有源码仓库、`Microi.net/License/keys` 和部署密钥不进入公开应用包。
68
+
69
+ ## 验收清单
70
+
71
+ - [ ] 同一包重复安装无重复表/字段/菜单/任务
72
+ - [ ] 客户自定义 V8 与非包拥有配置保持不变
73
+ - [ ] 源码包、构建包、Manifest 和数据库版本一致且哈希可核
74
+ - [ ] 无版本号根入口与当前商城版本一致,历史版本 URL 仍可独立访问
75
+ - [ ] 安装到不同 ApiBase/OsClient 后,入口 HTML 使用目标租户上下文且分享 URL 无运行参数
76
+ - [ ] 中断/重启后可恢复,两个节点不会重复副作用
77
+ - [ ] 普通角色不能安装、升级、卸载或读取私有源码
78
+ - [ ] 缓存刷新后远端 API 与真实 UI 通过
79
+ - [ ] 卸载范围明确、可审计、可恢复或已提示不可恢复
80
+
81
+ ## 复盘:后台任务基础包的自举与索引幂等
82
+
83
+ - `app.microi.background-task` 自身负责创建/修复后台任务表,首次安装和离线安装必须以前台接口完成;不能先调用 `RunBackground`,否则旧库缺少 `OsClient` 等字段时会在导入开始前失败。
84
+ - 后台任务可用性不能只检查表存在,还要检查运行时必需列;部分升级的旧表必须返回“能力尚未就绪”,不能继续拼接包含缺失列的 SQL。
85
+ - 应用包中的独立 `CREATE INDEX` 必须按表名和索引名做执行前回读;并发创建失败后再次回读,已存在则按幂等成功处理。索引 DDL 不能重复触发整张表的字段同步。
86
+ - 基础包必须同时携带 `OsClient` 的 `PhysicalColumns` 定义、建表内联索引与 4 条独立索引 DDL;新表靠建表一次成型,旧表靠物理列同步和独立 DDL 修复。安装前先把“应用商城”更新到包含 `BACKGROUND_TASK_BOOTSTRAP_READINESS_V1`、`APPLICATION_ASSET_BACKGROUND_CHUNKS_V1` 的 v1.8.0+ 导入器;安装成功前必须回读全部运行字段及索引,验收覆盖首次安装、部分旧表修复、重复安装和两节点竞态。
87
+ - 其它用户更新吾码 VS Code 插件并执行“初始化 AI 配置/拉取 Skills”后,AI 应自动识别本规范:大任务优先提交真实后台任务;若基础能力未就绪,先指导用户更新应用商城并以前台方式安装 `app.microi.background-task`,不得伪造进度或让基础包自举入队。
88
+ - 重复安装先比较应用包拥有的字段定义,完全一致就跳过 `UptFormData`。Jint 的 `LimitMemory` 统计累计托管分配而非当前存活堆;大量无效字段更新即使被 GC 回收也会耗尽预算。v1.8.0 导入器每个后台片最多实际上传 8 个文件,并以约 32 MB Base64 为分片目标;为避免单个大文件无限空转,每片至少允许处理一个文件。片末返回 `HasMore + Checkpoint`,下一片按 `AppId + FilePath + Hash` 复用已提交资产,并禁止为统计再次解码整文件 Base64。
89
+ - 只有固定 Key `import-microi-store-package`、服务端可信身份、`Level >= 9999`、当前进程主租户、持久化后台 TaskId 五项同时成立时,后端才使用 `ResidentMemoryGuardOnly`,跳过会永久累计已回收分配的 Jint 内存约束。该特例仍受容器优先的进程 RSS 防线保护:95% 停止接收新工作,98% 有界停机并由持久任务恢复。普通/前台/子租户/其它 V8 不得借用此特例。
90
+
91
+ ## 复盘:官网升级资源同步的三道门
92
+
93
+ - 官网当前资源只是三方合并的一侧,允许暂时落后于本地发布候选。下载阶段只校验固定白名单、稳定资源身份、JSON 可解析性及服务端返回 SHA-256;不能用“必须已包含本地最新功能标记”的规则提前拒绝旧官网,否则会形成“官网不够新所以永远无法发布新版”的循环依赖。
94
+ - 本地输入和三方合并后的最终候选必须继续执行最低版本、功能标记、内嵌逻辑副本一致性等严格校验;发布成功并按内容哈希回读一致后才能推进 `.resource-sync-base`,不能把放宽读取门误做成放宽发布门。
95
+ - 应用包版本与平台发布版本分别单调递增。包正文需要写回而本地包版本、平台版本均未高于官网时,应基于官网包版本自动递增补丁号;内容无变化时不得递增,必须用连续两次同步验证第二次为零变更。
96
+ - MCP 配置中的官方 API、`OsClient` 与 Token 文件是鉴权事实源,但编辑器可执行文件、插件版本目录和 `cwd` 都是易漂移的启动信息。发布器应保留鉴权配置、固定校验 `https://api.itdos.com + itdos`,并从已配置入口、同级最新已安装插件或当前工作区依次发现可信 `mcp-server.js`,使用正在运行发布脚本的 Node 启动;插件升级或旧目录清理不能再次阻塞后端发布。
97
+ - 本地资源同步的官网读取、发布和发布后回读应使用同一个已校验的 `microi_itdos` MCP 链路;CI 无 MCP 时才允许凭显式 Token 使用 HTTP。V8 独立文件与应用包内嵌副本合并时,先把文件头说明和 `Version` 与可执行正文分离:两端独立升版不能算代码冲突,不同正文安全合成后应基于两端最高版本再升一版;只有同一段可执行逻辑出现不同实现才失败关闭。
98
+ - 发布验收至少包含:定向合并测试、真实 `PublishBatch`、六项资源逐项 SHA-256 回读,以及立即执行第二次幂等重跑。任何一步失败都不得宣称官网已同步,也不得推进共同基线。
99
+
100
+ ## 复盘:老租户 NULL 数据阻止物理列收紧
101
+
102
+ - 触发场景:商城应用包把既有字段从可空升级为 `NOT NULL DEFAULT ...`,老租户的物理列已经存在,但历史记录仍为 `NULL`;导入器直接执行 `ALTER TABLE ... MODIFY COLUMN ... NOT NULL` 时,MySQL 报 `Invalid use of NULL value`,整个安装分片失败。
103
+ - 根因:物理列同步只比较类型、可空性、默认值和注释,没有在收紧可空性前迁移存量数据。列默认值只影响后续写入,不会自动修复既有 `NULL`。
104
+ - 通用规则:当包要求 `NOT NULL`、目标列仍可空且存在历史 `NULL` 时,必须先用包内明确声明的默认值参数化回填,再执行列约束变更;包未声明默认值时失败关闭并报告影响行数,禁止猜测业务值。该步骤必须可重复执行,并允许多节点并发重试后得到同一结果。
105
+ - 自动化检查:构造可空旧列及多条 `NULL` 行,断言导入器按“统计 NULL → 参数化回填 → `MODIFY ... NOT NULL`”顺序执行;覆盖字符串、整数、零行、缺失默认值、重复执行,以及商城包中全部发布协议状态字段。
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "应用商城"
3
+ short_description: "开发、打包、安装、差异升级和验收可复用且保护客户配置的吾码应用"
4
+ default_prompt: "使用 $app-store 设计、打包、安装或升级当前 Microi 应用。"
@@ -0,0 +1,184 @@
1
+ ---
2
+ name: business-blueprint
3
+ description: Microi 业务架构蓝图(System Blueprint)— 设计期系统知识图谱,AI 生成低代码系统时防幻觉的唯一事实源
4
+ ---
5
+
6
+ # Microi 业务架构蓝图(System Blueprint)
7
+
8
+ ## 这是什么
9
+
10
+ 业务架构蓝图是 Microi 吾码的 **设计期系统总图**,不是 n8n / Dify / ComfyUI 那种运行时工作流。它一次同时承担三个职责:
11
+
12
+ 1. **可视化总图** — 用户在前端 X6 画布拖拽节点,完整描述一个业务系统的组成
13
+ 2. **AI 事实源** — AI 生成代码、表、接口引擎、菜单前必读的"宪法",防止幻觉
14
+ 3. **VSCode/插件上下文** — 编辑器侧边栏据此提供精准的字段/接口/事件补全
15
+
16
+ ## 三层模型(同一画布内分层)
17
+
18
+ | 层 | 关注点 | 典型节点 shape |
19
+ |---|---|---|
20
+ | 领域层 Domain | ER:表、字段、外键 | `table`, `field`, `relation` |
21
+ | 流程层 Process | 跨表业务流:单据流转、状态机、子流程 | `start`, `task`, `decision`, `subDiagram`, `end` |
22
+ | 行为层 Behavior | V8 事件、接口引擎、菜单按钮、定时任务 | `engine`, `v8Event`, `menuBtn`, `job` |
23
+
24
+ 每个节点通过 `refs` 字段反向指向平台真实资源(diy_table / sys_apiengine / sys_menu / V8 事件文件 ...)。
25
+
26
+ ## 数据存储(system tables,已建好)
27
+
28
+ | 表 | 作用 |
29
+ |---|---|
30
+ | `sys_business_blueprint` | 蓝图主表(BlueprintData JSON 存全图) |
31
+ | `sys_blueprint_relation` | 反向引用索引(resource→blueprint,用于"这张表/接口被谁引用" + 漂移检测) |
32
+ | `sys_blueprint_history` | 历史快照(diff/回滚) |
33
+
34
+ ## MCP 工具
35
+
36
+ | Tool | 用途 | 写入 |
37
+ |---|---|---|
38
+ | `microi_get_blueprint_schema` | 读取蓝图协议指南 | 否 |
39
+ | `microi_list_blueprints` | 列出当前 OsClient 所有蓝图 | 否 |
40
+ | `microi_get_blueprint` | 读取单个蓝图(含 BlueprintData) | 否 |
41
+ | `microi_save_blueprint` | 创建或更新蓝图 + 自动写历史 + 重建反向索引 | 是(需 confirmExecution) |
42
+ | `microi_delete_blueprint` | 软删除蓝图 | 是 |
43
+ | `microi_validate_blueprint` | 漂移检测:所有 refs 是否仍存在 | 否 |
44
+
45
+ ## AI 工作流(强制约定)
46
+
47
+ ### 场景 A:用户提需求让 AI 生成新系统
48
+
49
+ ```
50
+ 1. microi_list_blueprints # 看是否已有相关蓝图
51
+ 2. microi_get_blueprint(id) # 有则读取作为上下文
52
+ 3. microi_get_manifest_schema # 读 manifest 协议
53
+ 4. microi_plan_system / generate_system
54
+ 5. microi_get_table_indexes / microi_create_table_index
55
+ # 按蓝图查询与业务不变量创建并回读索引
56
+ 6. microi_save_blueprint # 同步写入/更新蓝图(含本次新增的表/引擎/菜单引用)
57
+ 7. microi_validate_blueprint # 验收
58
+ ```
59
+
60
+ ### 场景 B:用户让 AI 修改某张表 / 加字段 / 改接口引擎
61
+
62
+ ```
63
+ 1. microi_list_blueprints + 文本搜索目标 table/engine 名
64
+ 2. 命中蓝图 → microi_get_blueprint 读取
65
+ 3. 根据蓝图理解上下文(这张表属于哪个业务流?哪些节点引用它?)
66
+ 4. 执行修改(add_field / upsert_engine / save_event_code 等)
67
+ 5. microi_validate_blueprint # 检查引用是否漂移
68
+ 6. 若蓝图内容变化(如字段重命名)→ microi_save_blueprint 同步
69
+ ```
70
+
71
+ ### 场景 C:用户问"这张表是干什么的 / 哪个接口在用它"
72
+
73
+ ```
74
+ 1. microi_list_blueprints
75
+ 2. 通过反向索引 sys_blueprint_relation 查 → 后端会自动用,AI 不直接读
76
+ 实际操作:microi_get_blueprint 找节点 refs 包含该资源的节点
77
+ 3. 把节点的 label / 所属 diagram / 上下游 edges 反馈给用户
78
+ ```
79
+
80
+ ## BlueprintData 协议(写入时关键)
81
+
82
+ 参考 `microi_get_blueprint_schema` 工具返回。最小可用结构:
83
+
84
+ ```json
85
+ {
86
+ "diagrams": [
87
+ {
88
+ "id": "diag_main",
89
+ "type": "process",
90
+ "name": "总流程",
91
+ "nodes": [
92
+ {
93
+ "id": "n1",
94
+ "shape": "task",
95
+ "label": "客户建档",
96
+ "x": 100, "y": 200,
97
+ "refs": {
98
+ "tables": ["crm_customer"],
99
+ "engines": ["api_customer_create"],
100
+ "v8Events": ["crm_customer:SubmitBeforeServerV8"]
101
+ }
102
+ }
103
+ ],
104
+ "edges": [
105
+ { "source": "n1", "target": "n2", "label": "审核通过" }
106
+ ]
107
+ }
108
+ ],
109
+ "domainModel": {
110
+ "entities": [
111
+ { "table": "crm_customer", "x": 50, "y": 50,
112
+ "relations": [{ "to": "crm_contact", "type": "1:N", "via": "CustomerId" }],
113
+ "indexes": [
114
+ { "name": "uk_crm_customer_osclient_code", "columns": ["OsClient", "Code"], "unique": true, "purpose": "租户内客户编码唯一" },
115
+ { "name": "idx_crm_customer_osclient_status_createtime", "columns": ["OsClient", "Status", "CreateTime"], "unique": false, "purpose": "客户状态列表" }
116
+ ] }
117
+ ]
118
+ },
119
+ "menuTree": {
120
+ "requiredDepth": 2,
121
+ "groups": [
122
+ { "name": "客户中心", "children": ["客户管理", "联系人管理"] },
123
+ { "name": "业务运营", "children": ["工单管理", "服务记录"] },
124
+ { "name": "报表中心", "children": ["检测报告", "阅读日志"] }
125
+ ]
126
+ }
127
+ }
128
+ ```
129
+
130
+ `refs` 内可填的资源类型:`tables` `fields`("table.field")`engines` `menus` `v8Events`("table:eventType")`dataSources` `printTemplates` `workflows` `pages` `jobs`。
131
+
132
+ 领域层每张实体表还必须描述真实查询需要的 `indexes`(名称、有序字段、唯一性、用途)。关系的 `via` 外键、租户内业务唯一键、幂等键、待办/重试扫描字段都必须评估索引。蓝图或需求一旦明确索引,生成 Manifest 时不得遗漏 `tables[].indexes`,落地必须调用 `microi_create_table_index` 并以 `microi_get_table_indexes` 回读;禁止在 V8 中手写 DDL。
133
+
134
+ ### 关系基数先于表单控件(强制)
135
+
136
+ - 每条领域关系必须先写清 `1:1`、`N:1` 或 `1:N`,再决定控件。自然语言中的“子表、
137
+ 明细、清单、条目、行项目、多个记录”默认按 `1:N` 建模,除非用户明确说明只关联一条。
138
+ - `1:N` 的 `via` 必须是**子表上的真实外键**,例如
139
+ `order -> order_detail, type: 1:N, via: OrderId`;Manifest 同时生成子表外键、
140
+ `(OsClient, OrderId)` 回查索引、隐藏子菜单和主表 `TableChild` 控件。
141
+ - `JoinForm` 只映射“主表保存一个目标 Id,并内嵌一条独立目标记录”的 `N:1`/`1:1`
142
+ 关系。禁止把 `1:N` 蓝图映射为 `JoinForm`,禁止让 `JoinForm` 指向当前表。
143
+ - 如果蓝图写了 `1:N`,而 Manifest 只有主表 `XxxId`/`JoinForm`,或缺少子表 `via`
144
+ 外键、子菜单、回查索引,蓝图检查必须失败,不能进入 `dryRun:false`。
145
+ - 基数仍有歧义时,在任何 MCP 写入前询问用户;不得为了避免询问而选择 `JoinForm`。
146
+
147
+ 后台菜单必须在蓝图阶段规划为至少两级结构。客户、设备、工单、报告、日志、配置等业务域应先形成父级菜单,再把具体 CRUD/报表/日志页面作为子菜单写入 Manifest/MCP;不要把所有模块平铺为一级菜单。
148
+
149
+ 如果是改造已生成系统,蓝图不能停留在建议层。必须列出现有一级菜单、目标父级菜单、每个子菜单的 `ParentId` 迁移关系,并通过 MCP 回读 `sys_menu` 验证迁移完成。
150
+
151
+ ## 角色与权限蓝图
152
+
153
+ 从自然语言需求生成 Microi 业务系统时,必须把角色、菜单权限、移动端能力和数据范围写进蓝图,而不是只建表和菜单。
154
+
155
+ 要求:
156
+
157
+ - 内部账号默认使用 `sys_user`,角色来源为 `sys_user.RoleIds` 关联 `sys_role`。移动端和接口引擎都应按 `RoleIds` / `V8.CurrentUser` 判断能力。
158
+ - 蓝图中至少列出角色矩阵:角色名、使用端、后台菜单范围、移动端可见页面、关键动作、数据范围。常见角色如超级管理员、客服、售后师傅、客户账号。
159
+ - 多角色账号按能力并集处理;只有服务端已确认的超级管理员(`Level>=9999`)默认拥有全部内部能力。前端角色名、“超级管理员”文案和 `_IsAdmin` 只能控制展示,不能代替后端授权。
160
+ - 客户账号不能简单获得后台客户、工单、报告全量菜单。客户侧数据应通过客户手机号登录 token、客户绑定表和接口行级过滤提供。
161
+ - 菜单权限使用 `sys_rolelimit` 控制入口;接口引擎仍要做业务级权限和行级数据过滤,不能只依赖菜单是否可见。
162
+ - Manifest/MCP 交付后必须回读 `sys_role`、`sys_menu`、`sys_rolelimit`,验证角色存在、菜单授权正确。
163
+ - 如果 MCP 的通用角色写入工具因 `UpdateTime cannot be null` 等系统字段问题失败,要记录工具缺口并使用平台修复后的专用角色工具。临时迁移可用一次性接口引擎和参数化 `V8.Db` 补建角色,但必须回读验证,且不要把临时接口作为长期业务接口。
164
+
165
+ 角色矩阵示例:
166
+
167
+ | 角色 | 后台菜单 | 移动端能力 | 数据范围 |
168
+ |---|---|---|---|
169
+ | 售后师傅 | 维保运营、工单、维保记录、检测报告 | 查看工单、接单、到场、提交记录、生成报告 | 分配给自己或待接单工单 |
170
+ | 客服 | 客户中心、维保运营、客户报修、报告中心、资讯 | 查看客户与报修、调度工单、查看报告 | 公司内部客户服务数据 |
171
+ | 客户账号 | 默认无后台菜单 | 查看绑定客户的计划、记录、报告,提交报修 | 仅绑定客户 |
172
+
173
+ ## 不要做的事
174
+
175
+ - ❌ 不要把蓝图当成运行时执行器(它不会自动跑接口、不会调度任务)
176
+ - ❌ 不要在审批工作流(jsPlumb / wf_flowdesign)里用蓝图替代 — 两者并存,蓝图是设计图,工作流是执行图
177
+ - ❌ 不要跳过 `microi_get_blueprint` 直接生成代码 — 会产生幻觉(编造字段名、引用不存在的引擎)
178
+ - ❌ 写入 BlueprintData 必须是合法 JSON 字符串(后端会用 JObject.Parse 校验)
179
+
180
+ ## 边界
181
+
182
+ - 蓝图 SaaS 隔离:`sys_business_blueprint.OsClient` + `sys_blueprint_relation.OsClient` 联合索引,不会跨租户
183
+ - 多人协作:当前 v1 用最后写入覆盖;后续 v2 计划加 `LockedBy/LockedAt` + diff 合并
184
+ - 历史快照:每次 SaveBlueprint 都自动落 `sys_blueprint_history`,可通过 BlueprintId 时序回溯
@@ -0,0 +1,89 @@
1
+ ---
2
+ name: datasource-engine
3
+ description: Microi 数据源引擎设计、调用与安全规范。用于配置 sys_datasource 的 SQL、V8、JSON 数据源,为表单选项、报表、接口或远程搜索供数,以及通过前后端 V8.DataSourceEngine.Run 调用和验收。
4
+ ---
5
+
6
+ # Microi 数据源引擎
7
+
8
+ ## 适用边界
9
+
10
+ 数据源引擎适合复用“只读或计算型数据获取”,支持 `SQL`、`V8`、`JSON`。需要跨表事务、状态推进、扣减库存或外部副作用时应创建接口引擎,不要把数据源当业务命令。
11
+
12
+ 数据源定义保存在 `sys_datasource`,属于平台控制面:创建、修改、删除、匿名开关和角色配置只允许 `Level >= 9999` 的可信管理链路。普通角色只能调用已经授权的数据源。
13
+
14
+ ## 标准调用
15
+
16
+ 前端 V8:
17
+
18
+ ```js
19
+ var result = await V8.DataSourceEngine.Run('product_options', {
20
+ Keyword: V8.Form.Keyword || ''
21
+ });
22
+ if (result.Code !== 1) V8.Tips(result.Msg || '加载数据失败', false);
23
+ ```
24
+
25
+ 后端 V8:
26
+
27
+ ```js
28
+ var result = await V8.DataSourceEngine.RunAsync({
29
+ DataSourceKey: 'product_options',
30
+ Keyword: V8.Param.Keyword || ''
31
+ });
32
+ return result;
33
+ ```
34
+
35
+ 兼容代码可以使用 callback;新代码优先 `await`。`DataSourceKey` 也兼容数据源 Id,但发布配置应使用稳定、可读且租户内唯一的 Key。
36
+
37
+ ## SQL 数据源
38
+
39
+ - 动态值必须参数化;禁止拼接用户输入、Token、排序字段或原始 `_Where`。
40
+ - 默认仅查询当前租户数据库,查询中必须保留 `OsClient` 隔离;扩展库由可信配置引用,不能让客户端传连接串。
41
+ - 只选择需要的列并设置结果上限。下拉远程搜索必须分页,不能一次返回整张大表。
42
+ - `$CurrentUser.*$` 等平台替换变量只能用于服务端已验证的当前用户,不能把客户端对象当身份。
43
+ - 菜单数据范围不是任意数据源 SQL 的自动授权。涉及客户、订单、合同等受限数据时,应在 SQL/V8 中显式应用当前用户范围,或改为受菜单授权的 FormEngine/接口引擎。
44
+ - 第三方数据库结构先通过 `microi_inspect_external_database` 发现;数据源只引用已保存的可信 DbKey,不能把浏览器或普通调用者传入的连接字符串交给 `V8.Dbs.Open`。
45
+
46
+ ## V8 与 JSON 数据源
47
+
48
+ - V8 数据源按接口引擎安全标准处理:校验参数、限制返回字段、避免泄露堆栈和密钥。
49
+ - JSON 数据源只存非敏感静态枚举。密钥、连接串和 Token 不得放入 JSON 或返回给浏览器。
50
+ - 数据源 V8 在 `V8TenantContext` 中只能使用当前租户。普通租户伪造 `OsClient` 不会获得跨租户权限。
51
+ - 匿名数据源必须是无身份、无敏感数据、有限结果且可限流的公开能力;不能因为“只读”就默认匿名。
52
+
53
+ ## 表单字段配置
54
+
55
+ 选择类字段使用数据源引擎时,至少配置:
56
+
57
+ ```json
58
+ {
59
+ "DataSource": "DataSource",
60
+ "DataSourceId": "product_options",
61
+ "SelectLabel": "Name",
62
+ "SelectSaveField": "Id",
63
+ "DataSourceSqlRemote": true
64
+ }
65
+ ```
66
+
67
+ 保存后回读 `diy_field.Component/Data/Config`,刷新字段/菜单缓存,再从真实表单验证显示值、保存值、搜索、清空和权限。
68
+
69
+ ## MCP 工作流
70
+
71
+ 1. `microi_get_db_schema` 读取 `sys_datasource`、目标表和菜单关系。
72
+ 2. 使用 `microi_save_data_source` 保存;写入必须有用户确认。
73
+ 3. 回读数据源定义,确认 Key、类型、匿名、角色和代码/SQL。
74
+ 4. 用普通角色、无权限角色和管理员分别调用。
75
+ 5. 对 SQL 注入、超大分页、跨租户 `OsClient` 和匿名访问做负向测试。
76
+
77
+ ## 缓存与分布式
78
+
79
+ 结果缓存 Key 至少包含 `OsClient + DataSourceKey + 权限主体/角色版本 + 参数哈希`。权限相关结果不能只按数据源 Key 缓存。缓存是优化,不是授权事实源;配置更新后使用共享版本或发布订阅让所有节点失效,不能依赖单机静态字典。
80
+
81
+ ## 验收清单
82
+
83
+ - [ ] 普通用户不能维护 `sys_datasource`
84
+ - [ ] 调用只在当前租户执行,伪造 `OsClient` 失败
85
+ - [ ] SQL 参数化、有列清单、分页和上限
86
+ - [ ] 敏感数据应用真实业务权限/数据范围
87
+ - [ ] 匿名、角色和错误响应不泄露内部配置
88
+ - [ ] 字段显示值与保存值真实回读通过
89
+ - [ ] 多节点配置更新后无需逐节点重启
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "数据源引擎"
3
+ short_description: "配置和调用数据源引擎,落实租户、参数、权限、缓存与结果安全"
4
+ default_prompt: "使用 $datasource-engine 设计并验收当前 Microi 数据源。"
@@ -0,0 +1,76 @@
1
+ ---
2
+ name: dos-orm
3
+ description: Dos.ORM C# 数据访问指南。用于 Microi.Server 中编写或审查 DbSession、Entity、From、WhereClip、事务、异步查询、BulkInsert、Upsert、SqlFunc、子查询、导航属性、CodeFirst、读写分离和分库分表代码。
4
+ ---
5
+
6
+ # Dos.ORM
7
+
8
+ Dos.ORM 是 Microi.Server 底层 C# ORM。它不是接口引擎里的 `V8.Db`:
9
+
10
+ - C# 服务端源码使用 `DbSession`、实体和 Section API。
11
+ - V8 JavaScript 使用 `V8.FormEngine` 或 `V8.Db.FromSql`。
12
+ - 不能把 C# lambda/事务示例原样放进 V8。
13
+
14
+ 完整 API、跨库行为与示例见 `references/api-reference.md`。
15
+
16
+ ## 默认选择
17
+
18
+ | 需求 | 首选 |
19
+ |---|---|
20
+ | 普通实体查询 | `dbSession.From<T>().Where(...).ToList/ToListAsync` |
21
+ | 动态条件 | `Where<T>` / `WhereClip` |
22
+ | 复杂 SQL | `FromSql(...).AddInParameter(...)` |
23
+ | 单条/小批写入 | `Insert/Update/Delete` |
24
+ | 大于约 1000 行批量插入 | `BulkInsert/BulkInsertAsync`,先压测批大小 |
25
+ | 按唯一键写入 | `Upsert/UpsertAsync` + 真实唯一索引 |
26
+ | 多步原子写 | `BeginTransaction()`,`using` + Commit/Rollback |
27
+
28
+ ## 安全规则
29
+
30
+ - 数据值全程参数化;`FromSql` 的动态值用 `AddInParameter`。
31
+ - 表名、字段名、排序名不能来自未经白名单验证的用户输入。
32
+ - 保留 `{0}Name{1}` 标识符延迟绑定机制,不能改成字符串替换。
33
+ - `OrderByClip` 的校验不是授权;可排序字段仍需业务白名单。
34
+ - Upsert 幂等依赖数据库唯一键,不能只靠“先查再写”。
35
+ - 租户业务表查询/写入必须包含真实 `OsClient` 范围。
36
+ - 已明确需要的索引在 Microi 业务表上通过 Manifest/MCP 管理,不从临时 SQL 创建。
37
+
38
+ ## 事务与异步
39
+
40
+ ```csharp
41
+ using (var trans = dbSession.BeginTransaction())
42
+ {
43
+ try
44
+ {
45
+ trans.Insert(entity);
46
+ trans.Update<User>(User._.Status, 1, User._.Id == entity.Id);
47
+ trans.Commit();
48
+ }
49
+ catch
50
+ {
51
+ trans.Rollback();
52
+ throw;
53
+ }
54
+ }
55
+ ```
56
+
57
+ Dispose 幂等,未 Commit 时自动回滚。事务内异步操作串行执行;不要在同一个连接/
58
+ 事务上 `Task.WhenAll`。取消、超时和异常必须传播,不能吞掉后继续 Commit。
59
+
60
+ ## 性能与跨库
61
+
62
+ - 显式选择字段,分页和流式读取,避免无界 `ToList()`。
63
+ - BulkInsert 会按可用客户端选择原生实现并回退多行 INSERT;不同数据库必须实测。
64
+ - 官网性能数字仅是特定环境参考,不能作为目标环境承诺。
65
+ - 查询缓存 Key 必须包含 SQL 参数值;业务写后考虑失效。
66
+ - 读写分离在“写后立刻读”和事务内强制读主。
67
+ - 分片使用稳定 Hash;不能使用进程随机化的 `string.GetHashCode()`。
68
+
69
+ ## 验收
70
+
71
+ - 至少在目标数据库 Provider 运行定向测试,不用 MySQL 结果宣称 Oracle/达梦通过。
72
+ - 覆盖 NULL、DateTime、decimal、Guid、enum、byte[] 和分页边界。
73
+ - 覆盖事务提交/回滚、唯一冲突、超时、取消和连接故障。
74
+ - BulkInsert/Upsert 核对受影响行、Identity 跳过、唯一键和重试副作用。
75
+ - 读写分离覆盖从库故障、写后读主和降级。
76
+ - CodeFirst/索引变更在隔离库验证,不直接对生产执行破坏性重建。