Skip to content

[IM] 设备语音直接消费的动作状态上报与跨入口同步 #214

Description

@JunLang-7

1. 目标

当用户直接对设备说“知道了”或“十分钟后提醒”,并由本地 TimingTask 成功消费提醒后,设备必须把这一本地最终事实主动上报给 IM Gateway。Gateway 据此收口同一 deviceId + reminderTriggerId 下尚未完成的 Action,使微信 H5 等其他入口不再继续显示可操作状态。

这解决的是“动作可从多个入口发生,但状态只有 H5 命令链能够更新”的缺口。

2. 用户场景

Given:

  • 同一强提醒已投递到微信公众号,H5 当前显示“知道了 / 稍后提醒”;
  • 设备本地仍拥有 ReminderTrigger 与 TimingTask 业务事实。

When:

  • 用户不打开 H5,而是直接对设备说“知道了”;或
  • 用户直接对设备说“十分钟后提醒”。

Then:

  • 设备先幂等更新本地 ReminderTrigger;
  • 设备把动作结果推送到 Gateway;
  • Gateway 更新同一提醒对应的 Action;
  • 用户再次打开或刷新 H5 时,只看到已处理状态和最终动作,不再看到操作按钮。

3. 设计规则

  1. 设备本地事实优先:Gateway 不直接修改 Schedule、TimingTask 或 ReminderTrigger,只接收设备已提交的动作事实。
  2. 跨入口使用同一业务键:状态归并以 deviceId + reminderTriggerId 为核心,不要求语音动作具备由 H5/SSE 生成的 commandId
  3. 一次本地动作只上报一次语义结果:设备生成稳定的 eventId/operationId;网络重试不得重复消费本地提醒,也不得在 Gateway 创建重复结果。
  4. 竞争入口只允许一个最终事实:H5 与语音并发操作时,以设备端实际提交成功的 ReminderTrigger 状态为准;Gateway 将其他仍可操作的 Action 收口为不可再消费状态,并保留来源与审计信息。
  5. 凭据与日志边界不变:沿用设备认证、TLS 和 correlationId;日志不得包含设备 Token、Action token 或语音原文。

4. 契约增量

新增或扩展一个不依赖 Gateway commandId 的设备侧状态上报契约(最终命名在实现前确认),至少包含:

字段 约束
schemaVersion 版本化契约
eventId 上报幂等键
correlationId 跨设备、Gateway、Delivery、Action 追踪
deviceId 必须与设备凭据一致
reminderTriggerId 跨入口归并键
operationId 本地动作幂等键
action acknowledgesnooze
status 本地已提交结果;失败不得伪报成功
occurredAt ISO 8601
nextTriggerAt snooze 成功时必填
source 本期固定支持 voice,不得依赖语音原文

现有带 commandIdReminderActionResult 继续用于 H5 → SSE → 设备命令回执;本 Issue 不要求强行伪造 commandId

5. 范围

  • 定义 C++/TypeScript 共享 fixture 与版本化状态上报契约;
  • 设备在语音动作成功提交到 TimingTask 后触发可靠、可重试的状态上报;
  • Gateway 使用设备凭据校验 deviceId,按 eventId/operationId 幂等处理;
  • Gateway 按 deviceId + reminderTriggerId 更新或收口相关 Action,并记录动作来源;
  • Action UI 查询统一状态;语音已消费后刷新页面不再显示按钮;
  • correlationId 贯穿本地动作、状态上报、Gateway Action 状态更新;
  • 覆盖语音与 H5 并发、重复上报、乱序到达、过期 Action、snooze 的 nextTriggerAt

6. 非目标

  • 不让 Gateway 成为 ReminderTrigger 的事实源;
  • 不把语音音频、ASR 原文或 NLU 中间结果上传到 Gateway;
  • 不在本 Issue 增加新的 IM 平台;
  • 不要求 Action UI 使用 WebSocket/SSE 自动刷新;本期要求重新打开或刷新后状态一致。浏览器实时更新可单独评估;
  • 不替代 接续 #127:把设备侧动作通道接入运行时并打通通知流调用链 #179 的设备运行时装配与 H5 命令通道接入。

7. TDD 与验收

RED:

  • 语音“知道了”成功后,H5 刷新仍错误显示操作按钮;
  • 语音“十分钟后提醒”无法向 Gateway 表达 nextTriggerAt
  • 相同事件重试会重复写入或重复迁移 Action;
  • H5 与语音并发会产生两个互相冲突的成功结果。

GREEN:

  • 设备本地动作成功后,状态上报在网络恢复时可重试;
  • Gateway 幂等接收并收口同一提醒的可操作 Action;
  • H5 刷新显示“已通过语音处理”及 acknowledge/snooze 结果;
  • snooze 的下一次触发时间与设备本地事实一致;
  • 冲突与乱序不会把终态回退为可操作状态。

自动验证:

  • C++ 与 TypeScript 对共享 fixture 的字段、枚举和校验一致;
  • 主机测试覆盖本地动作提交后才允许上报;
  • Gateway 测试覆盖幂等、归并、冲突、过期和 Action UI 状态;
  • ./scripts/run_checks.shpnpm --dir services/im-gateway ci 通过。

真机验收:

  • 真机收到强提醒并完成公众号投递;
  • 用户仅通过语音执行“知道了”,Gateway 收到一次语义结果,H5 刷新为不可操作终态;
  • 用户仅通过语音执行“十分钟后提醒”,Gateway 与设备展示相同的 nextTriggerAt
  • 上报期间断网并恢复后,设备本地只执行一次,Gateway 最终只接受一个结果;
  • 验收记录包含固件/Gateway commit、脱敏日志与 correlationId

8. 依赖与关系

Refs #95, #152, #179

Metadata

Metadata

Assignees

No one assigned

    Labels

    FullSpec规格粒度-影响面大的完整规格proposal产品设计-该 Issue是一个产品提案

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions