Files
yovision/docs/raw/10-Sense原型-功能模块缺口.md
T

265 lines
12 KiB
Markdown
Raw Normal View History

2026-08-04 14:46:12 +08:00
# Sense 原型:功能与模块缺口分析
> 对标:`docs/02-requirements.md` §3.1/§3.5/§4、`docs/04-architecture.md` §3/§6/§7/§8/§10、`docs/07-user-stories.md` US-001/002/007、`docs/routes.md`、`docs/api.md` §2
> 基准:`yovision-T-004/docs/design/sense/index.html`(codex,2026-08-04)
> 与《09-Sense原型评审-IX草稿》的区别:09 谈**行为缺口**(某状态没画),本文谈**模块缺口**(整个页面或实体不存在)
> 日期:2026-08-04
---
## 0. 判定基准
Sense 的交付窗口是 M1–M2(架构 §10):
> M1 只动 Sense,5 路接入骨架与 MediaMTX。
> M2 仍以 Sense 为主,完成 **16 路开通/停用、对账、多租户投影与隧道**。
所以判定标准是 **M2 出口**,不是 M1。原型现在覆盖的是"设备列表 + 详情 + 导入",大致相当于 M1 的一半。
### 现有信息架构
```
运行总览 · 实时监控 · 摄像头 · 接入任务 · 系统状态
└─ 详情:基本信息 / 画面与检测区域 / 流与健康 / 操作记录
```
### 实体链断了两级
架构 §8 定义的核心实体是:
```
Tenant → Site → Area/Device → StreamBinding/Zone
```
原型里 **Tenant 不存在**,**Site 是顶栏一行静态文字**,**Area 退化成添加对话框里的一个下拉**。只有 Device 和 Zone 是真的。
---
## 1. P0 缺口 —— M2 出口必需,现在完全没有
### 1.1 站点管理(模块级缺失)
顶栏写死「青藤寄宿学校 / 主校区 · 16 / 16 路」,不可切换,没有站点列表。`routes.md` 有 `/sites`(站点列表、配额与状态)。
M2 的出口标准里明写"多租户投影",而多站点是它的最小可见形态。
| 需要什么 | 依据 |
| --- | --- |
| 站点列表:名称、配额已用/上限、在线率、未收敛数、边缘节点状态 | `routes.md` `/sites` |
| 站点切换器(顶栏),切换后所有列表按站点过滤 | 架构 §3 SaaS-ready 边界 |
| 站点配额的**只读**展示 + 来源标注「由 Bell 持有」 | 架构 §5 第 7 条 |
| 跨站点的设备总览(实施工程师同时开通多个站点) | US-001 |
### 1.2 对账器运维视图(Sense 的心脏,只有一个数字)
总览有「待收敛项 **2**」,**点不进去**。架构 §7 用了整节讲对账语义,UI 只暴露了一个计数。
`routes.md` 有 `/operations`(设备/流/分片/对账运维,不与业务预警混在同一队列)。
| 需要什么 | 依据 |
| --- | --- |
| 未收敛项列表,每项显示**期望态 vs 实际态的具体差异** | 架构 §7「PostgreSQL 是期望态真相源」 |
| 每项的重试次数、当前退避间隔、下次重试时间 | 架构 §7「幂等、指数退避、限制并发」 |
| **孤儿资源列表 + 10% 安全闸触发告警** | 架构 §7「孤儿删除必须有 10% 安全闸和人工可观察指标」 |
| 手动触发单项收敛(总览的"立即对账"是全局的,粒度太粗) | — |
| 收敛持续失败的升级路径:多久算异常、通知谁 | §3.5 运维告警独立 |
> 这是原型最大的单点缺口。对账器是 Sense 区别于普通 NVR 的**全部理由**,现在在 UI 上等于不存在。
### 1.3 待激活设备的处置闭环
`02-requirements` §3.1 明确「支持待激活中间态」,添加对话框的按钮也确实写着「保存为待激活」。但:
- 设备表 5 行假数据里**没有一行是待激活**
- 筛选下拉只有「全部状态 / 异常 / 重连中」,**没有待激活**
- 待激活设备如何激活、如何补凭据、如何丢弃——零流程
| 需要什么 |
| --- |
| 待激活作为一级筛选项与独立计数 |
| 待激活 → 激活的校验流程(重新探测 Profiles / 校时 / 配额复核) |
| 批量激活与逐项结果 |
| 长期待激活的过期策略(放着不管会变成配额占用的幽灵) |
### 1.4 凭据更新与认证失败恢复
详情页写「凭据:已安全保存,页面不可见」——处理正确,但**只有读没有写**。
M0 验收专门要求记录「认证失败」(`02-requirements` §2),而现场改密码是最高频的运维事件。
| 需要什么 |
| --- |
| 单设备「更新凭据」动作(只写不读,不回显任何已存值) |
| 认证失败作为独立的实际态(区别于「离线」——原因不同,处置不同) |
| 批量更新凭据(一批摄像头同时改密是常态) |
| 更新后自动重试接入,结果可见 |
### 1.5 权限与角色(完全没有)
`02-requirements` §3.5 定义最小 RBAC 五角色:平台管理员 / 租户管理员 / 站点管理员 / 值班员 / 只读。`routes.md` 有完整的路由守卫要求。
原型没有登录、没有当前用户、没有任何权限差异表达。
| 需要什么 |
| --- |
| 顶栏当前用户与角色 |
| 只读角色下:添加/停用/删除/更新凭据**不出现**(不是置灰) |
| 越权深链的统一拒绝态(`routes.md`「深链打开无权限或已删除资源时给出统一、安全的反馈」) |
| 站点管理员只能看到自己站点 |
> 权限不是"以后加的一层"。它决定页面上**有没有**这个按钮,是信息架构问题,必须在原型里枚举。
### 1.6 配额服务降级态
`api.md` §2 精确定义了这个失败语义:
> Sense → Bell 读取站点视频配额:失败时**拒绝新增/启用但不影响已有流**
原型显示「已用 16 / 128」「配额 16 / 128」,但错误态只有一个「边缘节点不可达」。配额服务不可达是**另一种**故障,表现完全不同:视频照常播、列表照常看、只有写操作被拒。
| 需要什么 |
| --- |
| 配额不可读时的横幅:说明"当前无法新增或启用设备,已有视频不受影响" |
| 添加/激活按钮在该状态下禁用并说明原因 |
| 与「边缘节点不可达」区分开——后者是读故障,前者是写故障 |
---
## 2. P1 缺口 —— M2 内补齐
### 2.1 边缘节点与隧道
侧栏底部只有一行 `sense-edge-01 · 在线`。但边缘节点在架构里是独立实体,承担推流、本地环形缓冲、断网续传、WireGuard 隧道。
`02-requirements` §3.5:**断网时边缘缓存事件,恢复后补传。**
| 需要什么 |
| --- |
| 边缘节点列表:版本、在线时长、隧道状态、承载设备数 |
| 本地缓存水位 + 补传进度(断网 2 小时后恢复,用户要看到"正在补传 380 条") |
| 隧道断开时的明确表达:**控制面断了但视频还在推**(这是控制面/数据面分离的核心,UI 不体现等于白设计) |
| 边缘节点升级/重启动作 |
### 2.2 设备能力档案
添加时「测试连接」返回「2 个 Profile,时间漂移 +0.4s」,但这个结果**没有落地成设备的持久属性**。
US-007 要求记录:型号、固件、认证方式、Profiles/StreamUri/校时、主子码流、掉线恢复——形成采购白名单。
| 需要什么 |
| --- |
| 详情页「设备能力」区:厂商、型号、固件版本、认证方式 |
| Profile 列表(分辨率/帧率/编码),标注当前使用哪个 |
| 能力标记:是否支持校时、**是否支持 ONVIF 事件订阅**(决定它能否作为设备型触发源) |
| 与采购白名单的关联:该型号是否在白名单内 |
### 2.3 主/子码流切换
详情写死「Profile:子码流 704 × 576 · 5 FPS」,没有切换动作。
架构 §6:`media_shard.max_streams` 由**码率**决定。码流选择是容量的直接变量,必须可配。切换还会踢掉当前发布者(mediamtx 的硬约束),需要影响范围提示。
### 2.4 分片详情与设备迁移
总览显示 `media-01 8/32`、`media-02 8/32`,只读。
| 需要什么 |
| --- |
| 分片详情:承载设备清单、实际码率、重连历史 |
| 把设备从一个分片迁到另一个(迁移会中断该路,需确认) |
| 单分片故障时的影响范围展示(架构 §6「单分片故障不能扩散到其他分片」) |
| **`media_shard.max_streams` 的 32 需与《04》§6 对齐**——文档写「初始建议 32,可按故障域降为 16」,原型的 32 有据,但需标注它是可配置项而非固定值 |
### 2.5 批量任务列表与逐项结果
「当前任务」是单个卡片,「查看逐项结果」是个死按钮。
IX-001 要求:下载模板、上传校验、**逐行错误**、重复序列号、待激活、确认写入。
| 需要什么 |
| --- |
| 任务列表(历史任务可查、可重试、可导出错误清单) |
| 逐项结果页:每行的校验结果、失败原因、单行重试 |
| 上传前的本地预校验结果(原型文案已提到,但没有页面) |
| 部分成功的语义:8 路里 5 成功 3 失败,成功的已生效 |
### 2.6 Sense 运维告警
总览有「今日设备告警 3」和「与业务预警分开」的说明——**这个说明写得很好**,但点不进去。
`02-requirements` §3.4:业务预警与运维告警使用**不同通道和值班配置**。
| 需要什么 |
| --- |
| 运维告警列表(设备离线、时间漂移超阈、收敛失败、分片异常、隧道断开) |
| 静默与通知配置(运维侧的,与 Bell 的业务静默是两套) |
| 明确标注"这些不会推给家属/值班员" |
---
## 3. P2 缺口 —— M3 留出信息架构位置
不必现在实现,但导航和详情页要留位,否则 M3 时又是整页重做。
| # | 模块 | 依据 |
| --- | --- | --- |
| 1 | **推理绑定视图**:设备 ↔ inference worker 的绑定、worker 注册/心跳/容量、绑定失败态 | `api.md` §2「Worker → 控制面:注册、心跳、容量」;总览已有「推理绑定 16/16」但无下钻 |
| 2 | **pre-roll 切片运维**:切片请求量、失败率、耗时 | 架构 §5 第 3 条「pre-roll 由 Bell 发起、Sense 切片」 |
| 3 | **设备型触发源**:雷达/门磁/按钮/ONVIF 事件订阅的配置与状态 | 《08》§3 边界 2;与 IX-014 的 modality 是一体的 |
---
## 4. 两个横切问题
### 4.1 时间显示口径没有定义
操作记录显示裸时间「22:52」。但 Sense 这个系统里同时存在**三个时钟**:
- 设备时间(ONVIF 报的,可能漂 +3.8s)
- 服务器时间(期望态真相源)
- 浏览器本地时间(用户看到的)
而「时间漂移」正是原型自己列为一级列的指标。三个时钟不区分,运维会误判。
**需要**:统一时间显示口径(建议全部显示服务器时间 + 时区标注,设备时间只在漂移列出现),相对时间与绝对时间并存("2 分钟前"悬停显示完整时间戳)。
### 4.2 租户维度不存在
架构 §3:首期一客户一套私有实例,但「数据库实体、RBAC、配置与 API 从第一版携带 `tenant_id` 并保持 SaaS-ready 边界」。
原型没有任何租户表达。首期不需要租户**切换器**,但需要:当前租户的显示、以及所有列表默认按租户过滤的事实在 UI 上可见。否则实现时容易写成全局查询,SaaS-ready 边界在第一版就破了。
---
## 5. 汇总:建议加入的导航
现有五项 → 建议八项(新增三项加粗):
```
运行总览
实时监控
设备 ← 原「摄像头」,改名以容纳 modality(见 IX-014)
接入任务
**站点与区域** ← 新增:站点列表、配额、Area 管理(含隐私区域标记)
**运维** ← 新增:对账队列、孤儿资源、分片、边缘节点与隧道、运维告警
系统状态
**审计** ← 新增:设备操作审计入口(主真相源在 Bell,Sense 需入口)
```
顶栏需要补:站点切换器、当前用户与角色。
---
## 6. 优先级建议
| 顺序 | 做什么 | 理由 |
| --- | --- | --- |
| 1 | **对账器运维视图**(§1.2) | 单点最大缺口。这是 Sense 的存在理由,现在 UI 上等于不存在 |
| 2 | **权限与角色**(§1.5) | 决定页面上有没有按钮,是 IA 问题不是加一层 |
| 3 | **站点与区域**(§1.1) | 实体链断了两级,Area 还是隐私区域约束的挂载点 |
| 4 | 待激活闭环、凭据更新、配额降级态(§1.3–1.6) | 都是需求文档已明确定义、原型未表达的行为 |
| 5 | P1 六项 | M2 出口前补齐 |
| 6 | P2 三项只留导航位 | 不实现,避免 M3 整页重做 |
> §1.5(权限)与《09》的 IX-014(modality)都是**改信息架构**的改动,建议合并到同一次原型重生成里,不要分两次打补丁。