@microi.net/cli 5.5.1 → 5.5.3
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 +3 -3
- package/cordis.patch.yml +1 -1
- package/package.json +1 -1
- package/scripts/microi-skills.meta.json +199 -199
- package/skills/.microi-skills-version.json +2 -2
- package/skills/.progressive-disclosure-manifest.json +6 -6
- package/skills/ai-engine/SKILL.md +2 -1
- package/skills/app-store/SKILL.md +5 -1
- package/skills/microi-db-schema/SKILL.md +3 -1
- package/skills/microi-form-engine/SKILL.md +3 -2
- package/skills/microi-microservice/SKILL.md +3 -1
- package/skills/microi-mobile-app-quality/SKILL.md +1 -1
- 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 +12 -1
- package/skills/v8-export-import/SKILL.md +9 -1
- package/skills/vision-engine/SKILL.md +15 -7
- package/skills/vision-engine/references/architecture-and-acceptance.md +34 -12
- package/skills/workspace-conventions/SKILL.md +236 -236
- 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 +50 -50
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
|
-
"generatedAt": "2026-09-
|
|
3
|
+
"generatedAt": "2026-09-05T06:43:32.791Z",
|
|
4
4
|
"policy": {
|
|
5
5
|
"maxEntryLines": 285,
|
|
6
6
|
"referenceBudgetLines": 245,
|
|
@@ -534,8 +534,8 @@
|
|
|
534
534
|
]
|
|
535
535
|
},
|
|
536
536
|
"microi-mobile-app-quality": {
|
|
537
|
-
"originalSha256": "
|
|
538
|
-
"originalLines":
|
|
537
|
+
"originalSha256": "6a91cbc1ae49e576ae465b252b260a43dfc861cf3af2618cac636a429106d632",
|
|
538
|
+
"originalLines": 459,
|
|
539
539
|
"prefixSha256": "f8c7ff069eba59ee314557b078d3684b92eb05d232adebfe2a0a01002e66b581",
|
|
540
540
|
"prefixBytes": 1087,
|
|
541
541
|
"entryLines": 182,
|
|
@@ -568,7 +568,7 @@
|
|
|
568
568
|
"id": "microi-mobile-app-quality-003",
|
|
569
569
|
"ordinal": 3,
|
|
570
570
|
"destination": "microi-mobile-app-quality/SKILL.md",
|
|
571
|
-
"sha256": "
|
|
571
|
+
"sha256": "a35f20404acbf61814f9475610f881f7c60effc0ce3bb8797cee300cd3349ba7",
|
|
572
572
|
"lines": 25,
|
|
573
573
|
"heading": "2.1 登录验证码必须跟随 Sys_Config.EnableCaptcha"
|
|
574
574
|
},
|
|
@@ -712,8 +712,8 @@
|
|
|
712
712
|
"id": "microi-mobile-app-quality-021",
|
|
713
713
|
"ordinal": 21,
|
|
714
714
|
"destination": "microi-mobile-app-quality/references/progressive-02-9-主题切换必须真实且全局生效.md",
|
|
715
|
-
"sha256": "
|
|
716
|
-
"lines":
|
|
715
|
+
"sha256": "13405c8ce231e9db8920cd8e1c4e0db26a32c1b5ac967113abee1391985ebfcd",
|
|
716
|
+
"lines": 32,
|
|
717
717
|
"heading": "最终交付清单"
|
|
718
718
|
}
|
|
719
719
|
],
|
|
@@ -84,7 +84,8 @@ AI 业务统一实现在 `Microi.Server/Microi.AI`。`Microi.Server/Microi.net.A
|
|
|
84
84
|
- v6.3.6 还必须保持 AI助手包的 DDL、PhysicalColumns、DiyTables、DiyFields、DataSets 全层不再包含重复的 `mci_ai_app_version`、`mci_ai_app_file`、`sys_microistore`,这些表交回 Store/SaaS 既有平台包维护;当前仅 AI助手包拥有的 `app_mic_aiapp`、`mci_ai_app` 继续保留。
|
|
85
85
|
- 普通角色必须匹配启用的 `mci_ai_role_policy`。只有后端可信的 `V8.CurrentUser.Level >= 9999` 可以在新安装租户缺少角色策略时获得安全兜底:从目标租户动态读取已启用业务域和模型,范围为 `All`,仍保持 `AllowRawSql=false`、敏感字段默认关闭。不得相信客户端提交的 Level、角色名或账号名。
|
|
86
86
|
- 当租户要求“所有角色均可使用 AI 助手”时,必须为 `sys_role` 中每个目标角色建立显式启用策略;受限角色使用 `Self`/`Department` 与最小业务域,管理角色才可使用经确认的 `All`。禁止把“人人可打开助手”实现成普通角色默认全库可读。
|
|
87
|
-
- `Sys_Config.DisableAiAssistant` 是负向开关:缺失、空值或 `0/false` 都显示 AI 助手,只有显式 `1/true`
|
|
87
|
+
- `Sys_Config.DisableAiAssistant` 是负向开关:缺失、空值或 `0/false` 都显示 AI 助手,只有显式 `1/true` 才关闭图标。历史包曾复用旧 `IsShowAiAssistant` 的字段元数据 Id 就地改名;因此清理旧开关必须按当前表名和字段名回读定位,不能只按历史 Id 删除,避免误删已复用该 Id 的新开关。官方母版必须通过标准 MCP 删除旧字段元数据,不能仅隐藏;新版包的 DiyFields、PhysicalColumns、DDL 及生成器均不得重新创建旧开关。平台删除字段可保留存量物理列兼容,但新前端只读取 DisableAiAssistant,不得重建正向开关或改写租户现有配置值。关闭该开关前后都要做策略覆盖验收:回读 `sys_role` 与 `mci_ai_role_policy`,断言每个目标角色都有唯一启用策略,`AllowedDomains`、`AllowedModels` 均非空且模型仍处于启用状态;再至少用超级管理员、普通员工和客户身份分别调用 `Bootstrap`,确认 `Enabled=true` 且返回范围符合角色。仅看到入口图标不算可用。
|
|
88
|
+
- 提审要求关闭 AI 入口时,必须把“关闭AI助手图标”设为 `DisableAiAssistant=1`,从数据库、客户端实际配置接口和入口逐层验收,不能用旧正向字段为 `0` 代替。官方包发布与其他租户安装是两个独立动作;未执行目标租户安装或字段清理时,不得宣称全体存量租户已移除旧元数据。
|
|
88
89
|
- 角色策略存在但 `AllowedModels` 为空时,客户端最终仍会得到无可用模型;不得把它误判为前端角色拦截。应补齐当前租户启用模型白名单并回读,而不是删除 `mci_ai_role_policy` 校验或在客户端强制把 `Enabled` 改成 `true`。
|
|
89
90
|
- 商城包不能携带发布租户的角色 Id、模型 Id 或密钥;应携带业务域定义和接口引擎,由安装后的目标租户动态发现自己的启用模型。发布后回读 `sys_microistore.AppVersion/AppPakcet`,并真实执行 `Bootstrap` 验证超级管理员可用、模型非空、快捷问题存在。
|
|
90
91
|
|
|
@@ -19,7 +19,11 @@ description: Microi 应用商城开发、打包、安装和升级规范。用于
|
|
|
19
19
|
|
|
20
20
|
- 表、字段、Tab、菜单、权限、接口引擎、事件、数据源、页面、打印、工作流、任务和可幂等种子数据都应通过应用包升级;不得为这些资源在 `Microi.Server/Microi.Upgrade/` 新增租户定制 .NET 代码。
|
|
21
21
|
- 有官方 MCP 权限时,固定使用 `microi_itdos`(`https://api.itdos.com`、`OsClient=iTdos`)更新官方母版、制作并发布对应应用,按内容哈希/包版本回读后,再由目标租户 MCP 安装或更新。无官方权限时只通过当前用户自己的 MCP/Manifest 更新其数据库并回读,不得假借通用升级器越权发布官方应用。
|
|
22
|
-
- `Microi.Upgrade` 只保留应用商城/安装器启动前必需的核心物理兼容或协议迁移,并要求持久化版本门、共享租约、幂等、失败不推进版本。禁止每次启动对每个租户重跑不断增长的历史迁移清单。
|
|
22
|
+
- `Microi.Upgrade` 只保留应用商城/安装器启动前必需的核心物理兼容或协议迁移,并要求持久化版本门、共享租约、幂等、失败不推进版本。禁止每次启动对每个租户重跑不断增长的历史迁移清单。
|
|
23
|
+
- 新增升级点前必须完成“商城不可表达性”证明:逐项说明为什么 `DiyTables/DiyFields/DDLStatements/PhysicalColumns/DataSets`、菜单、接口引擎、工作流或 AI 应用包无法交付,以及为什么该结构在登录/商城恢复入口可用前就必须存在。不能证明时一律升级对应官方应用包;客户租户缺少某张业务表不得写成全平台 `.NET` 启动迁移。
|
|
24
|
+
- 历史升级点不能因为今天可由商城表达就直接删除:若后续步骤依赖其物理结果,须保留为冻结兼容链,或把必要前置检查显式并入后续步骤。新增步骤必须使用高于当前目标的唯一四段版本并追加到链末尾,不得抬高旧步骤版本造成非单调执行顺序。
|
|
25
|
+
- 租户协调器必须先只读 `ServerVersion`:已达到当前一次性基线时不得取得升级租约、重放历史不变量或刷新缓存;落后租户取得共享租约后必须再次读取版本,防止多节点重复执行。启动成本应近似“每租户一次版本读取 + 实际待执行迁移”,不得近似“租户数 × 历史升级点总数”。主租户接流量前的最小物理/商城引导门禁可独立保留,但不得扩展成全部子租户的永久全量扫描。
|
|
26
|
+
- 同一批历史漂移确需修复时,用一个新版本的“一次性基线”在租约内幂等封口,并仅在全部步骤强回读成功后前向推进版本;失败不得推进。基线完成后,任何新增核心迁移都必须再升版本,任何业务资源修复都必须再升应用包版本,禁止恢复为每次启动复检。
|
|
23
27
|
- 平台通用缺陷的交付证据必须分开记录:源码修复、官方母版资源、商城包发布后回读、目标租户后台安装任务、目标租户资源回读和真实 UI/接口验收;其中任一步未完成都不能笼统称为“已发布并安装”。
|
|
24
28
|
- 任何计划让全部吾码租户通过“安装/更新官方应用”获得的标准字段、布局、菜单、页面或种子数据,必须先在官方 `microi_itdos` 主租户创建并回读,再从该主租户按精确菜单/表资源导出新版包、单调递增应用版本并发布。包正文以 `PackageHdfsPath + PackageSha256 + PackageSize` 为事实源;`AppPakcet` 只作旧版读取兼容,验证完成后应为空。禁止先只在客户/子租户补字段,再用本地手工 JSON 冒充官方母版;客户验证应发生在官方包发布之后。
|
|
25
29
|
- 同一标准能力若同时属于基础 SaaS 空库包和独立官方应用(例如系统设置、系统账号),两条交付链都要更新:基础包保证新租户初始化完整,独立应用保证存量租户可增量安装。表、字段和初始化模板可按这两个目标分别交付,但同一个 Managed ApiEngineKey 必须只有一个官方包所有者,禁止 SaaS、Store 与独立应用重复携带后互相覆盖。发布后分别核对 `PackageInfo.Version`、物理列、`diy_field` 布局节点、接口引擎单一归属、商城行 `AppVersion` 和 HDFS 包指针/下载哈希,不能用其中一条替代另一条。
|
|
@@ -113,7 +113,9 @@ AI 或 MCP 生成低代码系统时,必须默认遵守此规则。发现已有
|
|
|
113
113
|
并把真实外键放在子表。不得创建主表 `XxxId` 后用 `JoinForm` 冒充子表。
|
|
114
114
|
- `JoinForm` 仅用于主表保存一个目标 Id 并嵌入一条独立目标记录;目标表不能与当前表相同。
|
|
115
115
|
关系基数不明确时,MCP 写入前必须询问,不能把 `JoinForm` 当安全默认值。
|
|
116
|
-
-
|
|
116
|
+
- 子表外键必须建立与物理租户隔离方式一致的回查索引:物理表存在 `OsClient` 时通常为
|
|
117
|
+
`(OsClient, ParentId)`,独立租户物理表没有 `OsClient` 时为 `(ParentId)`。结构或索引读取失败
|
|
118
|
+
必须拒绝关系配置,不能为了通过校验新增不存在业务语义的 `OsClient` 列。子表还要有绑定同一子表的隐藏菜单,
|
|
117
119
|
`Display=0`、`AppDisplay=0`、`HasChild=0`。
|
|
118
120
|
- Manifest/蓝图审查时,只要发现 1:N 关系对应 `JoinForm`、缺少子表外键、缺少隐藏子菜单
|
|
119
121
|
或缺少回查索引,就必须判定计划不合格,停止写入。
|
|
@@ -164,8 +164,9 @@ MCP 建模只使用:
|
|
|
164
164
|
### MCP 创建 `TableChild` 的两阶段流程
|
|
165
165
|
|
|
166
166
|
1. 创建主表和独立子表;在子表创建真实外键(如 `VisitId varchar(50)`)。
|
|
167
|
-
2.
|
|
168
|
-
`
|
|
167
|
+
2. 在子表为回查创建与物理隔离方式一致的索引:表有 `OsClient` 时通常为
|
|
168
|
+
`(OsClient, VisitId)`,独立租户表没有该列时为 `(VisitId)`。索引写入 Manifest
|
|
169
|
+
`tables[].indexes`,并以 `microi_get_table_indexes` 回读;物理字段回读失败时停止配置。
|
|
169
170
|
3. 为子表创建绑定其 `diyTableId` 的隐藏 CRUD 菜单:`Display=0`、`AppDisplay=0`、
|
|
170
171
|
`HasChild=0`。
|
|
171
172
|
4. 在完整系统 Manifest 的主表字段声明:
|
|
@@ -271,7 +271,9 @@ window.addEventListener('appstate-change', (event) => {
|
|
|
271
271
|
根节点写 `overflow:auto` 不算自滚动容器。验收需分别覆盖框架兜底和子应用自滚动,断言任一时刻
|
|
272
272
|
只有一个 `scrollHeight > clientHeight` 的纵向滚动所有者。
|
|
273
273
|
|
|
274
|
-
|
|
274
|
+
相机扫描、收银称台、扫码、签到等高频工具页必须另设“一屏操作”断点:在宿主下发的可用高度内同时显示输入/取景、主操作、处理状态、核心结果和业务要求的最近记录入口,完成主流程不得依赖页面纵向滚动;竖屏优先上下紧凑分区,短横屏切换左右或多列分区。历史明细可在自己的卡片内滚动,但不能隐藏错误、当前结果、暂停/继续/恢复等关键动作。桌面应占满宿主可用宽度,通过有界预览容器和 `object-fit` 防止上传竖图把页面撑高。真实浏览器验收至少覆盖一个常见手机竖屏和一个短横屏,并断言根容器不溢出、取景区/结果区/关键历史入口同时在视口内、平台底部菜单与安全区不遮挡按钮;桌面断点必须回归,不能为移动端压缩破坏 PC 布局。
|
|
275
|
+
|
|
276
|
+
摄像头微服务必须把媒体异步生命周期当作竞态处理:每次打开、关闭和卸载都递增操作令牌或取消版本;`getUserMedia`、设置 `srcObject`、`video.play()` 每个异步边界返回后都要验证令牌仍有效。关闭时先同步切换 UI 状态并使旧操作失效,再停止全部轨道和清空 `srcObject`,防止旧 Promise 把已关闭状态反写为开启。条件渲染或点击后会移动的关闭按钮可在 `pointerdown` 捕获阶段完成停止,再短时去重后续 `click`。自动识别可以按画面指纹去重,但用户点击主识别按钮必须能强制处理当前帧;同一页面不要再放置语义重复且易被宿主底栏遮挡的第二个“再次识别当前画面”。
|
|
275
277
|
|
|
276
278
|
加载/协议/运行时异常只由宿主兜底显示;子应用业务错误标记 `handled=true` 后宿主不得重复提示。
|
|
277
279
|
加载失败页至少显示 AppKey、PageKey、路由、版本、入口、HTTP 状态、发布状态、资产来源、挂载状态和安全原因码,并提供重试、返回与复制诊断。
|
|
@@ -78,7 +78,7 @@ description: Microi 移动端质量门禁,适用于 UniApp/H5/微信小程序
|
|
|
78
78
|
- 使用真实系统账号登录后,必须验证“我的”页显示已登录角色,首页/工单/报告不再出现未登录提示,刷新页面或切换底部导航后仍保持一致。
|
|
79
79
|
|
|
80
80
|
<!-- /microi-progressive:chunk -->
|
|
81
|
-
<!-- microi-progressive:chunk id=microi-mobile-app-quality-003 sha256=
|
|
81
|
+
<!-- microi-progressive:chunk id=microi-mobile-app-quality-003 sha256=a35f20404acbf61814f9475610f881f7c60effc0ce3bb8797cee300cd3349ba7 -->
|
|
82
82
|
## 2.1 登录验证码必须跟随 Sys_Config.EnableCaptcha
|
|
83
83
|
|
|
84
84
|
PC 端、H5、App、微信小程序或任何自定义前端只要调用 `/api/SysUser/login`、`/api/SysUser/Login` 或 `V8.Login(param)`,都必须先读取 `Sys_Config` 的 `EnableCaptcha` 配置,并按配置决定是否展示和提交图形验证码。
|
|
@@ -93,7 +93,18 @@
|
|
|
93
93
|
- 用未绑定的小程序手机号账号登录,截图确认“我的”页出现申请绑定身份入口;提交申请后后台能看到待审核记录;通过审核前数据权限不提前开放,通过审核后对应客户数据或内部工作台能力才出现。
|
|
94
94
|
|
|
95
95
|
<!-- /microi-progressive:chunk -->
|
|
96
|
-
<!-- microi-progressive:chunk id=microi-mobile-app-quality-021 sha256=
|
|
96
|
+
<!-- microi-progressive:chunk id=microi-mobile-app-quality-021 sha256=13405c8ce231e9db8920cd8e1c4e0db26a32c1b5ac967113abee1391985ebfcd -->
|
|
97
|
+
## 审核后的会话与角色同步(强制)
|
|
98
|
+
|
|
99
|
+
- 审核通过后的数据库角色、服务端 DiyToken 身份投影、SDK 用户缓存、页面 capability 和申请状态必须一致,禁止以“退出重登后正常”作为验收成功。
|
|
100
|
+
- `RefreshLoginUser` 必须检查返回值和真实授权边界。普通审核员能审核业务申请,不代表其能刷新任意用户 Token;不得伪造管理员身份、手写登录 Redis 或扩大跨用户会话权限。
|
|
101
|
+
- 已授权的刷新应在角色事务提交后执行。平台仅允许普通用户刷新本人会话时,审核接口提交后发送定向身份变更通知,接收方调用固定的本人上下文接口,从主库重算角色并刷新本人全部有效终端会话;通知不能携带可直接采信的角色、Token 或权限。
|
|
102
|
+
- SignalR 推送只作加速。应用前台恢复、实时重连及有界前台校验必须能从权威数据恢复离线期间的审批;后台停止轮询。不得要求审核者与申请者位于同一 API 节点。
|
|
103
|
+
- 应用级会话同步实行 single-flight,刷新结果同时替换 SDK 和 store 用户缓存。退出或切换账号递增 generation,拒绝前一身份的迟到响应,不能让旧请求把旧角色写回来。
|
|
104
|
+
- 比较身份投影时排除 `$authenticated` 等调用级虚拟角色;它们不能保存为业务角色,也不能导致每次查询重复刷新会话。
|
|
105
|
+
- 带 `OnlyGet` 的客户角色需要调用身份申请等窄业务入口时,只为已经做服务端用户隔离的接口配置明确 `ApiRole`,不得移除客户角色的全局只读保护。
|
|
106
|
+
- 必测:两个独立登录上下文,一方保持原登录状态,另一方以真实审核员权限通过申请;前者不重登、不刷新页面获得新角色。继续验证原 Token、另一终端有效 Token、SDK 缓存、断网恢复、降权、退出时在途请求及未经授权的审核拒绝。
|
|
107
|
+
|
|
97
108
|
## 最终交付清单
|
|
98
109
|
|
|
99
110
|
移动端项目标记完成前必须确认:
|
|
@@ -202,4 +202,12 @@ return { Code: 1, Data: dataList, DataCount: dataList.length };
|
|
|
202
202
|
- [references/progressive-01-excellayout-高级自由布局.md](references/progressive-01-excellayout-高级自由布局.md):`ExcelLayout` 高级自由布局;多 Sheet Excel 导出;Word 导出
|
|
203
203
|
- [references/progressive-02-powerpoint-导出.md](references/progressive-02-powerpoint-导出.md):PowerPoint 导出;完整导入模式(含进度跟踪);接收并下载文件(HTTP 链接转 Excel);子表导入自动关联主表
|
|
204
204
|
- [references/progressive-03-安全-性能注意.md](references/progressive-03-安全-性能注意.md):安全 / 性能注意
|
|
205
|
-
<!-- microi-progressive:end -->
|
|
205
|
+
<!-- microi-progressive:end -->
|
|
206
|
+
|
|
207
|
+
## 复盘:通用导入需要事务内整批业务校验
|
|
208
|
+
|
|
209
|
+
- 触发场景:业务要求按整批汇总校验额度,并在并发导入时锁定稳定的主记录;完全替换导入接口会重复实现文件解析、字段映射、权限、进度和错误报告。
|
|
210
|
+
- 通用规则:模块 `ImportV8` 显式配置为 `ApiEngine:<ApiEngineKey>` 时,平台标准导入器在 `RollbackAll` 的同一数据库事务内,把服务端重新解析并应用固定父表值后的全部行传给接口引擎;接口只负责校验和加锁,不自行写入或提交事务。平台通过 `V8.Param.Capabilities.PreflightFixedValuesV1=true` 声明支持安全回填;接口确认该能力后,若能从权威数据唯一推导出本批共同缺失的业务字段,可在成功结果的 `Data.FixedValues` 返回字段名到非空标量值的对象。平台只接受当前表可导入业务字段,拒绝平台字段、未知字段以及覆盖既有父表固定上下文,并把通过校验的值应用到本批全部写入。其它历史 `ImportV8` 文本保持原兼容行为。
|
|
211
|
+
- 父子表边界:固定父记录外键优先于 Excel 同名列;接口引擎仍须核对目标表、项目/主记录存在性、业务状态和额度。需要整批钩子的模块禁止 `ContinueOnError`。
|
|
212
|
+
- 重复提交:客户端每次重新选择文件生成新的 `_ImportIdempotencyKey`,同一 HTTP 重试沿用该键;服务端按租户、表、菜单、用户和请求键保存状态,`Pending/Running/Succeeded` 均不得重复创建写入任务。该机制不等同于“相同文件作为新请求再次上传”的内容判重。
|
|
213
|
+
- 自动化检查:至少覆盖同批汇总超量、稳定行锁先于累计回查、整批回滚、父外键不可被 Excel 覆盖、同一请求重试只写一次,以及错误中包含行号和业务上限明细。
|
|
@@ -36,12 +36,12 @@ Microi.Vision 是可信 .NET 宿主中的最小视觉原子层,只负责:
|
|
|
36
36
|
|
|
37
37
|
| 组件 | 策略 | 职责 |
|
|
38
38
|
|---|---|---|
|
|
39
|
-
| `platform-vision-runtime` | `Managed` | Recognize/Enroll/Result/Recent/Bootstrap/Capabilities |
|
|
39
|
+
| `platform-vision-runtime` | `Managed` | Recognize/Enroll/Result/Recent/Correct/Bootstrap/Capabilities |
|
|
40
40
|
| `platform-vision-ai-worker` | `Managed` | 持久任务消费、Microi.AI 视觉调用、回写与敏感图片清理 |
|
|
41
41
|
| `platform-vision-category-options` | `Managed` | 当前租户启用分类选项 |
|
|
42
42
|
| `platform-vision-subject-options` | `Managed` | 当前租户启用对象选项 |
|
|
43
43
|
| `platform-vision-custom-hook` | `CreateIfMissing` | 租户自己的低敏业务扩展,官方升级永不覆盖 |
|
|
44
|
-
| `microi-vision/workbench` | MicroService |
|
|
44
|
+
| `microi-vision/workbench` | MicroService | 图片、摄像头帧、连续模式、来源阶段、最近记录、纠错与样本录入 |
|
|
45
45
|
|
|
46
46
|
详细数据、状态、协议和验收规范见 [architecture-and-acceptance.md](references/architecture-and-acceptance.md)。
|
|
47
47
|
|
|
@@ -58,7 +58,9 @@ Microi.Vision 是可信 .NET 宿主中的最小视觉原子层,只负责:
|
|
|
58
58
|
7. AI 开启时先保存私有输入并创建共享后台任务,立即返回 `Status=AiPending`;
|
|
59
59
|
8. Worker 收敛到 `AiMatched` 或 `Failed`,前端用同一 `RequestNo` 轮询。
|
|
60
60
|
|
|
61
|
-
不得同步阻塞前端等待大模型,不得把 AI 结果自动写入可信对象主数据,也不得把本地相似度与 AI
|
|
61
|
+
不得同步阻塞前端等待大模型,不得把 AI 结果自动写入可信对象主数据,也不得把本地相似度与 AI 置信度混成一个分数。生鲜的冰冻状态、新鲜度、预估价格/单位/币种也必须按字段保存 `Database/AI/Manual` 来源:样本或对象主数据优先,只有数据库未命中后才允许 AI 推断;AI 价格只是非约束估计,不能直接覆盖门店售价。
|
|
62
|
+
|
|
63
|
+
历史记录纠错使用 `Correct` 动作:只允许绑定当前租户中启用且模式兼容的对象,记录原标签、原来源、修正人、时间和原因;选择 `SaveAsSample` 时通过来源 `RequestNo` 做幂等录入。AI 结果不得自动加入 `Ready` 样本,必须由有权限的用户明确确认。`Recent/Result` 只返回 `HasImage` 与后端生成的短期授权 URL,禁止把 `InputFilePath`、图片 Base64 或永久公开地址交给浏览器。
|
|
62
64
|
|
|
63
65
|
## V8 原子函数
|
|
64
66
|
|
|
@@ -116,13 +118,17 @@ var voted = await V8.Vision.Stabilize({
|
|
|
116
118
|
|
|
117
119
|
## 视频入口
|
|
118
120
|
|
|
119
|
-
前端使用 `getUserMedia` 并按 `FrameIntervalMs`
|
|
121
|
+
前端使用 `getUserMedia` 并按 `FrameIntervalMs` 取帧,必须提供开启、暂停、继续、立即识别当前帧和关闭操作;每次打开摄像头生成新的 `StreamSessionId`,每帧递增 `FrameSequence`。自动连续模式允许跳过相同画面,人工主按钮必须显式绕过前端去重以提交当前帧。可信边缘宿主将 RTSP/WebRTC 解码为 `IAsyncEnumerable<MicroiVisionExtractParam>` 后调用 `RecognizeFramesAsync`。Microi.Vision 不直接连接调用方提交的 RTSP URL,不保存摄像头账号,不承担流媒体服务器职责。
|
|
122
|
+
|
|
123
|
+
打开摄像头、`getUserMedia`、`video.play()`、关闭和组件卸载之间必须使用递增操作令牌或等价取消机制。关闭时先同步写入关闭态并使旧操作失效,再停止轨道和清空 `srcObject`;不能等待媒体清理完成后才改 UI,否则快速关闭会被较早的异步打开流程反向覆盖。移动控件或条件渲染按钮可在 `pointerdown` 立即执行停止语义,并对随后 `click` 做短时去重,防止 DOM 重排吞掉关闭操作。
|
|
120
124
|
|
|
121
125
|
连续帧必须有:最大图片大小、最小间隔、单客户端串行、取消/停止、RequestId 幂等、网络退避和后台任务去重。不能每个视频帧都无界调用大模型。接口返回 `AiPending` 后,前端必须进入 single-flight 状态:暂停提交新帧,只轮询当前 `RequestId`,直到 `AiMatched/AiFailed/Unmatched`、超时或用户取消后才允许下一帧;禁止并行创建多个 AI 任务。
|
|
122
126
|
|
|
123
127
|
跨版本接口字段必须在协议边界归一化。连续稳定结果至少兼容 `.NET` 原子常用的 `VoteCount/WindowCount/AverageConfidence` 与历史接口的 `Votes/WindowSize/Confidence`,前端只读取归一化 DTO,任何真实响应都不得展示 `undefined/undefined`。
|
|
124
128
|
|
|
125
|
-
|
|
129
|
+
手机收银/巡检工作台属于高频全屏操作面:在宿主提供的可用高度内同时露出取景区、主要识别按钮、当前状态、核心结果和“最近识别”入口,不依赖页面纵向滚动才能完成一次识别;竖屏按采集/结果/最近记录三段紧凑分配,短横屏改为三列,且不得改变已验收的桌面布局。历史列表可以成为卡片内部的唯一滚动区。相机权限拒绝、数据库匹配中、数据库未命中、AI 等待、终态结果和恢复操作都要在当前视口可见,平台底部菜单和安全区不得遮挡按钮。
|
|
130
|
+
|
|
131
|
+
桌面工作台使用宿主可用宽度,不再用固定窄版 `max-width`;采集、结果、最近记录同屏三栏。预览使用有界容器和 `object-fit: contain`,上传竖图或打开摄像头不能撑高整个页面。不要同时提供语义重复的底部“再次识别当前画面”和主操作按钮;保留一个清晰的“立即识别”,连续模式另提供暂停/继续。
|
|
126
132
|
|
|
127
133
|
## 交付顺序
|
|
128
134
|
|
|
@@ -140,7 +146,9 @@ var voted = await V8.Vision.Stabilize({
|
|
|
140
146
|
## 禁止事项
|
|
141
147
|
|
|
142
148
|
- 禁止用 HTTP 200、构建成功、Mock UI、同一图片命中代替真实商品/人脸准确率。
|
|
143
|
-
- 禁止把大模型标签伪装成数据库命中或权威身份。
|
|
149
|
+
- 禁止把大模型标签伪装成数据库命中或权威身份。
|
|
150
|
+
- 禁止把 AI 新鲜度、冰冻状态或估价伪装成传感器、检疫、食品安全结论或正式售价。
|
|
151
|
+
- 禁止把历史识别的原始私有文件路径或永久公开 URL 返回前端,也禁止未经人工确认把 AI 结果自动沉淀为可信样本。
|
|
144
152
|
- 禁止在接口参数中接受模型目录、任意本地路径、任意网络地址或执行提供程序。
|
|
145
153
|
- 禁止把图片 Base64、原始人脸、向量、提示词、AI Key 写入 Hook 或普通日志。
|
|
146
154
|
- 禁止用进程内队列、`static` 字典或本地文件作为 AI 任务完成事实源。
|
|
@@ -149,4 +157,4 @@ var voted = await V8.Vision.Stabilize({
|
|
|
149
157
|
|
|
150
158
|
## 验收输出
|
|
151
159
|
|
|
152
|
-
最终报告至少分开列出:源码测试、5 表/字段/索引、7 菜单、5 引擎/4
|
|
160
|
+
最终报告至少分开列出:源码测试、5 表/字段/索引、7 菜单、5 引擎/4 事件、微服务源码与构建哈希、商城包与版本、框架制品、目标节点版本、真实浏览器、PC/手机横竖屏布局、历史图片与纠错、真实图片素材来源、数据库命中、AI 回退、生鲜属性/价格来源、人脸同意、模型准确率和未执行的物理设备测试。
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
| 表 | 主业务键 | 关键字段 |
|
|
6
6
|
|---|---|---|
|
|
7
7
|
| `mci_vision_category` | `CategoryNo` | Name、Scope、ParentId、Sort、Enabled |
|
|
8
|
-
| `mci_vision_subject` | `ObjectNo` | Name、CategoryId、ObjectType、RecognitionMode、ThresholdOverride、ReviewRequired |
|
|
9
|
-
| `mci_vision_sample` | `SampleNo` | SubjectId、Mode、ImagePath、EmbeddingBase64、ModelKey、QualityScore、Status |
|
|
10
|
-
| `mci_vision_request` | `RequestNo` | Mode、Status、MatchSource、StreamSessionId、FrameSequence、DetectionsJson、StabilityJson、AI
|
|
8
|
+
| `mci_vision_subject` | `ObjectNo` | Name、CategoryId、ObjectType、RecognitionMode、ThresholdOverride、ReviewRequired、默认价格/单位/币种 |
|
|
9
|
+
| `mci_vision_sample` | `SampleNo` | SubjectId、Mode、ImagePath、EmbeddingBase64、ModelKey、QualityScore、Status、冰冻/新鲜度/价格及来源请求 |
|
|
10
|
+
| `mci_vision_request` | `RequestNo` | Mode、Status、MatchSource、StreamSessionId、FrameSequence、DetectionsJson、StabilityJson、AI 字段、冰冻/新鲜度/价格及各自来源、纠错审计、耗时 |
|
|
11
11
|
| `mci_vision_profile` | `ProfileKey` | 两类 ModelKey/Threshold、TopK、CandidateLimit、HnswEfSearch、连续投票、AI 开关、取帧间隔、保留策略 |
|
|
12
12
|
|
|
13
13
|
数据库隔离租户的业务表物理层可能没有 `OsClient` 列;建索引前必须以 `microi_get_db_schema` 和物理索引回读为准。若当前部署是共享表租户模型,才把真实租户字段放到唯一索引前缀,不能机械套用。
|
|
@@ -30,12 +30,15 @@
|
|
|
30
30
|
| `LocalMatched` | `Database` | 是 | 当前模型版本样本达到阈值 |
|
|
31
31
|
| `AiPending` | `None` | 否 | 后台任务已接受 |
|
|
32
32
|
| `Unmatched` | `None` | 是 | 未命中且 AI 关闭 |
|
|
33
|
-
| `AiMatched` | `AI` | 是 | AI 标签已回写 |
|
|
33
|
+
| `AiMatched` | `AI` | 是 | AI 标签已回写 |
|
|
34
|
+
| `Corrected` | `Manual` | 是 | 用户已把结果修正为当前租户的可信对象 |
|
|
34
35
|
| `Failed` | `None` | 是 | 本地流水线或 Worker 最终失败 |
|
|
35
36
|
| `ManualReview` | `None` | 是 | 高风险场景需要人工复核 |
|
|
36
37
|
| `LowQuality` | `None` | 是 | 低于质量阈值 |
|
|
37
38
|
|
|
38
|
-
`Status` 与 `MatchSource` 必须一起返回。AI 成功不应填充 `SubjectId`,除非后续人工确认并通过正常业务接口绑定。
|
|
39
|
+
`Status` 与 `MatchSource` 必须一起返回。AI 成功不应填充 `SubjectId`,除非后续人工确认并通过正常业务接口绑定。
|
|
40
|
+
|
|
41
|
+
生鲜字段同样保留独立来源:`FrozenStateSource`、`FreshnessSource`、`PriceSource` 只能是 `Database/AI/Manual/None`。数据库命中时样本字段优先、对象默认价格次之;未命中后 AI 才能补充。价格是区间与单位估计,不是订单或称重结算事实。
|
|
39
42
|
|
|
40
43
|
## Runtime 请求
|
|
41
44
|
|
|
@@ -68,7 +71,7 @@ Face 模式必须 `ConsentConfirmed=true`;服务端不能只信任前端 check
|
|
|
68
71
|
|
|
69
72
|
轮询应在终态停止,并使用指数或有界间隔;页面卸载、取消或新帧覆盖旧帧时应中止旧轮询。
|
|
70
73
|
|
|
71
|
-
### Enroll
|
|
74
|
+
### Enroll
|
|
72
75
|
|
|
73
76
|
```json
|
|
74
77
|
{
|
|
@@ -80,11 +83,25 @@ Face 模式必须 `ConsentConfirmed=true`;服务端不能只信任前端 check
|
|
|
80
83
|
}
|
|
81
84
|
```
|
|
82
85
|
|
|
83
|
-
服务端读取对象的 Category/Mode,不能信任调用方自行提交 SubjectName、CategoryName 或 ModelKey。
|
|
86
|
+
服务端读取对象的 Category/Mode,不能信任调用方自行提交 SubjectName、CategoryName 或 ModelKey。
|
|
87
|
+
|
|
88
|
+
### Correct
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"Action": "Correct",
|
|
93
|
+
"RequestNo": "待修正识别记录",
|
|
94
|
+
"SubjectId": "当前租户正确对象Id",
|
|
95
|
+
"CorrectionReason": "人工复核原因",
|
|
96
|
+
"SaveAsSample": true
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
服务端必须重新读取请求和对象,校验租户、权限、启用状态与识别模式;保存原结果、修正人、时间和原因。`SaveAsSample=true` 时按来源请求幂等录入,不能因重试重复生成样本,也不能绕过正常 `Enroll` 的图片、质量、模型和人脸同意门禁。
|
|
84
101
|
|
|
85
102
|
## 公开结果最小字段
|
|
86
103
|
|
|
87
|
-
允许返回:RequestNo、FrameId、StreamSessionId、FrameSequence、Mode、Status、MatchSource、SubjectId/Name、CategoryId/Name、LocalSimilarity、Confidence、对象框/TrackId、Stability、AiLabel/Category/Description/Candidates、ModelKey/Version、ImageWidth/Height、QualityScore、RequestedAt、CompletedAt、ElapsedMs、ErrorMessage
|
|
104
|
+
允许返回:RequestNo、FrameId、StreamSessionId、FrameSequence、Mode、Status、MatchSource、SubjectId/Name、CategoryId/Name、LocalSimilarity、Confidence、对象框/TrackId、Stability、AiLabel/Category/Description/Candidates、FrozenState/Freshness/EstimatedPrice/Unit/Currency 及各自来源、ModelKey/Version、ImageWidth/Height、QualityScore、HasImage、短期授权 ImageUrl、RequestedAt、CompletedAt、ElapsedMs、ErrorMessage 和不含秘密的纠错审计摘要。
|
|
88
105
|
|
|
89
106
|
禁止返回:EmbeddingBase64、InputFilePath、图片 Base64、模型磁盘路径、AI Provider Key、系统提示词、后台任务内部载荷。
|
|
90
107
|
|
|
@@ -136,8 +153,11 @@ Face 模式必须 `ConsentConfirmed=true`;服务端不能只信任前端 check
|
|
|
136
153
|
- 数据库优先且 AI 不入队;
|
|
137
154
|
- 未命中 + AI 开启立即返回 AiPending;
|
|
138
155
|
- Worker 成功/失败/重复消费收敛;
|
|
139
|
-
- AI 关闭直接 Unmatched;
|
|
140
|
-
- 低质量不进入匹配;
|
|
156
|
+
- AI 关闭直接 Unmatched;
|
|
157
|
+
- 低质量不进入匹配;
|
|
158
|
+
- 生鲜字段数据库优先、AI 只在未命中后补充,字段来源不会串改;
|
|
159
|
+
- Correct 校验对象与模式、保存原结果和审计,SaveAsSample 按 RequestNo 幂等;
|
|
160
|
+
- Recent/Result 的历史图片只返回授权 URL,不返回原始私有路径;
|
|
141
161
|
- 受保护向量只能在同租户同核心引擎解开;
|
|
142
162
|
- Hook 不接收敏感载荷且 CreateIfMissing 不被升级覆盖。
|
|
143
163
|
|
|
@@ -146,8 +166,10 @@ Face 模式必须 `ConsentConfirmed=true`;服务端不能只信任前端 check
|
|
|
146
166
|
- 已登录真实菜单打开 MicroService,不是独立 Mock 页面;
|
|
147
167
|
- 桌面、窄屏、暗色、键盘焦点和文字对比度;
|
|
148
168
|
- 上传预览、清除、重复选择、错误格式/超限;
|
|
149
|
-
-
|
|
150
|
-
- Database/AiPending/AI/Unmatched/LowQuality/AiFailed
|
|
169
|
+
- 摄像头授权拒绝、成功、暂停、继续、强制当前帧、快速关闭与卸载清理;覆盖 getUserMedia/video.play 与关闭竞态;
|
|
170
|
+
- Database/AiPending/AI/Manual/Unmatched/LowQuality/AiFailed 状态和数据库→AI 两段进度;
|
|
171
|
+
- 桌面全宽三栏;390×844 竖屏和短横屏中采集、结果、最近记录同屏,页面级无纵向滚动且不被宿主底栏遮挡;
|
|
172
|
+
- 历史缩略图授权加载、原画弹窗、纠错和可选存样本;
|
|
151
173
|
- FaceConsent 默认未勾选,未同意按钮禁用且后端拒绝;
|
|
152
174
|
- Console/PageError/失败请求为 0 或逐项解释。
|
|
153
175
|
|