@microi.net/cli 5.2.6 → 5.2.8
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.
- package/.codebuddy-plugin/marketplace.json +2 -2
- package/.codebuddy-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.workbuddy-plugin/marketplace.json +2 -2
- package/.workbuddy-plugin/plugin.json +1 -1
- package/assets/build-meta.json +5 -5
- package/cordis.patch.yml +1 -1
- package/package.json +1 -1
- package/scripts/mcp-server.js +59 -59
- package/scripts/microi-cli.js +52 -29
- package/scripts/microi-skills.meta.json +221 -221
- package/skills/.microi-skills-version.json +2 -2
- package/skills/.progressive-disclosure-manifest.json +95 -95
- package/skills/ai-engine/SKILL.md +12 -4
- package/skills/app-store/SKILL.md +41 -20
- package/skills/message-notification/SKILL.md +8 -1
- package/skills/microi-client-frontend/SKILL.md +1 -1
- 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 +1 -1
- 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 +2 -2
- package/skills/microi-docs-coverage/references/capability-map.md +2 -1
- package/skills/microi-form-layout/SKILL.md +6 -6
- package/skills/microi-frontend-sdk/SKILL.md +6 -6
- package/skills/microi-sso/SKILL.md +1 -1
- package/skills/microi-sso/references/acceptance.md +1 -1
- package/skills/microi-sso/references/configuration-and-security.md +1 -1
- package/skills/microi-system-delivery/SKILL.md +2 -2
- package/skills/microi-system-delivery/references/progressive-01-/346/240/207/345/207/206/345/267/245/344/275/234/346/265/201.md +1 -1
- package/skills/microi.v8.js +1 -1
- package/skills/system-observability/SKILL.md +25 -7
- package/skills/translate-engine/SKILL.md +3 -0
- package/skills/ui-design/SKILL.md +1 -1
- package/skills/v8-api-config/SKILL.md +31 -9
- package/skills/v8-cache-pattern/SKILL.md +304 -289
- package/skills/v8-file-upload/SKILL.md +11 -8
- 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 +1 -1
- package/skills/v8-menu-buttons/SKILL.md +1 -1
- package/skills/v8-menu-buttons/references/progressive-01-2-/346/214/211/351/222/256/345/257/271/350/261/241-schema.md +1 -1
- package/skills/v8-mongodb/SKILL.md +58 -18
- package/skills/v8-mq-mqtt/SKILL.md +130 -109
- package/skills/v8-mq-mqtt/references/mqtt-production.md +3 -2
- package/skills/v8-mq-mqtt/scripts/check-mqtt-skill-coverage.mjs +14 -16
- package/skills/v8-saas-multi-tenant/SKILL.md +3 -0
- package/skills/v8-security/SKILL.md +10 -6
- package/skills/v8-table-event/SKILL.md +1 -1
- 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 +1 -1
- package/skills/v8-utilities/SKILL.md +1 -1
- package/skills/v8-utilities/references/platform-http-routes.md +4 -2
- package/skills/v8-utilities/references/server-api-index.md +31 -10
- package/skills/v8-workflow/SKILL.md +1 -1
- package/skills/workspace-conventions/SKILL.md +1 -1
|
@@ -21,14 +21,14 @@ description: Microi 应用商城开发、打包、安装和升级规范。用于
|
|
|
21
21
|
- 有官方 MCP 权限时,固定使用 `microi_itdos`(`https://api.itdos.com`、`OsClient=iTdos`)更新官方母版、制作并发布对应应用,按内容哈希/包版本回读后,再由目标租户 MCP 安装或更新。无官方权限时只通过当前用户自己的 MCP/Manifest 更新其数据库并回读,不得假借通用升级器越权发布官方应用。
|
|
22
22
|
- `Microi.Upgrade` 只保留应用商城/安装器启动前必需的核心物理兼容或协议迁移,并要求持久化版本门、共享租约、幂等、失败不推进版本。禁止每次启动对每个租户重跑不断增长的历史迁移清单。
|
|
23
23
|
- 平台通用缺陷的交付证据必须分开记录:源码修复、官方母版资源、商城包发布后回读、目标租户后台安装任务、目标租户资源回读和真实 UI/接口验收;其中任一步未完成都不能笼统称为“已发布并安装”。
|
|
24
|
-
- 任何计划让全部吾码租户通过“安装/更新官方应用”获得的标准字段、布局、菜单、页面或种子数据,必须先在官方 `microi_itdos`
|
|
25
|
-
- 同一标准能力若同时属于基础 SaaS
|
|
24
|
+
- 任何计划让全部吾码租户通过“安装/更新官方应用”获得的标准字段、布局、菜单、页面或种子数据,必须先在官方 `microi_itdos` 主租户创建并回读,再从该主租户按精确菜单/表资源导出新版包、单调递增应用版本并发布。包正文以 `PackageHdfsPath + PackageSha256 + PackageSize` 为事实源;`AppPakcet` 只作旧版读取兼容,验证完成后应为空。禁止先只在客户/子租户补字段,再用本地手工 JSON 冒充官方母版;客户验证应发生在官方包发布之后。
|
|
25
|
+
- 同一标准能力若同时属于基础 SaaS 空库包和独立官方应用(例如系统设置、系统账号),两条交付链都要更新:基础包保证新租户初始化完整,独立应用保证存量租户可增量安装。表、字段和初始化模板可按这两个目标分别交付,但同一个 Managed ApiEngineKey 必须只有一个官方包所有者,禁止 SaaS、Store 与独立应用重复携带后互相覆盖。发布后分别核对 `PackageInfo.Version`、物理列、`diy_field` 布局节点、接口引擎单一归属、商城行 `AppVersion` 和 HDFS 包指针/下载哈希,不能用其中一条替代另一条。
|
|
26
26
|
|
|
27
27
|
## 吾码创建人开发时的强制发布闭环
|
|
28
28
|
|
|
29
29
|
- 每次任务先检查工作区根的 `Microi.Server/Microi.net/`。只有目录存在且 `rg --files Microi.Server/Microi.net` 能找到至少一个真实源码文件时,才确认当前是吾码创建人在官方完整源码工作区开发;空目录不算,且不要求本次修改位于该目录。确认后,对任意目录中的平台基础能力执行修改、构建或交付时,官方应用数据包都不是“以后再补”的附加产物,而是本次实现的组成部分。目录缺失或为空时按普通用户工作区处理;纯审查、解释或诊断仍保持只读。
|
|
30
|
-
- 触发资源包括系统设置、表、字段、Tab
|
|
31
|
-
- 强制闭环依次包含:①源码和定向测试;②通过绑定 `https://api.itdos.com + OsClient=iTdos` 的 `microi_itdos` 更新并回读官方母版资源;③从母版导出或按受审计发布契约生成本地应用包,单调提升包版本并核对资源数量、版本和 SHA-256;④发布对应官方 Platform
|
|
30
|
+
- 触发资源包括系统设置、表、字段、Tab、菜单、权限、接口引擎、事件、数据源、页面、打印、工作流、任务、平台内置微服务和可幂等种子数据。开始修改时就确定资源归属:租户开通、启动投影与基础空库归 `app.microi.saas-engine`;用户偏好、个人资料及其租户 Hook 归 `app.microi.sys_user`;租户系统设置编排及其 Hook 归 `app.microi.sys-config`;表单引擎归 `app.microi.form-engine`;模块引擎归 `app.microi.module-engine`;应用商城归 `app.microi.store`。同一能力跨多个包时逐包更新,但同一 Managed ApiEngineKey 仍须单一归属。
|
|
31
|
+
- 强制闭环依次包含:①源码和定向测试;②通过绑定 `https://api.itdos.com + OsClient=iTdos` 的 `microi_itdos` 更新并回读官方母版资源;③从母版导出或按受审计发布契约生成本地应用包,单调提升包版本并核对资源数量、版本和 SHA-256;④发布对应官方 Platform 应用;⑤重新读取商城行的小型 HDFS 指针,用公有下载或受权私有下载取得原始 JSON,核对 `Published/IsApprove`、`AppVersion`、`PackageInfo.Version`、UTF-8 字节数、SHA-256 和资源正文;⑥立即做一次同输入幂等重跑,确认无重复升版或漂移。任务还指定目标租户时,再安装/更新并等待后台任务 `Succeeded` 后回读真实资源。
|
|
32
32
|
- 本地包文件、生成器成功、单元测试通过、返回 TaskId 或 HTTP 200 都不能代替官方主数据库与商城回读。`.resource-sync-base` 只能在官网发布后逐项哈希一致时由同步器推进,不得与本地候选一起手工修改。若官方身份、MCP 登录或发布门禁失效,必须保留准确的未发布边界并修复链路;不得把本地 JSON 宣称为“其它吾码用户已经可以安装”。
|
|
33
33
|
- 应用包不得携带真实地图 Key、Token、连接串或其它租户秘密。浏览器供应商 Key 等配置只交付字段/设置模板和安全读取能力,实际值由每个目标租户在安装后自行填写。
|
|
34
34
|
|
|
@@ -43,9 +43,10 @@ description: Microi 应用商城开发、打包、安装和升级规范。用于
|
|
|
43
43
|
## 接口引擎资源所有权(强制)
|
|
44
44
|
|
|
45
45
|
- 新发布包必须声明 `ResourcePolicies.ApiEngines`,不得再依赖“同 Key 直接覆盖”。官方不可随租户修改的核心使用 `{ Ownership:'Application', UpgradePolicy:'Managed' }`;提供给租户改业务的 Hook 使用 `{ Ownership:'Tenant', UpgradePolicy:'CreateIfMissing' }`。
|
|
46
|
-
-
|
|
46
|
+
- 发布器从上一版安装包正文的 `SysApiEngines` 计算 `BaseHash`;正文可能来自已验证的 HDFS 指针或旧版 `AppPakcet`。导入成功后把本版摘要写入 `sys_microistoreversion.InstallResult.ResourceState.ApiEngines`。普通/社区应用仍按 Base/Local/Incoming 三方保护:`Local == Base` 才更新,`Local != Base && Local != Incoming` 必须冲突回滚。唯一覆盖例外是从固定 `https://api.itdos.com + iTdos` 实时回读并校验为官方 `ApplicationType=Platform` 的应用:其中 `Ownership=Application + UpgradePolicy=Managed` 属于平台发行物,安装/更新按包覆盖本地差异;离线包、自报官方、非 Platform 来源都不能获得该权限。
|
|
47
47
|
- `CreateIfMissing` 只在目标 Key 不存在时创建,存在时不得对齐 Id、源码、启用状态或其它字段。扩展模板发布后即归租户维护;后续版本禁止把同一 Key 改回 `Managed` 接管,确需新的官方核心时发布新 Key 并显式迁移。
|
|
48
|
-
- 官方功能采用“Managed 核心 + CreateIfMissing Hook”。核心只提供稳定协议和默认行为,并在可信官方 Platform 包更新时覆盖升级;客户日志、写表、通知和业务动作放 Hook,并以稳定 `EventId`、唯一约束或 outbox 幂等。`CreateIfMissing` 一旦交给租户维护,即使后续官方包误改为 Managed 也必须冲突回滚。
|
|
48
|
+
- 官方功能采用“Managed 核心 + CreateIfMissing Hook”。核心只提供稳定协议和默认行为,并在可信官方 Platform 包更新时覆盖升级;客户日志、写表、通知和业务动作放 Hook,并以稳定 `EventId`、唯一约束或 outbox 幂等。`CreateIfMissing` 一旦交给租户维护,即使后续官方包误改为 Managed 也必须冲突回滚。
|
|
49
|
+
- 每个官方包内的接口引擎源码顶部都必须有醒目所有权提示。Managed 提示必须写明所属官方应用、从可信官方源安装/更新/重新安装会恢复官方代码,并指向该应用的 CreateIfMissing Hook;CreateIfMissing 提示必须写明首次创建后归租户维护、官方升级不得覆盖。官方 SSO、登录、通知等核心在安全阶段调用 Hook 时,只传脱敏上下文,禁止传 Token、Secret、密码或原始协议断言。
|
|
49
50
|
- 历史包未声明策略时只能按旧兼容流程安装;重新发布时发布器必须生成策略。验收至少覆盖首次安装、可信官方 Managed 本地有差异仍覆盖、普通应用核心差异冲突回滚、Hook 被改后保持原样、重复安装、两节点竞态,以及官方发布数据库连 `ValidateOnly` 也禁止执行安装器。
|
|
50
51
|
|
|
51
52
|
## 安装流程
|
|
@@ -57,9 +58,11 @@ description: Microi 应用商城开发、打包、安装和升级规范。用于
|
|
|
57
58
|
5. `PostSchema` 完成后,在独立 `ScheduleJobs` checkpoint 中幂等安装定时任务并回读 Quartz 运行元数据。
|
|
58
59
|
6. 写入成功后刷新共享缓存版本。
|
|
59
60
|
7. 回读表、字段、引擎、菜单、权限、页面、定时任务等关键资源。
|
|
60
|
-
8. 做 HTTP、UI 和权限冒烟;全部成功后才标记安装版本。
|
|
61
|
-
|
|
62
|
-
安装中断后从 checkpoint 幂等恢复;不能依赖当前 API 节点内存。
|
|
61
|
+
8. 做 HTTP、UI 和权限冒烟;全部成功后才标记安装版本。
|
|
62
|
+
|
|
63
|
+
安装中断后从 checkpoint 幂等恢复;不能依赖当前 API 节点内存。
|
|
64
|
+
|
|
65
|
+
后台任务中心的 `POST /api/BackgroundTask/List` 只返回有界分页的状态、进度、时间和 `HasLog/HasResult` 摘要;日志、结果、参数、可信用户快照与 checkpoint 必须按任务所有权在详情接口按需读取,不能为列表轮询重复返回大字段。
|
|
63
66
|
|
|
64
67
|
## 权限与租户
|
|
65
68
|
|
|
@@ -72,20 +75,25 @@ description: Microi 应用商城开发、打包、安装和升级规范。用于
|
|
|
72
75
|
- 安装次数回传属于非阻塞幂等遥测,不是应用导入事务的成功条件。来源节点返回旧格式 `True`、空响应、非 JSON、业务失败或请求异常时,只能写入带 `OperationId`/`InstallationKey` 的 warning 诊断,不得用 `_error_` 标记或回滚已经成功导入的应用;重试仍须复用同一幂等键。
|
|
73
76
|
- “全部安装/更新”固定只处理 `ApplicationType=Platform` 的官方平台应用中未安装与存在新版本的项目,不得把 UniApp、Web、MicroService 或其它社区/AI 应用整库安装;已是最新版的应用不重新安装。批量计划、子项状态、checkpoint 和进度必须持久化到共享数据库/后台任务,支持多节点抢占、失败重试和重启恢复,不能依赖进程内集合或浏览器状态。
|
|
74
77
|
- 主租户批量维护全部子租户时,前端入口和接口引擎都必须校验主租户上下文及 `Level >= 9999`,再由可信控制面为每个启用子租户创建独立持久后台任务;父任务必须按子任务真实百分比聚合进度,等全部子任务终态后才成功或失败,并在通知中心保留每个租户、阶段和原始失败原因。所有子任务可立即创建,但固定商城工作器必须通过配置租户 Redis 的集群并发租约跨租户串行执行,避免共享物理库并发 DDL/元数据写入死锁;分片幂等任务使用足以覆盖短时死锁和滚动重启的有界重试预算,禁止无限重试。`MaxAttempts` 表示连续失败预算:任一分片成功写入 checkpoint 后必须把 `AttemptCount` 与陈旧 `LastError` 清零,不能让数百个成功分片之间偶发的网络错误按任务生命周期累计并误终结。分片重新入队后必须按 `COALESCE(NextRunTime, CreateTime)` 选取最早就绪任务,禁止只按 `CreateTime` 让最早长任务重复抢占全部分片。商城包属于只读权威数据,可对空响应做有界退避重试,并优先用完整响应的 `Content`、`RawBytes`、HTTP 状态和传输错误诊断;不得把该规则扩展到安装写入请求。目标租户固定商城工作器只允许从受信任官方谱系向更高版本刷新;同版本不同源码、目标端更新版或未知谱系必须失败关闭。历史空库缺少生成实体所需物理列时,导入器须在首次 FormEngine 调用前幂等补齐并回读,不能再把真实表结构错误包装成 `Value cannot be null (source)`。
|
|
75
|
-
- 必须随所有后端版本自动落地的平台基础能力,仍要封装成受信任的官方 Platform 应用包,再由升级器调用统一 `import-microi-store-package` 幂等导入;禁止把表、字段、页面或微服务复制成定制 C#
|
|
78
|
+
- 必须随所有后端版本自动落地的平台基础能力,仍要封装成受信任的官方 Platform 应用包,再由升级器调用统一 `import-microi-store-package` 幂等导入;禁止把表、字段、页面或微服务复制成定制 C# 迁移。`app.microi.saas-engine.json` 可携带基础空库所需的 `mci_system_setting`、`mci_user_external_identity`、默认设置和平台内置微服务;系统账号的 `platform-user-update-preferences`、`platform-user-update-profile`、`platform-user-custom-hook` 只由 `app.microi.sys_user.json` 交付,租户设置的 `platform-tenant-system-settings`、`platform-system-settings-custom-hook` 只由 `app.microi.sys-config.json` 交付。SaaS/Store 不得保留这些 Key、策略或 RequiredPlatformCapabilities。默认行必须使用 `InsertIfMissing + ConfigKey`,只补缺失,不覆盖 `ValueSource=Tenant` 的租户值或租户后来明确关闭的功能。小型平台启动微服务应以 `Source=NotIncluded + Build=DatabaseOnly + StorageMode=db` 随程序集交付并接受 256 文件/5MB、逐文件哈希和无源码门禁,使新租户在 HDFS 故障时仍能打开商城与恢复入口;普通应用安装、源码编辑和文件能力继续失败关闭,不得伪装成全平台健康。
|
|
76
79
|
- 批量任务已经以“一个应用”为外层持久化恢复单元。规模可控的小型官方包应在一个事务中完成,避免对同一包体按 8 个字段反复下载、解析和重新排队;超过字段、表、DDL、流程、随包数据或资产安全阈值的大包继续使用内部 checkpoint 分片。热更新发现旧版批量计划不含 `ApplicationType` 时,必须丢弃旧计划并重新盘点,不能继续安装历史计划中的社区应用。
|
|
77
80
|
- MySQL 宽表触发 65,535 字节行内上限时,只允许把不参与索引的 `varchar` 配置列无损提升为 `mediumtext`,并把类型覆盖持久化到后台任务 checkpoint;索引列和非行宽错误必须失败关闭。发布包对长连接串、密钥、回调地址、域名/白名单等字段应直接使用 `mediumtext`,同时更新 `DiyFields` 与建表 DDL,不能长期依赖安装时猜测。
|
|
78
81
|
- 卸载是破坏性操作,必须明确列出将删除/保留的资源、二次确认并优先软删除/归档业务数据。
|
|
79
82
|
|
|
80
|
-
## 联邦商城源、公开范围与历史版本(强制)
|
|
81
|
-
|
|
82
|
-
- 每个主租户和子租户都可以发布自己的应用;应用行用 `IsPublic` 表达公开范围,缺省/历史空值按公开兼容。公开应用允许未登录来源读取和安装,私有应用只允许来源登录成功后的授权身份读取,列表、详情、版本接口都必须重复执行这一权限判断。
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
83
|
+
## 联邦商城源、公开范围与历史版本(强制)
|
|
84
|
+
|
|
85
|
+
- 每个主租户和子租户都可以发布自己的应用;应用行用 `IsPublic` 表达公开范围,缺省/历史空值按公开兼容。公开应用允许未登录来源读取和安装,私有应用只允许来源登录成功后的授权身份读取,列表、详情、版本接口都必须重复执行这一权限判断。
|
|
86
|
+
- 新版安装包正文不得长期内联在 `sys_microistore.AppPakcet`,也不得随 `mic_data_version.Data` 重复复制。公开应用写入 HDFS 公有桶并记录 `HdfsPublic`,私有应用写入私有桶并记录 `HdfsPrivate`;数据库只保存 `PackageId/PackageHdfsPath/PackageSha256/PackageSize/PackageContentType/PackageFormatVersion/PackageUploadedAt`。`IsPublic` 历史空值按公开兼容,但所有新建应用必须显式落为 `1/0`。
|
|
87
|
+
- 发布顺序必须是“UTF-8 JSON 上传 → HDFS 回读 → 字节数和 SHA-256 一致 → 写入不可变包索引及商城指针 → 以原值 CAS 清空 `AppPakcet`”。普通发布不得仅凭 Redis 命中跳过 HDFS 回读;只有受控历史压缩可复用内容寻址缓存,安装端仍必须独立下载并校验。公开包可通过 FileServer/CDN 公有地址读取;私有包只能由来源后端在当前授权身份下签发短期下载地址,Token、签名 URL 和包正文不得进入浏览器配置、日志或后台任务参数。
|
|
88
|
+
- `mic_data_version` 历史快照保留不可变 `StoreVersionId` 和同一组包指针,因此旧版本仍可精确安装,不再要求 `Data` 内含完整 JSON。导入器先校验快照版本/应用身份,再按指针下载并在解析前核对大小与哈希;指针缺失时才回退旧版内联字段,禁止快照不匹配时退回当前版本。
|
|
89
|
+
- 旧库容量治理使用 `compact-microi-store-packages` 超级管理员持久后台任务:先幂等补齐物理列,再用有界 `Id` 游标逐批处理;每个包都先上传回读,随后 CAS 清理当前行或历史快照。禁止对数 GB `mic_data_version.Data` 执行全表 `LIKE`/包正文计数。逻辑大字段清空后,MySQL 表空间文件是否立即缩小取决于存储引擎;`OPTIMIZE TABLE` 只能在备份完成的维护窗口由管理员另行执行,不能由应用安装或压缩任务自动触发。
|
|
90
|
+
- 商城来源以 `ApiBase + OsClient` 唯一定位。添加来源先只读发现系统标题、验证码策略和公开应用数;需要私有应用时再登录。帐号、密码、Token 不能写浏览器配置或商城来源 JSON;密码只用于本次登录,长会话 Token 以 `MCP/Mobile` 非 PC 客户端签发,并由当前租户后端加密保存到 `mci_system_setting`,浏览器只持有不具备取密能力的凭据 Key。
|
|
91
|
+
- 后端来源代理必须固定已保存的 `ApiBase + OsClient`,拒绝过期 Token、访问密钥会话、非超级管理员、非 HTTPS 外网地址、重定向漂移和超限响应;Token 不得返回浏览器、日志、审计或应用包。退出登录同步删除服务端密文。
|
|
92
|
+
- 商城源业务由 `app.microi.store` 单一拥有的 `platform-marketplace-source`(`Managed`)编排,租户扩展只写 `platform-marketplace-source-hook`(`CreateIfMissing`,默认可执行正文精确为 `return { Code : 1 };`)。登录必须在远端配置读取、密码发送和凭据保存之前执行 `BeforeMarketplaceSourceLogin`;断开必须在删除服务端凭据之前执行 `BeforeMarketplaceSourceDisconnect`。Hook 失败直接阻断操作。Before Hook 仅允许 `Stage / SourceApiEngineKey / Action / SourceId`,不得传 `ApiBase`、远端 `OsClient`、账号、密码、Token、签名地址或凭据密文;协议、加密和密钥隔离继续由可信网关负责。
|
|
93
|
+
- 商城主页面统一承载应用市场、已安装、我发布的应用、安装离线包和来源管理,不能再通过独立菜单或路由割裂上下文。来源增删改启停逐项自动保存;来源管理、详情和复杂配置使用平台统一 `80%` 可拖动大圆角 Dialog,遮罩服从正向开关 `sys_config.FormMaskBlur`,缺失或 `0/false` 默认关闭毛玻璃。
|
|
86
94
|
- 每张应用卡必须显示预览图、公开范围、分类、最新版本、当前租户已安装版本及状态色。来源卡必须显示其公开数和当前授权可访问总数;平台官方发布节点只显示“平台官方应用源”身份标记,不显示安装、更新或重新安装操作。
|
|
87
|
-
- 安装可明确选择 `sys_microistore` 当前版本或 `mic_data_version`
|
|
88
|
-
- 应用详情的版本选择必须服务端分页和搜索,默认每页不超过 20
|
|
95
|
+
- 安装可明确选择 `sys_microistore` 当前版本或 `mic_data_version` 中仍含完整包正文或已验证包指针的历史快照;后台任务在首次取包时必须把计划中的 `AppVersion` 解析为匹配且可安装的不可变 `StoreVersionId`,写入 checkpoint,并在全部后续分片一直传到详情取包。发布方中途升版时继续完成已锁定快照,新版留给下一轮盘点;快照缺失、版本不匹配、身份变化或快照 Id 漂移必须失败关闭,禁止退回易变当前行。实际安装版本写回 `sys_microistoreversion`。回退旧版属于重新安装,不得静默换成最新版。
|
|
96
|
+
- 应用详情的版本选择必须服务端分页和搜索,默认每页不超过 20 条;当前版本固定置顶,历史版本只返回含完整旧包或有效 HDFS 指针的可安装状态。禁止用 `_PageSize:500` 或一次加载全部版本后在浏览器过滤。翻页、搜索与页大小切换都必须保持已选版本语义并显示总数。
|
|
89
97
|
- 商城详情、来源管理等 Teleport 弹层必须使用宿主级固定遮罩,毛玻璃覆盖完整可视区域;标题栏拖动按弹层真实尺寸限制四边,窗口缩放后重新限制,不能依赖固定像素最大位移或允许内容越出视口。
|
|
90
98
|
- “我发布的应用”只读取当前登录用户拥有的记录,可以包含草稿和构建失败项;普通商城列表只读取已发布项。两者必须在服务端按 Owner 和发布状态过滤,不能依赖浏览器过滤后再分页。
|
|
91
99
|
|
|
@@ -144,12 +152,25 @@ description: Microi 应用商城开发、打包、安装和升级规范。用于
|
|
|
144
152
|
- [ ] 缓存刷新后远端 API 与真实 UI 通过
|
|
145
153
|
- [ ] 卸载范围明确、可审计、可恢复或已提示不可恢复
|
|
146
154
|
|
|
147
|
-
## 复盘:商城按钮已到达但依赖接口引擎缺失
|
|
155
|
+
## 复盘:商城按钮已到达但依赖接口引擎缺失
|
|
148
156
|
|
|
149
157
|
- 触发场景:子租户更新应用商城后能够看到“全部安装/更新”,点击却提示 `sys_apiengine` 中不存在按钮调用的接口;继续临时补引擎后,还可能因目标租户缺少批量计划表再次失败。
|
|
150
158
|
- 根因:商城元数据版本、`AppPakcet.PackageInfo.Version` 与真实包正文发生分叉,页面按钮被单独更新;同时应用导入器把接口引擎新增/更新失败只写进 Debug 后继续返回成功,没有做写后回读,批量引擎又依赖未随同一应用包交付的表。
|
|
151
159
|
- 通用规则:按钮及其调用的接口引擎、表和权限必须属于同一个单调版本应用包;任何依赖写入失败或回读内容不一致都要让安装事务失败。可复用的批量状态优先写入平台后台任务 `CheckpointJson`,避免仅为批量编排增加未交付的租户表。商城行版本、包内版本和包内容哈希必须同时回读一致,禁止单独提升商城行版本或只更新菜单。
|
|
152
|
-
- 自动化检查:应用包契约测试必须从按钮代码提取接口 Key,断言包内存在启用且配置正确的引擎并与独立源码逐字一致;导入器测试覆盖新增失败、更新失败、缓存清理后回读缺失和源码不一致均返回 `Code=0`;真实子租户更新后回读 `sys_menu + sys_apiengine + 后台任务`,再实际执行一次“无需更新”和至少一个安装/更新计划。
|
|
160
|
+
- 自动化检查:应用包契约测试必须从按钮代码提取接口 Key,断言包内存在启用且配置正确的引擎并与独立源码逐字一致;导入器测试覆盖新增失败、更新失败、缓存清理后回读缺失和源码不一致均返回 `Code=0`;真实子租户更新后回读 `sys_menu + sys_apiengine + 后台任务`,再实际执行一次“无需更新”和至少一个安装/更新计划。
|
|
161
|
+
|
|
162
|
+
## 复盘:新版前端先启动、基础包却遗漏登录菜单依赖
|
|
163
|
+
|
|
164
|
+
- 触发场景:租户先升级新版前后端,登录后路由初始化固定调用 `/apiengine/platform-sys-menu`;目标库此前没有该接口。应用商城包只补了 `platform-background-task`,而菜单接口仍由安装顺序靠后的 SaaS 包顺带携带;启动完整性检查也只验证后台任务接口,于是数据库版本和商城版本都显示最新,但用户在进入应用商城之前已经因 `NoExistData sys_apiengine` 全站不可用。
|
|
165
|
+
- 根因:把单个已修复依赖误当成完整的启动依赖集合,包资源闭包、`NeedRefresh` 完成判定和安装后强回读没有使用同一清单;发布验收只覆盖已有目标租户,未覆盖“新版二进制 + 历史库恰好缺少某一启动接口”的升级排列。
|
|
166
|
+
- 通用规则:凡是登录、菜单构建、恢复入口或应用商城打开之前必调的表、接口引擎和微服务路由,都属于启动依赖闭包,必须由安装顺序最前的同一个官方 Platform 包原子交付。每项接口必须同时声明固定自定义地址、最低版本、启用/匿名/HTTP 状态、`Managed` 策略、V8 原子能力和包内能力标记;启动完整性检查与安装后回读必须遍历同一依赖清单,任意一项缺失都触发修复且失败不推进版本。其它后置应用携带相同资源只能作兼容副本,不能成为启动正确性的唯一来源。
|
|
167
|
+
- 竞态与验收:前端可对明确的“启动 Managed 资源尚未落库”做不超过一分钟的有界退避,并在耗尽后显示精确包名和最低版本;它不能吞掉鉴权错误、普通网络错误,也不能代替服务端修复。契约测试须逐项删除或降级每个启动依赖,断言包校验、租户完整性判断和安装后回读都失败;真实验收至少覆盖一个历史缺失租户,先证明旧状态会失败,再安装精确商城版本、回读接口源码/地址/策略、执行菜单动作、刷新登录后页面,最后做同版本无操作复跑。
|
|
168
|
+
|
|
169
|
+
## 复盘:应用包切换 HDFS 后旧导入器无法更新自己
|
|
170
|
+
|
|
171
|
+
- 触发场景:商城行与不可变版本快照已经只保存 HDFS 路径、大小和 SHA-256;历史租户仍运行只读取 `AppPakcet` 的导入器。用户尝试先更新“应用商城”以获得新版导入器时,旧导入器从商城源取得空 `AppPakcet`,在 3% 直接报“Package不能为空”,形成更新器无法更新自己的引导死锁。
|
|
172
|
+
- 通用协议:新版导入器请求商城模型时必须显式声明 `PackagePointerMode=HdfsV1`,自行下载一次并校验 UTF-8 字节数与 SHA-256。商城模型面对未声明该能力的旧调用端,允许从同一个受信 HDFS 指针读取并严格校验正文,只在本次响应的 `AppPakcet` 中临时回填;绝对禁止写回 `sys_microistore`、`mic_data_version`、任务参数或检查点。私有包仍必须使用短期授权地址,大小上限、HTTP 状态和摘要任一异常都失败关闭。
|
|
173
|
+
- 发布顺序与验收:先把兼容桥更新到官方商城源的 `get-microi-store-model`,再发布包含新版模型接口、导入器和启动依赖的精确应用商城版本。自动化同时覆盖新版请求零回填、旧请求可安装、摘要/大小不符拒绝、数据库无包正文字段更新;真实历史租户必须保留旧导入器启动第一次正式更新,等待终态成功并回读新版导入器,然后立即同版本复跑为零更新。直接通过 MCP 替换目标导入器只能作为已故障租户的最后恢复手段,不能代替协议兼容性验收。
|
|
153
174
|
|
|
154
175
|
## 复盘:可信后台任务被 StopHttp 提前拦截
|
|
155
176
|
|
|
@@ -103,7 +103,13 @@ await V8.Notification.MarkRead({ All: true });
|
|
|
103
103
|
|
|
104
104
|
## 应用商城交付
|
|
105
105
|
|
|
106
|
-
“消息通知”应用包必须包含 `mic_msgset`、`mic_msg_event_log`、`wx_tpl_msg`、`wx_mp`、`wx_mini_program` 五张结构资源,以及相关菜单、`msg_event`、`msg_internal_list`、`msg_internal_mark_read` 和必要索引。`wx_mp`、`wx_mini_program` 只交付物理表结构与表单字段元数据,不得携带数据集;否则既可能泄露真实公众号/小程序密钥,也会覆盖目标租户配置。`sys_user.WxMpId` 和 `wx_tpl_msg` 会读取 `wx_mp`,漏包会使 `/system/diy-user` 等无关页面在加载 Select 数据源时触发 `GetDiyFieldSqlData` 缺表错误。包内不得包含真实公众号 Token/AppSecret、用户接收人、OpenId、历史发送记录或租户专属 URL。先 `ValidateOnly`,再在全新或缺表目标租户真实安装,回读五张表、应用版本和依赖页面;结构校验不能替代真实安装验收。
|
|
106
|
+
“消息通知”应用包必须包含 `mic_msgset`、`mic_msg_event_log`、`wx_tpl_msg`、`wx_mp`、`wx_mini_program` 五张结构资源,以及相关菜单、`msg_event`、`msg_internal_list`、`msg_internal_mark_read`、`platform-chat-system-message`、`platform-chat-runtime`、`platform-message-notification-custom-hook` 和必要索引。`wx_mp`、`wx_mini_program` 只交付物理表结构与表单字段元数据,不得携带数据集;否则既可能泄露真实公众号/小程序密钥,也会覆盖目标租户配置。`sys_user.WxMpId` 和 `wx_tpl_msg` 会读取 `wx_mp`,漏包会使 `/system/diy-user` 等无关页面在加载 Select 数据源时触发 `GetDiyFieldSqlData` 缺表错误。包内不得包含真实公众号 Token/AppSecret、用户接收人、OpenId、历史发送记录或租户专属 URL。先 `ValidateOnly`,再在全新或缺表目标租户真实安装,回读五张表、应用版本和依赖页面;结构校验不能替代真实安装验收。
|
|
107
|
+
|
|
108
|
+
系统聊天门面 `platform-chat-system-message`(`Managed`)完成平台超级管理员校验后,只转调本应用单一拥有的 `platform-chat-runtime`(`Managed`)。运行时统一编排 `PersistMessage / PersistSystemMessage / PersistAssistantMessage / GetHistoryAndMarkRead / GetUnreadCount / TouchContact / ListContacts / DeleteContact`;Hub/Controller 旧入口只保留 DiyToken 认证、SignalR 投递和 AI 流式协议,不得直连 MongoDB/FormEngine 复制业务。访问密钥会话、空 Token、伪造租户/发送人必须失败关闭。
|
|
109
|
+
|
|
110
|
+
`platform-chat-runtime` 以 `V8.CurrentUser` / `V8.OsClient` 为唯一身份与租户事实源,对“租户 + 稳定 RequestId”生成确定性 Mongo `_id`;只有全部载荷哈希一致才复用旧记录。MongoDB 不参与 `V8.DbTrans`,因此消息/已读/联系人成功后即是已提交事实;SignalR、投影或 After Hook 失败必须保持 `Code=1` 并通过 `DataAppend.HookWarning` / `ProjectionWarnings` 告警,不得伪装未发生而引导盲目重试。调用 `V8.MongoDb.UptFormDataByWhere` / `DelFormDataByWhere` 时必须使用包含当前用户/权威资源边界的非空参数化 `_Where`,规则详见 `../v8-mongodb/SKILL.md`。
|
|
111
|
+
|
|
112
|
+
租户个性化仅写入 `platform-message-notification-custom-hook`(`CreateIfMissing`),默认正文必须精确为 `return { Code : 1 };`。运行时在 `BeforeChatRuntime / AfterChatRuntime` 调用 Hook:Before 失败在 Mongo 写前阻断,After 失败只告警。Hook 只接收 `Stage`、`SourceApiEngineKey`、`Action`、`ActorUserId`、`PeerUserId`、`MessageId`、`MessageType`;正文、头像、OpenId、Token 与其它秘密不得进入租户扩展。三项接口的源码顶部都要保留官方恢复/租户不覆盖提示,并在包合同测试中逐字核对独立源码、包内副本、所有权策略和 HTTP/匿名开关。
|
|
107
113
|
|
|
108
114
|
## 最低验收
|
|
109
115
|
|
|
@@ -113,3 +119,4 @@ await V8.Notification.MarkRead({ All: true });
|
|
|
113
119
|
4. 用户只能查询和标记自己的通知;危险链接、超长正文、跨租户接收人和匿名调用被拒绝。
|
|
114
120
|
5. 公众号/服务号发送主体与小程序跳转目标分别验证,不把 `MiniProgramAppId` 当作模板发送主体。
|
|
115
121
|
6. 源码定向测试、后端编译、远端 MCP 回读、真实浏览器点击和商城安装/校验分别报告;未执行的生产发布不得写成已上线。
|
|
122
|
+
7. 聊天空 Token/访问密钥/伪造租户失败关闭;相同 `RequestId` 并发只有一份 Mongo 事实,不同载荷冲突拒绝;已持久后 SignalR/After Hook 失败仍返回成功并可回读。
|
|
@@ -44,7 +44,7 @@ description: Microi.Client 源码架构指南。用于修改 Microi.Client Vue
|
|
|
44
44
|
---
|
|
45
45
|
|
|
46
46
|
<!-- /microi-progressive:chunk -->
|
|
47
|
-
<!-- microi-progressive:chunk id=microi-client-frontend-002 sha256=
|
|
47
|
+
<!-- microi-progressive:chunk id=microi-client-frontend-002 sha256=ca442fa8a4990040aa7172dd37b49437bc6de0c9b1f88d889a30f5e936321aa1 -->
|
|
48
48
|
## 2. 表单引擎三层结构
|
|
49
49
|
|
|
50
50
|
### 模块级跨端视图
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> 按需读取;本文件由 SKILL.md 的原章节无损拆分。
|
|
4
4
|
|
|
5
|
-
<!-- microi-progressive:chunk id=microi-client-frontend-005 sha256=
|
|
5
|
+
<!-- microi-progressive:chunk id=microi-client-frontend-005 sha256=0ffafbd99fc0ee478db91200bfc3645c288f20d45120cd7413fb00ac3fbd8952 -->
|
|
6
6
|
## 3. 动态按钮系统
|
|
7
7
|
|
|
8
8
|
按钮配置来自 `sys_menu`:
|
|
@@ -149,7 +149,7 @@ Microi 的 AI 应用与应用商城只有一个主数据源:`sys_microistore`
|
|
|
149
149
|
- 同一份 ApiKey/Token 摘要在 Overview 与 AI 页面复用同一个组件;Token 额度统一展示“总量/Total”,不要把总量写成“赠送”。复制密钥必须有明确成功或失败提示,并提供 Clipboard API 不可用时的兼容复制。
|
|
150
150
|
|
|
151
151
|
<!-- /microi-progressive:chunk -->
|
|
152
|
-
<!-- microi-progressive:chunk id=microi-client-frontend-013 sha256=
|
|
152
|
+
<!-- microi-progressive:chunk id=microi-client-frontend-013 sha256=8f876b46e20dce5020e17f87ac6f9acfb37c908ab27f7c9568d59e9e7a00d3b2 -->
|
|
153
153
|
## 浏览器访问密钥路由
|
|
154
154
|
|
|
155
155
|
- 固定看板免登录使用常量匿名路由 `/access-login`,密钥使用 `microi_ak_` 前缀,完整链接格式为 `{Microi.Client前端WebBase}/?OsClient={当前租户}#/access-login?access_key={密钥}&redirect={encodeURIComponent后的站内Hash路由}`。例如目标路由 `/mic/data-dashboard/preview/01KK988A0YPHKAM8SF216917HX` 必须生成 `redirect=%2Fmic%2Fdata-dashboard%2Fpreview%2F01KK988A0YPHKAM8SF216917HX`。生成器只复制当前 `OsClient`,不能把其它页面查询参数带进凭据链接,也不能把 API Server 当成前端 WebBase。
|
|
@@ -159,7 +159,7 @@ Microi 的 AI 应用与应用商城只有一个主数据源:`sys_microistore`
|
|
|
159
159
|
- 兑换通过 `POST /api/SysUserAccessKey/Exchange` 的 JSON Body 完成。响应头中的短期 Token 继续交给平台统一请求层保存和轮换。
|
|
160
160
|
- 创建界面默认按页面名称勾选,也支持粘贴完整页面网址自动解析;不能要求普通用户手写路由和物理表名。页面/数据均可选择“全部已授权”,内部值为 `*`,含义只是取消密钥层二次白名单,仍与目标帐号实时菜单、表单和行权限取交集。接口引擎与数据源引擎 Key 仍必须准确选择。
|
|
161
161
|
- `_AccessKeySession=true` 且页面为准确白名单时只允许清单路径;页面范围为 `*` 时才加载目标帐号实时可用的动态路由,以便全部已授权菜单可访问。该前端限制只是体验和泄露面收窄,服务端仍必须校验 API、表和引擎权限。
|
|
162
|
-
- 全部页面模式会调用 `/
|
|
162
|
+
- 全部页面模式会调用 `/apiengine/platform-sys-menu?Action=GetSysMenuStep`,服务端只能在 `page:open + AllowedRoutes=*` 时放行;准确页面模式不得为了省事请求完整菜单树。页面渲染过程中使用 `FormEngineKey`、`TableId`、`ModuleEngineKey` 或 `_SysMenuId` 的请求都必须能被服务端映射到同一份表范围,不能通过换参数名绕过,也不能把合法的菜单 Id 请求误判为缺少表引用。
|
|
163
163
|
- 列表和表单会把表 Key 或菜单 Id 放进动态友好地址,例如 `/api/FormEngine/GetTableData-{table-key}` 和 `/api/FormEngine/GetFormData-{table-key}`。访问密钥服务端必须先把这些地址归一化为标准 action,再按 `form:read/form:write` 对 URL 后缀与请求体中的表/菜单引用做一致性校验,并把菜单 Id 映射回绑定的 `DiyTableId` 校验数据范围;不能要求前端为了密钥会话退回另一套 URL,也不能对整个 `FormEngine` Controller 无条件放行。
|
|
164
164
|
- 不要因为底层帐号是管理员而在访问密钥会话展示控制面入口或触发控制面预加载。`_AccessKeySession=true` 时,密码显示、密钥管理、表/字段/菜单设计、缓存/服务器管理、查看或踢出其它终端等功能必须保持不可用;后台任务中心最多读取和管理当前用户自己的任务。
|
|
165
165
|
- `/access-login` 必须在普通 SSO 发现之前直接放行,兑换最多等待 20 秒并给出明确错误,不能让页面永久停在“正在自动登录”。
|
|
@@ -40,6 +40,7 @@ Markdown。第一列是相对 `microi.doc/docs/doc/` 的路径;第二列 Skill
|
|
|
40
40
|
| `system-engine/app-store.md` | app-store | 应用包、安装、升级和回滚 |
|
|
41
41
|
| `system-engine/databases.md` | dos-orm, v8-sql-query, microi-deployment | 扩展数据库与迁移 |
|
|
42
42
|
| `system-engine/datasource-engine.md` | datasource-engine | 数据源定义、执行和供数 |
|
|
43
|
+
| `system-engine/cache.md` | v8-cache-pattern, v8-saas-multi-tenant | L1/L2 架构、租户 Redis、Pub/Sub 失效、V8 安全代理与 Redis 管理器 |
|
|
43
44
|
| `system-engine/file-manage.md` | v8-file-upload, microi-client-frontend | 文件柜、公私桶管理、在线预览、回收站、跨平台与 MinIO 同步 |
|
|
44
45
|
| `system-engine/job.md` | job-engine | 调度、后台任务和分布式恢复 |
|
|
45
46
|
| `system-engine/micro-app.md` | microi-microservice, microi-ai-application | 微服务/AI 前端应用的工程架构与交付 |
|
|
@@ -47,7 +48,7 @@ Markdown。第一列是相对 `microi.doc/docs/doc/` 的路径;第二列 Skill
|
|
|
47
48
|
| `system-engine/microi-ui.md` | microi-ui | Microi.UI 组件和主题 |
|
|
48
49
|
| `system-engine/message-notification.md` | message-notification | 平台内部消息、SignalR 与多通道通知 |
|
|
49
50
|
| `system-engine/module-engine.md` | module-engine, v8-menu-buttons, v8-template-engine, microi-mobile-app-quality | 菜单统计、模块指标、复合列、移动卡片、按钮角标和页面入口 |
|
|
50
|
-
| `system-engine/mq.md` | v8-mq-mqtt | RabbitMQ
|
|
51
|
+
| `system-engine/mq.md` | v8-mq-mqtt | RabbitMQ 租户连接、队列规范化、事务发布、消费确认、有限重试、幂等与多节点运行 |
|
|
51
52
|
| `system-engine/mqtt-engine.md` | v8-mq-mqtt | MQTT Broker、SaaS 认证、Topic ACL、V8 事件、设备路由、下行与生产部署 |
|
|
52
53
|
| `system-engine/page-engine.md` | page-engine | 界面引擎 JSON |
|
|
53
54
|
| `system-engine/print-engine.md` | print-engine, v8-frontend-events | 服务端模板打印与蓝牙直连边界 |
|
|
@@ -33,7 +33,7 @@ Microi 吾码低代码提供 **三种** 表单分组能力,但每种都有明
|
|
|
33
33
|
- 配置表采用“表级 Tab + Tab 内 CollapseGroup”时,CollapseGroup 必须与成员字段写入同一个 `Tab`,并用连续 `Sort` 保证作用范围在下一个布局节点前结束。发布前必须打开真实编辑表单验证,不能只凭元数据字符串判断布局成功。
|
|
34
34
|
|
|
35
35
|
<!-- microi-progressive:begin -->
|
|
36
|
-
<!-- microi-progressive:chunk id=microi-form-layout-000 sha256=
|
|
36
|
+
<!-- microi-progressive:chunk id=microi-form-layout-000 sha256=79fcf1787c0fbdbe51363f25fcf72b060b714eed9cbc5593760f9080cff48e31 -->
|
|
37
37
|
## 1. 三种分组能力速查
|
|
38
38
|
|
|
39
39
|
| 能力 | 存储位置 | 控件 | 核心作用 | 适用场景 |
|
|
@@ -44,7 +44,7 @@ Microi 吾码低代码提供 **三种** 表单分组能力,但每种都有明
|
|
|
44
44
|
| **D. 不分组(默认平铺)** | 无 | — | 全部字段在第一屏 | 总有效表单行 ≤ 6、没有复杂控件,且没有必须强调的业务分组 |
|
|
45
45
|
|
|
46
46
|
<!-- /microi-progressive:chunk -->
|
|
47
|
-
<!-- microi-progressive:chunk id=microi-form-layout-001 sha256=
|
|
47
|
+
<!-- microi-progressive:chunk id=microi-form-layout-001 sha256=eb8f9a306f46484217f8fc6094a7dc8ea1f5315187430329d79fa71134c3b2da -->
|
|
48
48
|
## 2. 黄金决策流程(AI 必须按此顺序判断)
|
|
49
49
|
|
|
50
50
|
### 2.1 先算“有效表单行”,禁止只数字段
|
|
@@ -95,7 +95,7 @@ Q1: 核心可见字段数、子表和强任务域?
|
|
|
95
95
|
| 工作流审批表(≤10 字段) | D. 不分组 | 禁止使用 Tab |
|
|
96
96
|
|
|
97
97
|
<!-- /microi-progressive:chunk -->
|
|
98
|
-
<!-- microi-progressive:chunk id=microi-form-layout-002 sha256=
|
|
98
|
+
<!-- microi-progressive:chunk id=microi-form-layout-002 sha256=119311f1ec30de83c323a0604c0aefb12676da7c421fc459d1555b0a1a7858d0 -->
|
|
99
99
|
## 4. AI 生成表单布局的标准动作
|
|
100
100
|
|
|
101
101
|
### 4.1 必做顺序
|
|
@@ -137,7 +137,7 @@ Q1: 核心可见字段数、子表和强任务域?
|
|
|
137
137
|
V8 事件中可用 `V8.HideFormTab('tabId')` / `V8.ShowFormTab('tabId')` / `V8.ClickFormTab('tabId')` 动态控制 Tab 显隐和默认选中。
|
|
138
138
|
|
|
139
139
|
<!-- /microi-progressive:chunk -->
|
|
140
|
-
<!-- microi-progressive:chunk id=microi-form-layout-003 sha256=
|
|
140
|
+
<!-- microi-progressive:chunk id=microi-form-layout-003 sha256=02934831afff7bd9065406b074f5780cb5686ccdb63fcb350b8c409dad315c74 -->
|
|
141
141
|
## 5. 必填与禁止
|
|
142
142
|
|
|
143
143
|
### 5.1 必填
|
|
@@ -167,7 +167,7 @@ V8 事件中可用 `V8.HideFormTab('tabId')` / `V8.ShowFormTab('tabId')` / `V8.C
|
|
|
167
167
|
- ❌ **禁止**用普通新增字段或通用表单数据写入创建布局节点;这类路径可能对目标业务表执行物理 DDL。
|
|
168
168
|
|
|
169
169
|
<!-- /microi-progressive:chunk -->
|
|
170
|
-
<!-- microi-progressive:chunk id=microi-form-layout-004 sha256=
|
|
170
|
+
<!-- microi-progressive:chunk id=microi-form-layout-004 sha256=5de749261dec123edd0fc9186188cb90887892490298dad9d6944670457177df -->
|
|
171
171
|
## 6. 验收清单
|
|
172
172
|
|
|
173
173
|
修改或新建表单布局后,AI 必须按以下顺序验收:
|
|
@@ -188,7 +188,7 @@ V8 事件中可用 `V8.HideFormTab('tabId')` / `V8.ShowFormTab('tabId')` / `V8.C
|
|
|
188
188
|
通常跳过这些运行态事件;未完成这一步不得直接判定为 Microi.Client 渲染缺陷。
|
|
189
189
|
|
|
190
190
|
<!-- /microi-progressive:chunk -->
|
|
191
|
-
<!-- microi-progressive:chunk id=microi-form-layout-005 sha256=
|
|
191
|
+
<!-- microi-progressive:chunk id=microi-form-layout-005 sha256=941d45f4389751946df34ec388e28adbbe9965d6ad9f637f48fd35cc6aca5065 -->
|
|
192
192
|
## 9. 与其他 Skill 的关系
|
|
193
193
|
|
|
194
194
|
- 字段创建流程:`v8-table-event/SKILL.md` 写 InFormV8 / SubmitFormV8 等。
|
|
@@ -10,7 +10,7 @@ description: Microi 前端 SDK 使用规范,适用于 Vue 3、uni-app、H5、P
|
|
|
10
10
|
所有 Vue 3 前端项目都应使用 `microi.skills/microi.v8.js` 作为统一的 Microi 前端 SDK。新项目不要复制旧版 Vue2/Vuex 请求封装,也不要重新手写 token、上传、文件 URL、ApiEngine 或 FormEngine 层。
|
|
11
11
|
|
|
12
12
|
<!-- microi-progressive:begin -->
|
|
13
|
-
<!-- microi-progressive:chunk id=microi-frontend-sdk-000 sha256=
|
|
13
|
+
<!-- microi-progressive:chunk id=microi-frontend-sdk-000 sha256=4b1d4f626b1c4de344339a2fba6b2eaf48e9e5a018c2faa1f7480b90254a4cfb -->
|
|
14
14
|
## 必须采用的模式
|
|
15
15
|
|
|
16
16
|
将 SDK 复制到项目源码目录,通常是:
|
|
@@ -56,7 +56,7 @@ export function createApp() {
|
|
|
56
56
|
页面和业务接口模块应从项目请求模块导入已配置实例或薄封装函数,不要直接从标准 skill 文件导入。
|
|
57
57
|
|
|
58
58
|
<!-- /microi-progressive:chunk -->
|
|
59
|
-
<!-- microi-progressive:chunk id=microi-frontend-sdk-001 sha256=
|
|
59
|
+
<!-- microi-progressive:chunk id=microi-frontend-sdk-001 sha256=c418c6c9e6846d2ce4db04501520036e2c6b0f162c282d6e099e802c9b83f72d -->
|
|
60
60
|
## 必须委托 SDK 的能力
|
|
61
61
|
|
|
62
62
|
- `ApiEngine.Run`:直接调用 `/apiengine/{key}` 时使用 `V8.ApiEngine.Run(key, data)`。
|
|
@@ -71,7 +71,7 @@ export function createApp() {
|
|
|
71
71
|
`Microi.Client` 主后台运行时已内置前后端同构的 `V8.Http.Get/Post/Patch` 及对应 Response 方法;表单事件、按钮 V8 等宿主前端新代码必须优先使用 `V8.Http`,旧 `V8.Post/Get` 仅作兼容保留,其参数和兼容规则以 `v8-http-integration/SKILL.md` 为准。独立项目使用本 SDK、且不在主后台 V8 宿主中时,才使用 SDK 自身的小写 `V8.get/post`、`ApiEngine`、`FormEngine`;不要把它们与宿主旧版大写 `V8.Post/Get` 混为一谈,也不要假设浏览器可以绕过第三方接口的 CORS。
|
|
72
72
|
|
|
73
73
|
<!-- /microi-progressive:chunk -->
|
|
74
|
-
<!-- microi-progressive:chunk id=microi-frontend-sdk-002 sha256=
|
|
74
|
+
<!-- microi-progressive:chunk id=microi-frontend-sdk-002 sha256=54b302bfe2a8830a3043ae7804ca775d6159453bea0cfdeac61c3b97d36466ed -->
|
|
75
75
|
## 登录与验证码封装
|
|
76
76
|
|
|
77
77
|
SDK 或项目请求模块必须提供登录所需的系统配置和验证码薄封装,不要让页面散落手写。
|
|
@@ -120,7 +120,7 @@ AI 生成的前端微服务不能假定永远在主平台 iframe/micro-app 宿
|
|
|
120
120
|
- 宿主额外传入 `permissionContext={sysMenuId,moduleEngineKey,diyTableId}`。SDK/服务层需要访问 FormEngine 时使用真实授权 `moduleEngineKey`;该对象不能代替后端权限,也不能成为放宽匿名接口的理由。
|
|
121
121
|
|
|
122
122
|
<!-- /microi-progressive:chunk -->
|
|
123
|
-
<!-- microi-progressive:chunk id=microi-frontend-sdk-003 sha256=
|
|
123
|
+
<!-- microi-progressive:chunk id=microi-frontend-sdk-003 sha256=fd0dbc19f767d1b69c41582a99d2c578c2e4ee8c871df89fd67ed054641d1931 -->
|
|
124
124
|
## 请求头规则
|
|
125
125
|
|
|
126
126
|
SDK 的 `buildHeaders` 必须集中处理所有请求头,不能让页面、业务 wrapper 或上传逻辑各自拼接租户和鉴权头。
|
|
@@ -132,7 +132,7 @@ SDK 的 `buildHeaders` 必须集中处理所有请求头,不能让页面、业
|
|
|
132
132
|
- 验收时检查真实网络请求:不得出现 `osclient: demo, demo`、`Authorization: Bearer xxx, Bearer xxx` 这类逗号合并值。
|
|
133
133
|
|
|
134
134
|
<!-- /microi-progressive:chunk -->
|
|
135
|
-
<!-- microi-progressive:chunk id=microi-frontend-sdk-004 sha256=
|
|
135
|
+
<!-- microi-progressive:chunk id=microi-frontend-sdk-004 sha256=f5644fc45280e53988d1eed432e57afc2c56fc58b1232505950359219b5220d2 -->
|
|
136
136
|
## 上传规则
|
|
137
137
|
|
|
138
138
|
`V8.uploadFile` 是 Microi 前端唯一允许的上传入口。SDK 实现必须:
|
|
@@ -150,7 +150,7 @@ SDK 的 `buildHeaders` 必须集中处理所有请求头,不能让页面、业
|
|
|
150
150
|
当上传突然报 `移动端文件上传路径不合法!` 时,先检查实际 multipart 表单字段和请求头。在 Microi 移动端/会员 Token 流程中,后端会在 HDFS 上传前校验 `Path`;错误的 `Content-Type` 会导致后端读不到表单字段,并表现为路径错误。
|
|
151
151
|
|
|
152
152
|
<!-- /microi-progressive:chunk -->
|
|
153
|
-
<!-- microi-progressive:chunk id=microi-frontend-sdk-005 sha256=
|
|
153
|
+
<!-- microi-progressive:chunk id=microi-frontend-sdk-005 sha256=ea5ffc6757b73bb3251b34d26b2902674c3a0c7f5277dcf8745e39ff11fe6b56 -->
|
|
154
154
|
## 项目封装规则
|
|
155
155
|
|
|
156
156
|
面向业务页面的函数名要保持稳定。如果已有项目导出 `callEngine`、`formEngineGet`、`getImageUrl`、`parseImages` 或 `uploadFile`,保留这些导出,内部委托给 `V8`。这样既能统一 SDK,又能避免大面积改页面。
|
|
@@ -40,7 +40,7 @@ description: 设计、实现、配置、迁移、发布和验收 Microi 吾码
|
|
|
40
40
|
7. 外部角色、邮箱或昵称不能直接获得管理员权限。默认 `BoundOnly`,JIT 必须显式默认角色、唯一性、回收和审计。
|
|
41
41
|
8. HTTP 200、构建成功、商城任务入队或包可下载都不是完整 SSO 验收。
|
|
42
42
|
9. SSO 业务逻辑必须接口引擎优先:连接投影、绑定/JIT、角色与 Claim 映射、审计、登录完成和租户扩展不得重新写进 Controller。只有协议报文、签名验签、Secret/私钥隔离、一次性票据与 DiyToken 等可信原子可以保留 C#。
|
|
43
|
-
10.
|
|
43
|
+
10. 客户端调用固定应用接口必须优先使用 `/apiengine/{ApiEngineKey}?OsClient=`,让系统日志/监控按真实接口引擎归因;新版宿主即使接口尚未安装也会返回结构化缺失错误。`/api/ApiEngine/Run` 只保留给无法预知 Key 的旧版兼容调用,禁止新增固定业务依赖;同样禁止调用已删除的 `/api/Sso/Capabilities` 等定制路由。
|
|
44
44
|
|
|
45
45
|
## 标准工作流
|
|
46
46
|
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
|
|
44
44
|
## 404 与应用缺失回归
|
|
45
45
|
|
|
46
|
-
- 客户端能力发现和登录完成只允许调用 `/api/ApiEngine/Run
|
|
46
|
+
- 客户端能力发现和登录完成只允许调用 `/apiengine/{ApiEngineKey}?OsClient=`;固定业务不得新增 `/api/ApiEngine/Run` 依赖。
|
|
47
47
|
- 在未安装 `app.microi.sso` 的租户调用通用入口,应返回结构化“接口引擎不存在”;不能返回 `/api/Sso/Capabilities` 路由 404。
|
|
48
48
|
- 安装后回读 11 个 `sys_apiengine` 行并刷新缓存,再验证 `sso_capabilities` 为 `Code=1`。
|
|
49
49
|
- `/api/Sso/Capabilities`、`LegacyCapabilities`、`CompleteLogin`、`RotateClientSecret` 与 `/api/SysUser/SsoPengrui` 必须保持删除,防止业务逻辑重新漂回 Controller。
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
`diy_sso` 是管理员专用平台表。匿名能力接口只投影 ConnectionKey、名称、协议、图标、说明和发起地址;旧兼容投影只允许同源 `/api/` 路径与安全 Token 参数名。
|
|
14
14
|
|
|
15
|
-
匿名投影由 `sso_capabilities` / `sso_legacy_capabilities` 接口引擎提供;Controller 不得直接查询并返回 `diy_sso`。内部协议网关通过 StopHttp 的 `sso_connection_runtime` 取得最小运行投影。客户端统一调用 `/
|
|
15
|
+
匿名投影由 `sso_capabilities` / `sso_legacy_capabilities` 接口引擎提供;Controller 不得直接查询并返回 `diy_sso`。内部协议网关通过 StopHttp 的 `sso_connection_runtime` 取得最小运行投影。客户端统一调用 `/apiengine/{ApiEngineKey}?OsClient=`,让观测数据保留真实 Key;新版宿主对未安装引擎返回结构化缺失错误,不再因动态路由尚未注册而直接 404。
|
|
16
16
|
|
|
17
17
|
## Secret 与证书
|
|
18
18
|
|
|
@@ -16,7 +16,7 @@ Manifest 使用 `tables[].formBanner`;未显式配置时仍按字段类型选
|
|
|
16
16
|
模块引擎或 `sys_menu`。逐步建模在字段完成后调用 `microi_configure_form_banner` 回读验收。
|
|
17
17
|
|
|
18
18
|
<!-- microi-progressive:begin -->
|
|
19
|
-
<!-- microi-progressive:chunk id=microi-system-delivery-000 sha256=
|
|
19
|
+
<!-- microi-progressive:chunk id=microi-system-delivery-000 sha256=088aaa73360be7d63b64ca476e884371140c7807d118c05f04d87a12de0c7701 -->
|
|
20
20
|
## 交付总原则
|
|
21
21
|
|
|
22
22
|
1. **先事实源,后建模**:先读需求文档、截图、现有蓝图、数据库结构和菜单结构,形成业务蓝图;不要边猜边建表、边猜边写接口。
|
|
@@ -45,7 +45,7 @@ Manifest 使用 `tables[].formBanner`;未显式配置时仍按字段类型选
|
|
|
45
45
|
最终回复必须按原始编号逐项汇总:哪些已实现、哪些未实现、是否通过全自动化测试、是否通过截图验证。不能只给总括性“都完成了”。如果某项没有测试或没有截图,必须明说“未覆盖/未截图”,并说明原因。
|
|
46
46
|
|
|
47
47
|
<!-- /microi-progressive:chunk -->
|
|
48
|
-
<!-- microi-progressive:chunk id=microi-system-delivery-002 sha256=
|
|
48
|
+
<!-- microi-progressive:chunk id=microi-system-delivery-002 sha256=5b929c8ab1cf588601fb0e27149ef05893bc5000eecf05e58961c4f785251e31 -->
|
|
49
49
|
## 平台安全与存量兼容验收(强制)
|
|
50
50
|
|
|
51
51
|
AI 零代码交付不能只验证管理员帐号和页面能打开。任何涉及 FormEngine、菜单、角色、子表、文件、SaaS 或登录协议的交付,都必须按以下服务端边界设计和验收:
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
统计都应来自真实字段或真实接口引擎;配置写 `diy_table`,禁止写入 `sys_menu`。即使用户
|
|
8
8
|
没有逐项指定,也必须写入类型感知的合理默认值,不能交付空 Banner。
|
|
9
9
|
|
|
10
|
-
<!-- microi-progressive:chunk id=microi-system-delivery-005 sha256=
|
|
10
|
+
<!-- microi-progressive:chunk id=microi-system-delivery-005 sha256=8e90f8c4618b882000935a83b8ed581ff20c32d9b888f74eb0ace8c39439a46e -->
|
|
11
11
|
## 标准工作流
|
|
12
12
|
|
|
13
13
|
### 1. 需求蓝图阶段
|
package/skills/microi.v8.js
CHANGED
|
@@ -1510,7 +1510,7 @@ export function createMicroiV8(options = {}) {
|
|
|
1510
1510
|
UniappUploadAnonymous: '/api/HDFS/uniappUploadAnonymous',
|
|
1511
1511
|
GetCurrentUser: '/api/SysUser/getCurrentUser',
|
|
1512
1512
|
GetDateTimeNow: '/api/os/getDateTimeNow',
|
|
1513
|
-
AddSysLog: '/
|
|
1513
|
+
AddSysLog: '/apiengine/platform-client-log',
|
|
1514
1514
|
GetOsClientByDomain: '/api/Os/getOsClientByDomain',
|
|
1515
1515
|
ApiEngine: {}
|
|
1516
1516
|
};
|
|
@@ -39,21 +39,31 @@ AI 第一次使用时先查询 `action=Capabilities`,再按返回的动作、
|
|
|
39
39
|
| `AppLogs` | 当前 API 进程日志尾部 | `lines=20..1000` |
|
|
40
40
|
| `PlatformStats` | 表、菜单、接口引擎、租户、用户和排行 | 无 |
|
|
41
41
|
| `SecurityData` | 访问、攻击或封锁记录 | `kind=Access|Attack|Block`、分页 |
|
|
42
|
-
| `TrafficHistory` | MySQL
|
|
42
|
+
| `TrafficHistory` | MySQL 固定时间桶流量趋势 | `rangeKey`;可选 `dimensionType` |
|
|
43
|
+
| `HistoricalDashboard` | 同一时间范围内的热点接口、IP、帐号、租户、内容类型与请求/流量总览 | `rangeKey=live5|today|yesterday|3d|7d|15d|30d|3m|6m|1y`、`top` |
|
|
44
|
+
| `TrafficDetails` | 跨月大文件、上传下载和可疑传输 MongoDB 明细 | `rangeKey`、`pageIndex/pageSize`;可选 `keyword/transferAction/ip/userId/endpoint` |
|
|
43
45
|
|
|
44
46
|
示例:
|
|
45
47
|
|
|
46
48
|
```json
|
|
47
49
|
{
|
|
48
|
-
"action": "
|
|
49
|
-
"
|
|
50
|
-
"
|
|
50
|
+
"action": "HistoricalDashboard",
|
|
51
|
+
"rangeKey": "30d",
|
|
52
|
+
"top": 15
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"action": "TrafficDetails",
|
|
59
|
+
"rangeKey": "7d",
|
|
60
|
+
"transferAction": "Upload",
|
|
51
61
|
"pageIndex": 1,
|
|
52
62
|
"pageSize": 15
|
|
53
63
|
}
|
|
54
64
|
```
|
|
55
65
|
|
|
56
|
-
所有列表默认按 15 条开始;扩大分页前先增加过滤条件。日志和安全数据每页最多 200 条,Trace
|
|
66
|
+
所有列表默认按 15 条开始;扩大分页前先增加过滤条件。日志和安全数据每页最多 200 条,Trace 最多 500 条。历史总览由固定聚合桶一次返回有界 TOP,不得循环拉取无时间边界的全量日志。
|
|
57
67
|
|
|
58
68
|
## 安全治理动作
|
|
59
69
|
|
|
@@ -73,6 +83,7 @@ UnblockIp:<ip>
|
|
|
73
83
|
3. HTTP 可归因流量只统计经过 API 中间件的请求体和响应体。网卡、容器 NetIO 还包含 TLS/HTTP 头、重传、数据库、Redis、MongoDB、MQ、对象存储、外部 HTTP、健康检查和同机其它进程。
|
|
74
84
|
4. “未归因流量”只能作为排查线索,不能强行归属给某个帐号、IP 或接口。
|
|
75
85
|
5. IP 必须注明是可信代理解析后的客户端地址还是直接连接地址;代理链未配置正确前不要据此处罚用户。
|
|
86
|
+
6. 进程 CPU“多核原始值”可超过 100%;247.7% 表示约占用 2.48 个逻辑核心。判断整机压力应使用主机归一值并结合持续时间、请求率与热点排行。
|
|
76
87
|
|
|
77
88
|
## 隐私与权限
|
|
78
89
|
|
|
@@ -86,17 +97,24 @@ UnblockIp:<ip>
|
|
|
86
97
|
|
|
87
98
|
- 请求热路径只做原子计数和有硬上限的分钟桶聚合;端点、IP、帐号、租户、内容类型限制基数并保留 TOP N。
|
|
88
99
|
- 普通高频明细只保留短窗口内存;错误、慢请求、大文件和可疑传输进入有界队列,异步批量写 MongoDB。
|
|
89
|
-
- 长期趋势使用 MySQL 固定时间桶和确定性幂等键批量 upsert
|
|
100
|
+
- 长期趋势使用 MySQL 固定时间桶和确定性幂等键批量 upsert;5 分钟桶保留 48 小时、小时桶保留 45 天、天桶保留 400 天。页面不能每次扫描 Mongo 明细重新聚合总览。
|
|
90
101
|
- 队列必须有硬容量、故障 spool/WAL、停机排空和幂等重放;禁止无界 `ConcurrentQueue` 或逐请求同步写 Mongo/MySQL。
|
|
91
102
|
- Redis 适合短时热点结果、租约和限流;缓存 Key 包含租户、动作和过滤摘要,写入或治理后主动失效,并保留短 TTL 防止永久陈旧。
|
|
92
103
|
|
|
104
|
+
## 接口引擎归因规范
|
|
105
|
+
|
|
106
|
+
- PC、UniApp、内置微服务、MCP 和应用包中的固定接口必须调用 `/apiengine/{ApiEngineKey}` 或该引擎唯一 `ApiAddress`;新增代码禁止调用 `/api/ApiEngine/Run`。
|
|
107
|
+
- SDK 的普通 `ApiEngine.Run` 必须自动生成真实引擎路径;旧通用入口只能封装在显式 `RunLegacy` 中,供不能立即升级的历史客户端使用。
|
|
108
|
+
- 监控中保留通用入口的兼容识别,但不能依赖读取请求正文才能知道 Key;真实路由、访问日志、限流和流量排行应直接显示接口引擎 Key。
|
|
109
|
+
- 代码审计要区分运行调用与文档/兼容测试;发布门至少扫描 Microi.Client、UniApp、微服务源码、MCP 与应用包,确保没有新增固定业务依赖。
|
|
110
|
+
|
|
93
111
|
需要压测或修改热路径时同时读取 `../performance-testing/SKILL.md`;排查 V8/日志写法时读取 `../v8-debugging/SKILL.md`。
|
|
94
112
|
|
|
95
113
|
## AI 诊断顺序
|
|
96
114
|
|
|
97
115
|
1. 先查 `Capabilities`,确认当前版本和边界。
|
|
98
116
|
2. 查 `Snapshot`,记录节点、窗口、请求率、活动请求、CPU/内存、队列、HTTP 流量与未归因残差。
|
|
99
|
-
3. 查 `ApiRank` 和 `TrafficHistory` 的 Endpoint/IP/User/Tenant/ContentType
|
|
117
|
+
3. 查 `ApiRank` 和 `TrafficHistory` 的 Endpoint/IP/User/Tenant/ContentType 维度,区分“计算慢”与“传输大”;再用 `TrafficDetails` 定位具体帐号/匿名、IP、接口、文件元数据和 TraceId。
|
|
100
118
|
4. 按异常接口或 TraceId 查 `Logs`、`Signal`、`Trace`;先处理时间线中的首个根因。
|
|
101
119
|
5. 对慢 SQL 核对执行计划、索引、返回字段、分页、排序/Join 和锁等待;不要先盲目加 Redis。
|
|
102
120
|
6. 对高频只读结果评估短 TTL Redis,并明确更新/删除时的失效路径;对写接口先批量化 I/O、缩小事务和消除逐行远程调用。
|
|
@@ -7,6 +7,8 @@ description: Microi 翻译引擎与多语言词条规范。用于 V8.TranslateEn
|
|
|
7
7
|
|
|
8
8
|
# Microi TranslateEngine
|
|
9
9
|
|
|
10
|
+
翻译运行时源码位于开源类库 `Microi.Server/Microi.Translate`,NuGet 包名为 `Microi.Translate`。可复用的供应商、租户隔离、缓存和模型契约必须维护在该类库;闭源 `Microi.net` 只允许保留 License 授权或平台私有装配边界,不能重新复制翻译业务实现。
|
|
11
|
+
|
|
10
12
|
## API
|
|
11
13
|
|
|
12
14
|
```js
|
|
@@ -111,6 +113,7 @@ MCP 固定工具:`microi_translate`、`microi_detect_language`、`microi_list_
|
|
|
111
113
|
|
|
112
114
|
## 验收清单
|
|
113
115
|
|
|
116
|
+
- [ ] `Microi.Translate` 能独立编译、打包并由发布脚本推送 NuGet,`Microi.net/TranslateEngine` 不再残留重复源码
|
|
114
117
|
- [ ] `Translate` 的 `DosResult` 契约处理正确
|
|
115
118
|
- [ ] 词条优先,动态翻译只用于动态内容
|
|
116
119
|
- [ ] 普通租户无法伪造 `OsClient`
|
|
@@ -63,7 +63,7 @@ description: Microi UI 设计系统指南。用于设计 PC Vue、Element Plus
|
|
|
63
63
|
---
|
|
64
64
|
|
|
65
65
|
<!-- /microi-progressive:chunk -->
|
|
66
|
-
<!-- microi-progressive:chunk id=ui-design-002 sha256=
|
|
66
|
+
<!-- microi-progressive:chunk id=ui-design-002 sha256=0d1bac0d19d61d288a6eb25f18fc15a045bca3df9a01399d5ce5224c8accffd3 -->
|
|
67
67
|
## 高端视觉标准
|
|
68
68
|
|
|
69
69
|
- 每个新页面必须有首屏视觉重心:核心数据、主任务、产品/品牌对象或可操作内容应在第一屏明确出现,不能只有说明文字或空白装饰。
|
|
@@ -19,7 +19,8 @@ description: Microi V8 接口引擎配置指南。用于设置 ApiEngineKey、Ap
|
|
|
19
19
|
| `ParamType` | `form` / `json` / `url` —— 但 V8.Param 都能统一接收 | `Both` |
|
|
20
20
|
| `IsAnonymous` | 允许匿名调用(无 Token) | `false` |
|
|
21
21
|
| `StopHttp` | 禁止外部 HTTP 调用(仅允许 V8.ApiEngine.Run 内部调用) | `false` |
|
|
22
|
-
| `IsResponseFile` | 是否响应文件(开启后 Data 必须是文件结构) | `false` |
|
|
22
|
+
| `IsResponseFile` | 是否响应文件(开启后 Data 必须是文件结构) | `false` |
|
|
23
|
+
| `ResponseType` | `JSON/String/File/HTML/Stream`;`Stream` 开启 SSE/NDJSON | 自动识别 |
|
|
23
24
|
| `LockKey` | 分布式锁 Key(同一时刻全集群只能执行一次) | 空 |
|
|
24
25
|
| `LockTimeout` | 锁超时秒数 | `30` |
|
|
25
26
|
| `LockMsg` | 加锁失败时返回提示 | `操作过于频繁` |
|
|
@@ -35,9 +36,25 @@ description: Microi V8 接口引擎配置指南。用于设置 ApiEngineKey、Ap
|
|
|
35
36
|
- 嵌套调用不重复占用全局/租户并发名额,同一调用树重入同 Key 也不会自锁;不同子接口 Key 仍受自己的 Key 并发门保护。
|
|
36
37
|
- `V8.Limits` 可读取本片有效预算和当前深度。异常优先检查 `DataAppend.V8Limit.Code`,不要看到“2GB”就判断服务器真实吃满 2GB。
|
|
37
38
|
- 后台任务使用同一执行引擎。总任务可以运行数小时,但单片仍受 `Timeout/MaxStatements/LimitMemory` 约束;超过 10 分钟必须返回 `HasMore + Checkpoint` 分片续跑,不能只把 `Timeout` 调到 1800/3600。
|
|
38
|
-
- 接口引擎使用正向 `V8Limit`:默认 `0/false`,不设置当前 Jint Engine 的单次超时、语句、函数递归、累计分配和 Promise 固定等待预算;只有 `1/true` 才应用 `Timeout/MaxStatements/LimitMemory/LimitRecursion`。常驻内存保护、取消令牌、并发、接口嵌套深度、权限沙箱及数据库限制在两种状态下都保留。老 `V8Unlimited` 只作协议兼容;MCP/Manifest 新配置统一写 `v8Limit`。
|
|
39
|
-
|
|
40
|
-
###
|
|
39
|
+
- 接口引擎使用正向 `V8Limit`:默认 `0/false`,不设置当前 Jint Engine 的单次超时、语句、函数递归、累计分配和 Promise 固定等待预算;只有 `1/true` 才应用 `Timeout/MaxStatements/LimitMemory/LimitRecursion`。常驻内存保护、取消令牌、并发、接口嵌套深度、权限沙箱及数据库限制在两种状态下都保留。老 `V8Unlimited` 只作协议兼容;MCP/Manifest 新配置统一写 `v8Limit`。
|
|
40
|
+
|
|
41
|
+
### 流式响应(ResponseType=Stream)
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
for (var i = 0; i < rows.length; i++) {
|
|
45
|
+
var pushed = await V8.Stream.WriteAsync(rows[i], 'chunk', String(i));
|
|
46
|
+
if (pushed.Code !== 1) return pushed;
|
|
47
|
+
}
|
|
48
|
+
return { Code: 1, Data: { Count: rows.length } };
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
- 默认协议为 SSE;客户端请求 `Accept: application/x-ndjson` 或 `streamFormat=ndjson` 可使用 NDJSON。
|
|
52
|
+
- `V8.Stream.Write/WriteAsync` 输出的分片统一标记 `Provisional:true`。宿主保留 `open/done/error/heartbeat`,并且只有事务提交后才发送 `done + Committed:true`;收到 `error` 时客户端不得把暂态分片当成已提交数据。
|
|
53
|
+
- 每次写入都要检查 `Code`,客户端断开或超过大小上限后立即停止循环。请求取消会传入当前 Jint 执行链,但不能替代业务幂等和事务。
|
|
54
|
+
- 当前租户在 `sys_osclients` 配置单分片、累计响应和心跳:`ApiEngineStreamMaxChunkKB` 默认 256(4–1024)、`ApiEngineStreamMaxTotalMB` 默认 16(1–256)、`ApiEngineStreamHeartbeatSeconds` 默认 15(5–60)。
|
|
55
|
+
- 流式传输用于在线增量反馈;大型文件走 HDFS/文件响应,可靠长任务走后台任务 + Checkpoint,广播状态走提交后 SignalR。禁止用流式响应绕过这些边界。
|
|
56
|
+
|
|
57
|
+
### 通用实时事件(SignalR)
|
|
41
58
|
|
|
42
59
|
订单、协作、设备、审批或多人房间需要实时刷新时,业务写命令仍由接口引擎执行并提交事务;成功结果通过 `DataAppend.RealtimeEvent` 声明提交后事件。新业务统一使用通用 v2 Hub `/api-engine-realtime`,不要再新建业务专用 Hub 或把权威状态放进 C# 进程内字典。
|
|
43
60
|
|
|
@@ -205,11 +222,16 @@ POST /apiengine/{ApiEngineKey}
|
|
|
205
222
|
Headers: Content-Type=application/json, osclient={OsClient}, apiengine=1
|
|
206
223
|
Body: {"Action":"Bootstrap","OsClient":"{OsClient}"}
|
|
207
224
|
|
|
208
|
-
#
|
|
209
|
-
POST /api/ApiEngine/Run
|
|
210
|
-
Headers: Content-Type=application/json, OsClient={OsClient}
|
|
211
|
-
Body: {"ApiEngineKey":"your_key","Action":"Bootstrap"}
|
|
212
|
-
```
|
|
225
|
+
# 仅用于不能立即升级的旧客户端;新增或可修改代码禁止使用
|
|
226
|
+
POST /api/ApiEngine/Run
|
|
227
|
+
Headers: Content-Type=application/json, OsClient={OsClient}
|
|
228
|
+
Body: {"ApiEngineKey":"your_key","Action":"Bootstrap"}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
固定业务接口必须调用 `/apiengine/{ApiEngineKey}` 或该引擎配置的唯一
|
|
232
|
+
`ApiAddress`。禁止新增 `/api/ApiEngine/Run` 依赖,否则反向代理、限流、审计和
|
|
233
|
+
系统日志/监控只能看到同一个通用入口,难以按真实接口引擎准确归因。SDK 只可在
|
|
234
|
+
显式命名的 `RunLegacy` 兼容方法中保留旧地址,普通 `Run` 必须生成动态地址。
|
|
213
235
|
|
|
214
236
|
复测重点:
|
|
215
237
|
|