1. 目标
当用户直接对设备说“知道了”或“十分钟后提醒”,并由本地 TimingTask 成功消费提醒后,设备必须把这一本地最终事实主动上报给 IM Gateway。Gateway 据此收口同一 deviceId + reminderTriggerId 下尚未完成的 Action,使微信 H5 等其他入口不再继续显示可操作状态。
这解决的是“动作可从多个入口发生,但状态只有 H5 命令链能够更新”的缺口。
2. 用户场景
Given:
同一强提醒已投递到微信公众号,H5 当前显示“知道了 / 稍后提醒”;
设备本地仍拥有 ReminderTrigger 与 TimingTask 业务事实。
When:
用户不打开 H5,而是直接对设备说“知道了”;或
用户直接对设备说“十分钟后提醒”。
Then:
设备先幂等更新本地 ReminderTrigger;
设备把动作结果推送到 Gateway;
Gateway 更新同一提醒对应的 Action;
用户再次打开或刷新 H5 时,只看到已处理状态和最终动作,不再看到操作按钮。
3. 设计规则
设备本地事实优先 :Gateway 不直接修改 Schedule、TimingTask 或 ReminderTrigger,只接收设备已提交的动作事实。
跨入口使用同一业务键 :状态归并以 deviceId + reminderTriggerId 为核心,不要求语音动作具备由 H5/SSE 生成的 commandId。
一次本地动作只上报一次语义结果 :设备生成稳定的 eventId/operationId;网络重试不得重复消费本地提醒,也不得在 Gateway 创建重复结果。
竞争入口只允许一个最终事实 :H5 与语音并发操作时,以设备端实际提交成功的 ReminderTrigger 状态为准;Gateway 将其他仍可操作的 Action 收口为不可再消费状态,并保留来源与审计信息。
凭据与日志边界不变 :沿用设备认证、TLS 和 correlationId;日志不得包含设备 Token、Action token 或语音原文。
4. 契约增量
新增或扩展一个不依赖 Gateway commandId 的设备侧状态上报契约(最终命名在实现前确认),至少包含:
字段
约束
schemaVersion
版本化契约
eventId
上报幂等键
correlationId
跨设备、Gateway、Delivery、Action 追踪
deviceId
必须与设备凭据一致
reminderTriggerId
跨入口归并键
operationId
本地动作幂等键
action
acknowledge 或 snooze
status
本地已提交结果;失败不得伪报成功
occurredAt
ISO 8601
nextTriggerAt
snooze 成功时必填
source
本期固定支持 voice,不得依赖语音原文
现有带 commandId 的 ReminderActionResult 继续用于 H5 → SSE → 设备命令回执;本 Issue 不要求强行伪造 commandId。
5. 范围
6. 非目标
不让 Gateway 成为 ReminderTrigger 的事实源;
不把语音音频、ASR 原文或 NLU 中间结果上传到 Gateway;
不在本 Issue 增加新的 IM 平台;
不要求 Action UI 使用 WebSocket/SSE 自动刷新;本期要求重新打开或刷新后状态一致。浏览器实时更新可单独评估;
不替代 接续 #127:把设备侧动作通道接入运行时并打通通知流调用链 #179 的设备运行时装配与 H5 命令通道接入。
7. TDD 与验收
RED:
GREEN:
自动验证:
真机验收:
8. 依赖与关系
Refs #95 , #152 , #179
1. 目标
当用户直接对设备说“知道了”或“十分钟后提醒”,并由本地 TimingTask 成功消费提醒后,设备必须把这一本地最终事实主动上报给 IM Gateway。Gateway 据此收口同一
deviceId + reminderTriggerId下尚未完成的 Action,使微信 H5 等其他入口不再继续显示可操作状态。这解决的是“动作可从多个入口发生,但状态只有 H5 命令链能够更新”的缺口。
2. 用户场景
Given:
When:
Then:
3. 设计规则
deviceId + reminderTriggerId为核心,不要求语音动作具备由 H5/SSE 生成的commandId。eventId/operationId;网络重试不得重复消费本地提醒,也不得在 Gateway 创建重复结果。correlationId;日志不得包含设备 Token、Action token 或语音原文。4. 契约增量
新增或扩展一个不依赖 Gateway
commandId的设备侧状态上报契约(最终命名在实现前确认),至少包含:schemaVersioneventIdcorrelationIddeviceIdreminderTriggerIdoperationIdactionacknowledge或snoozestatusoccurredAtnextTriggerAtsourcevoice,不得依赖语音原文现有带
commandId的ReminderActionResult继续用于 H5 → SSE → 设备命令回执;本 Issue 不要求强行伪造commandId。5. 范围
deviceId,按eventId/operationId幂等处理;deviceId + reminderTriggerId更新或收口相关 Action,并记录动作来源;correlationId贯穿本地动作、状态上报、Gateway Action 状态更新;nextTriggerAt。6. 非目标
7. TDD 与验收
RED:
nextTriggerAt;GREEN:
自动验证:
./scripts/run_checks.sh与pnpm --dir services/im-gateway ci通过。真机验收:
nextTriggerAt;correlationId。8. 依赖与关系
Refs #95, #152, #179