feat(v1): add local alerts, screenshot and JSONL event log

AlertDispatcher de-duplicates by event_id and fires each side effect once
per CONFIRMED: annotated screenshot, one JSONL line (config_version,
source_id, no rtsp/credentials), sound and popup via injectable sink.
44 tests pass; real-frame artifact smoke verified.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ila
2026-07-21 19:49:20 +08:00
co-authored by Claude Opus 4.8
parent 861532ffb0
commit afe7a5e781
8 changed files with 347 additions and 7 deletions
+17
View File
@@ -76,6 +76,23 @@ FallEvent = {
`FallEvent` 是状态机的纯内存确认事件,只在状态首次进入 `CONFIRMED` 时创建一次。连续帧更新 UI 状态,但不重复创建事件。`config_version` 是由运行配置快照计算的非敏感版本标识;T-202 的 `alerts` 会在不改变事件幂等语义的前提下,为截图/JSONL 记录补充来源、UTC 时间和证据。
T-202 的 `alerts` 按 `event_id` 去重,对首次 CONFIRMED 只触发一次副作用(声音、弹窗、截图、JSONL 一行)。JSONL 记录如下,文件名与字段不含 RTSP 地址、凭证或客户姓名:
```text
AlertRecord(JSONL) = {
event_id: string,
track_id: string,
config_version: string,
source_id: string,
state: "CONFIRMED",
confirmed_at_utc: string, # ISO-8601 UTC
suspected_at_monotonic: float,
confirmed_at_monotonic: float,
latency_seconds: float,
screenshot: string # 相对 event_dir 的 "YYYYMMDD/FALL-xxxxxx.png"
}
```
`PersonPose` 是 T-103 的纯模型输出,不带人员 ID;T-104 的跟踪模块产生 `TrackedPersonPose` 后,才允许事件证据按人员连续积累。
## 视频来源帧合约