2026-08-03 22:18:02 +08:00
|
|
|
|
# API 与契约
|
|
|
|
|
|
|
2026-08-11 00:24:32 +08:00
|
|
|
|
> Brain → Bell 事件契约 v0.1、Sense Control API v1、Bell 配额/Area 只读投影 v1、Sense 本地设备审计事件 v1/v2 与 Sense→Bell 审计 relay v1 已冻结;其他 API 仍在设计阶段。不得把本文的“待定”自行具体化为公共契约。
|
2026-08-03 22:18:02 +08:00
|
|
|
|
|
|
|
|
|
|
## 1. 已冻结:Brain → Bell 事件契约
|
|
|
|
|
|
|
|
|
|
|
|
- Schema:[`raw/contracts/event-v0.1.schema.json`](raw/contracts/event-v0.1.schema.json)
|
|
|
|
|
|
- 语义、kind 注册表、映射和代码级断言:[`raw/contracts/README.md`](raw/contracts/README.md)
|
|
|
|
|
|
- 示例:`raw/contracts/event-v0.1.example-*.json`
|
|
|
|
|
|
|
|
|
|
|
|
关键规则:
|
|
|
|
|
|
|
|
|
|
|
|
- 顶层未知字段拒绝;扩展只能放 `ext`。
|
|
|
|
|
|
- Brain 提供 `source_event_id`,Bell 生成平台 ULID。
|
|
|
|
|
|
- `confidence` 允许 null,当前判定链路必须为 null。
|
|
|
|
|
|
- `detected_at >= occurred_at`,时间与 `latency_seconds` 自洽。
|
|
|
|
|
|
- 证据文件名只含事件 ID 与日期目录,不含 IP、端口、凭据或客户名。
|
|
|
|
|
|
- `sensors` 中恰有一个 primary,且其 `device_id` 与顶层一致。
|
|
|
|
|
|
|
2026-08-10 23:53:11 +08:00
|
|
|
|
T-015 已实现 Bell 消费端的内部组装与存储边界:可信 ingress 先接收“不含平台 `id`”的候选事实,Bell 生成 `evt_` ULID 后形成最终 v0.1 对象,再执行 schema 与六项代码断言并不可变落库。该候选类型是 Bell 内部 port,不是 Brain 可依赖的 HTTP/消息总线协议;transport、认证和重放语义仍由后续任务冻结。
|
|
|
|
|
|
|
2026-08-07 17:12:15 +08:00
|
|
|
|
## 2. 跨系统接口状态
|
2026-08-03 22:18:02 +08:00
|
|
|
|
|
|
|
|
|
|
| 调用方 → 提供方 | 用途 | 当前约束 | 状态 |
|
|
|
|
|
|
| --- | --- | --- | --- |
|
2026-08-07 17:52:50 +08:00
|
|
|
|
| Sense → Bell | 读取站点视频配额 | 同一 PostgreSQL 实例内只读 `bell.site_quota_v1`;默认 16、最大 128;失败时拒绝新增/启用但不影响已有流 | T-008 冻结,T-009 已实现数据路径 |
|
2026-08-07 18:23:24 +08:00
|
|
|
|
| Sense → Bell | 读取 Area 成像准入 | 只读 `bell.area_policy_v1`;`video_allowed | non_imaging_only`;缺失/非法/回退失败关闭但不影响已有设备 | T-010 已冻结并实现数据路径 |
|
2026-08-11 00:24:32 +08:00
|
|
|
|
| Sense → Bell | 汇入设备操作审计 | `POST /internal/v1/audit-events:batch`;1~100 项、1 MiB、10 秒 deadline、HMAC/nonce、逐项确认;非回环必须 HTTPS | T-016 已冻结并实现 |
|
2026-08-03 22:18:02 +08:00
|
|
|
|
| Bell → Sense | 请求事件证据/pre-roll 切片 | 幂等、按租户授权、异步结果、不得暴露原始凭据 | 待 M3 设计 |
|
|
|
|
|
|
| Bell → Brain | outcome/误报反馈 | 原事件不可变;反馈可重试、去重、审计 | 待 M3 设计 |
|
|
|
|
|
|
| Sense → Brain | 流绑定与设备型触发 | 分片可路由,触发入口与流控制解耦 | 待 M2/M3 设计 |
|
|
|
|
|
|
| Worker → 控制面 | 注册、心跳、容量 | `max_sources` 来自 profile/压测,不固定为 16 | 待 M3 设计 |
|
|
|
|
|
|
|
2026-08-11 00:24:32 +08:00
|
|
|
|
冻结签名和失败语义见 [`contracts/README.md`](contracts/README.md)、[`contracts/sense-audit-relay-v1.openapi.json`](contracts/sense-audit-relay-v1.openapi.json)、[`contracts/site-quota-v1.sql`](contracts/site-quota-v1.sql)、[`contracts/area-policy-v1.sql`](contracts/area-policy-v1.sql) 与 [`contracts/sense-device-audit-v1.schema.json`](contracts/sense-device-audit-v1.schema.json)。Bell 拥有投影源数据和视图,Sense 数据库角色只有 `SELECT`;未来分库必须发布新版本,不能在 v1 下把本地视图静默替换为网络调用。
|
2026-08-07 17:12:15 +08:00
|
|
|
|
|
|
|
|
|
|
## 3. 已冻结:Sense Control API v1
|
|
|
|
|
|
|
|
|
|
|
|
- OpenAPI:[`contracts/sense-control-v1.openapi.json`](contracts/sense-control-v1.openapi.json)
|
|
|
|
|
|
- 语义、资源所有权、幂等、并发与兼容规则:[`contracts/README.md`](contracts/README.md)
|
|
|
|
|
|
- 范围:设备分页查询、创建、读取、修改、单项启停、最多 128 项的批量启停和批量操作查询。
|
|
|
|
|
|
|
|
|
|
|
|
关键规则:
|
|
|
|
|
|
|
|
|
|
|
|
- 所有业务路径使用 `/api/v1` 和 Bearer 认证;tenant 只来自认证上下文,跨租户访问与不存在统一为 `404 not_found`。
|
|
|
|
|
|
- Site、Area、RBAC、配额和全局审计仍由 Bell 持有;Sense 只管理 Device 期望态和收敛状态,不提供这些 Bell 资源的 CRUD。
|
|
|
|
|
|
- 列表使用稳定顺序和不透明 cursor,默认 50、最大 100;创建与批量写要求 `Idempotency-Key`,资源修改与单项期望态写要求 `If-Match`。
|
|
|
|
|
|
- `endpoint_ref`、`credential_ref`、`profile_token` 只写不读;设备 ID 由服务端生成。普通响应和错误不得包含凭据、完整流 URI、token 或 MediaMTX 内部配置。
|
|
|
|
|
|
- v1 不提供删除设备;停用设备保留历史。写入受理只表示期望态已持久化,不能表示实际态已收敛。
|
|
|
|
|
|
|
2026-08-11 00:24:32 +08:00
|
|
|
|
T-008 冻结公共控制契约;T-009/T-010 建立 PostgreSQL 投影、准入和本地审计基础;T-011 已实现 7 个 HTTP handler、外部静态摘要认证适配器、tenant/Site scope、幂等收据、ETag/HMAC cursor 和持久化 batch operation。业务路由默认关闭且仅可在 PostgreSQL 上开启;T-016 的审计 relay 是独立内部端点,不替代 Bell 管理服务或 JWT/OIDC。
|
2026-08-07 17:12:15 +08:00
|
|
|
|
|
|
|
|
|
|
## 4. 待冻结的 Bell 公共 API
|
2026-08-03 22:18:02 +08:00
|
|
|
|
|
|
|
|
|
|
资源范围预计包括:租户、站点、设备只读投影、规则、事件、预警、ack、处置、误报反馈、审计和报表。设计时必须满足:
|
|
|
|
|
|
|
|
|
|
|
|
- URL 版本化,例如 `/api/v1/...`;具体路径须由对应任务冻结。
|
|
|
|
|
|
- 租户从认证上下文确定,不信任客户端随意传入的 tenant ID。
|
|
|
|
|
|
- 列表强制分页、稳定排序和可组合筛选;批量操作返回逐项结果。
|
|
|
|
|
|
- 写操作支持幂等键或等价机制;并发更新使用版本/ETag 或明确冲突响应。
|
|
|
|
|
|
- 错误体包含稳定错误码、可读消息和 trace ID,不返回内部堆栈或凭据。
|
|
|
|
|
|
- 人脸功能未授权时表现为能力不存在,而非仅按钮置灰。
|
|
|
|
|
|
|
2026-08-07 17:12:15 +08:00
|
|
|
|
## 5. MediaMTX 接口边界
|
2026-08-03 22:18:02 +08:00
|
|
|
|
|
|
|
|
|
|
Sense 使用 MediaMTX 官方 OpenAPI 生成客户端并加薄封装。业务代码不得散落硬编码 path API;生成代码不可手改。MediaMTX path 不是租户/站点/设备的业务真相源。
|
|
|
|
|
|
|
2026-08-07 17:12:15 +08:00
|
|
|
|
### 5.1 T-003 已实现的内部适配契约
|
2026-08-04 15:45:50 +08:00
|
|
|
|
|
|
|
|
|
|
以下是 Sense 内部 Go port,不是 Bell 或第三方可依赖的公共 HTTP API:
|
|
|
|
|
|
|
|
|
|
|
|
| Port | 操作 | 数据所有者 / 失败语义 |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| ONVIF adapter | `Probe(target)`、`SetSystemDateAndTime(target, time)` | 设备是外部来源;`target` 只含 endpoint ref 与不透明 credential ref。错误稳定映射为认证失败、超时、不可用、响应无效,不记录凭据或完整流地址 |
|
2026-08-07 23:00:03 +08:00
|
|
|
|
| MediaMTX paths | `CreatePath`、`GetPath`、`EnsurePath`、`DeletePath`、`PathReady`、`ListPathNames` | 设备台账持有期望态,MediaMTX 只持有运行配置;分页枚举只返回名称、不返回 source。普通调和只操作精确台账 Path;独立孤儿流程只报告未知归属,受控处置只接受有历史归属的 stale Path |
|
2026-08-07 18:23:24 +08:00
|
|
|
|
| Device repository | 设备、期望态、实际态、调和进度 | SQLite 是 M1 默认开发路径;PostgreSQL 是 M2 生产路径并只读 Site/Area 两个 Bell 视图。调和退避持久化;配额/Area 失败时拒绝相关新增或启用,不关闭已有流;高风险写入与脱敏 Outbox 同事务 |
|
2026-08-04 15:45:50 +08:00
|
|
|
|
|
2026-08-07 23:00:03 +08:00
|
|
|
|
MediaMTX 薄封装调用同版官方 OpenAPI 的 `/v3/config/paths/get|add|patch|delete/{name}`、`/v3/config/paths/list` 与 `/v3/paths/get/{name}`。列表有最大页数和重复页保护,source URI 在薄封装内丢弃。生成源、版本和 SHA-256 见 `docs/03-tech-stack.md`;业务包不得直接 import 生成包。
|
2026-08-04 15:45:50 +08:00
|
|
|
|
|
2026-08-07 17:12:15 +08:00
|
|
|
|
### 5.2 设备台账语义
|
2026-08-04 15:45:50 +08:00
|
|
|
|
|
|
|
|
|
|
- 设备类型由 `modality` 表达物理类别,由多值 `capabilities` 表达视频采集、音频、空间规则或遥测能力,避免把“摄像头”固化为唯一设备模型。
|
|
|
|
|
|
- 视频配额只统计 `desired_state=enabled` 且具有 `video_capture` capability 的设备;站点默认 16、可配置 1~128。禁用设备和非视频传感器不占视频路数。
|
2026-08-07 18:23:24 +08:00
|
|
|
|
- SQLite 表使用 `sense_` 前缀且只是 M1 实验室兼容路径;PostgreSQL 使用 `sense.devices`、能力/调和表、两个投影观察表和 `sense.device_operation_outbox`。PostgreSQL 不建立可写 Site/Area 真相副本;后续公共控制 API 只在 PostgreSQL 路径启用,不能把 SQLite 描述为 Area/Outbox 生产等价实现。
|
2026-08-04 15:45:50 +08:00
|
|
|
|
- 摄像头密码不进入设备普通字段。`credential_ref` 只保存外部密钥引用;ONVIF 返回的 stream URI 只在内存中传给 MediaMTX,不写入设备台账或日志。
|
|
|
|
|
|
|
2026-08-07 17:12:15 +08:00
|
|
|
|
### 5.3 Sense 进程 HTTP 面
|
2026-08-04 15:45:50 +08:00
|
|
|
|
|
2026-08-07 23:00:03 +08:00
|
|
|
|
`GET /healthz` 表示进程存活,`GET /readyz` 表示所选数据库已打开且 schema/权限前置检查完成;两者不要求认证,也不等价于摄像头、MediaMTX path 或里程碑健康。`GET /metrics` 默认输出无租户/设备/Path 标签的 Prometheus 汇总,可通过 `SENSE_METRICS_ENABLED=false` 关闭。T-011 在 `SENSE_CONTROL_API_ENABLED=true`、PostgreSQL v5 schema 和外部安全文件全部有效时注册冻结的 `/api/v1` 路由;默认 SQLite 不注册业务路由。业务路由不提供无 Site 边界的 `/api/v1/devices` 临时接口。
|
|
|
|
|
|
|
|
|
|
|
|
孤儿报告/处置不是公共 HTTP API。它由 PostgreSQL 专用 `cmd/sense-orphan` 在受控运维主机执行,使用 15 分钟 scan ID、actor、精确确认文本和运行前二次快照;不改变 Sense Control API v1 的 7 个 endpoint。
|
2026-08-04 15:45:50 +08:00
|
|
|
|
|
2026-08-07 17:12:15 +08:00
|
|
|
|
## 6. 变更流程
|
2026-08-03 22:18:02 +08:00
|
|
|
|
|
|
|
|
|
|
1. 在对应任务文件写清调用方、提供方、数据所有者、失败语义、幂等与兼容策略。
|
|
|
|
|
|
2. 更新本文和 schema/OpenAPI。
|
|
|
|
|
|
3. 同步生产者、消费者、契约测试和示例。
|
|
|
|
|
|
4. 记录迁移、回滚与版本废弃策略。
|
|
|
|
|
|
|
2026-08-07 18:23:24 +08:00
|
|
|
|
事件 v0.1、Sense Control API v1、配额/Area 投影 v1 或本地设备审计 v1 的破坏性变化必须发布新版本,不能原地修改已被生产者/消费者使用的契约。
|