docs(M06-C): 记录协议幂等验收并推进控制箱

This commit is contained in:
Codex
2026-06-22 18:30:36 +08:00
parent e795cdb693
commit f71ac09a0b
9 changed files with 80 additions and 18 deletions
+3 -3
View File
@@ -120,9 +120,9 @@ WSL 已验证:EMQX `5.8.9`、MQTTX CLI `1.13.0`、EMQX 服务 `active (running
项目已开发部分模块。具体完成度不得从 README 猜测,必须以现有代码、测试、数据库迁移、Git 历史以及 `docs/current-baseline.md``docs/module-status.md``docs/feature-status.md` 为准。 项目已开发部分模块。具体完成度不得从 README 猜测,必须以现有代码、测试、数据库迁移、Git 历史以及 `docs/current-baseline.md``docs/module-status.md``docs/feature-status.md` 为准。
- 当前执行游标:`M06-C` - 当前执行游标:`M06-D`
- 最近工程提交:`74a67ac`,完成 M06-B 设备资产、控制通道、Sub-1G 拓扑、状态快照、告警/维护结构与门店权限 - 最近工程提交:`e795cdb`,完成 M06-C 三类协议适配器、13 位命令状态机、ACK 关联、QoS 1 去重与死信
- 下一工程目标:M06-C 协议适配器和消息幂等 - 下一工程目标:M06-D 控制箱和门锁业务能力
## 版本递进 ## 版本递进
+2 -2
View File
@@ -1,8 +1,8 @@
# 当前开发成果基线 # 当前开发成果基线
> V5.0 首次核验日期:2026-06-16 > V5.0 首次核验日期:2026-06-16
> audited_commit: `74a67ac` > audited_commit: `e795cdb`
> next_engineering_target: M06-C 协议适配器和消息幂等 > next_engineering_target: M06-D 控制箱和门锁业务能力
> 事实源:当前工作区、Git 历史、状态文档、Windows/WSL 检查脚本。 > 事实源:当前工作区、Git 历史、状态文档、Windows/WSL 检查脚本。
## 总体结论 ## 总体结论
@@ -0,0 +1,16 @@
# M06-C IoT 消息数据库变更
- 迁移版本:`2026062220`
- 名称:`m06c_iot_messages`
## 新增
- `qipai_iot_commands`:13 位命令 ID、状态、请求/回包、发布/ACK/超时和失败原因。
- `qipai_iot_device_events`:原始/标准化消息、Topic、事件类型、payload 哈希、接收次数。
- `qipai_iot_dead_letters`:非法 Topic、未知设备和解析失败消息。
## 幂等与回滚
- 设备事件按租户、设备、Topic 和 payload 哈希唯一;重复消息只增加计数。
- 死信按 Topic 和 payload 哈希唯一。
- down 迁移仅删除 M06-C 三张表,不影响设备资产和拓扑。
@@ -0,0 +1,34 @@
# M06-C 协议适配器和消息幂等
- 日期:2026-06-22
- 起始 commit`c96045f`
- 工程 commit`e795cdb`
- ENGINEERING_DELTA=YES
- 子阶段状态:DONE(可独立工程范围);PDF 原件复核为外部阻塞
## 工程增量
- 实现 `MqttTransport``JilianControlBoxAdapter``JilianSub1GLockAdapter``JilianSmartSocketAdapter`
- 严格保留 `ConctolPower``Crldoor``CrlLED``PlayTTS``CtrlDevice` 等厂商拼写。
- Zod 校验控制箱读取/控电/门锁/TTS/LED/任务、Sub-1G 配对控制、插座读取/开关/本地任务。
- 建立 13 位命令 ID、命令持久化、发布状态、ACK/失败/超时状态推进。
- MQTT 消费校验 Topic、DeviceID 和 JSON;原始/标准化 payload 分开保存。
- QoS 1 重复消息只增加接收次数,不重复推进命令或设备状态。
- 非法 Topic、未知设备、非法 JSON/字段进入可去重死信表,消费循环不崩溃。
## 验证
- Windows `npm test``scripts/dev/windows/test-all.ps1`:退出码 0。
- WSL MySQL 8.4.9 原生临时副本:`up → verify → down → up → verify` 通过。
- 迁移语句:up 102、verify 74、down 96。
- 实测同一 ACK 投递两次:事件行 1 条、`receive_count=2`、命令只推进一次至 `ACKED`
- 非法 Topic 实测进入 `qipai_iot_dead_letters`
- 工程 commit 已 push`HEAD == origin/main == e795cdb6935568611a5d27d78991bf9e7ee2f7df`
## 资料边界
当前工作区与现有压缩包未找到 V5.4 点名的两份协议 PDF。实现依据为 V5.4 已固化的协议章节;PDF 页码级复核登记为 `ISSUE-013/BLOCKED_EXTERNAL`
## 后续
执行游标进入 M06-D:控制箱和门锁业务能力。
+2
View File
@@ -40,3 +40,5 @@
| BKG-007 | 后台微信支付配置 | M05-D/M08 | PARTIAL | `1680d73` | 已提供收款账户、分账接收方、门店/全局比例策略和授权状态 API;私钥、APIv3 Key 和接收方真实标识只使用环境引用,查询仅返回脱敏信息。 | Vue 后台页面待 M08;真实商户与服务商授权未提供。 | M08 接入响应式配置页面;授权后完成生产验收。 | | BKG-007 | 后台微信支付配置 | M05-D/M08 | PARTIAL | `1680d73` | 已提供收款账户、分账接收方、门店/全局比例策略和授权状态 API;私钥、APIv3 Key 和接收方真实标识只使用环境引用,查询仅返回脱敏信息。 | Vue 后台页面待 M08;真实商户与服务商授权未提供。 | M08 接入响应式配置页面;授权后完成生产验收。 |
| DEV-003 | 设备管理 | M06-B/M08 | PARTIAL | `74a67ac` | 已实现 DeviceID/IMEI/ICCID/型号/固件/信号/能力资产,控制箱通道、智慧插座负载、Sub-1G 父子拓扑、状态快照、开放告警和维护记录查询;门店数据范围生效。 | 尚无后台/手机页面,在线状态仍需 M06-C/G 由真实消息更新。 | M06-C 接入协议消息与幂等;M08 实现响应式界面。 | | DEV-003 | 设备管理 | M06-B/M08 | PARTIAL | `74a67ac` | 已实现 DeviceID/IMEI/ICCID/型号/固件/信号/能力资产,控制箱通道、智慧插座负载、Sub-1G 父子拓扑、状态快照、开放告警和维护记录查询;门店数据范围生效。 | 尚无后台/手机页面,在线状态仍需 M06-C/G 由真实消息更新。 | M06-C 接入协议消息与幂等;M08 实现响应式界面。 |
| BKG-004 | 后台设备管理 | M06-B/M08 | PARTIAL | `74a67ac` | 已提供设备入库、列表、拓扑、通道绑定、Sub-1G 绑定、状态和维护 API;同一房间控制目标唯一,控制箱与智慧插座重复负载被数据库拒绝。 | Vue 后台页面和真实设备扫码入库待 M08/M06-G。 | M06-C/D/E 接入协议后补真实状态;M08 实现管理页面。 | | BKG-004 | 后台设备管理 | M06-B/M08 | PARTIAL | `74a67ac` | 已提供设备入库、列表、拓扑、通道绑定、Sub-1G 绑定、状态和维护 API;同一房间控制目标唯一,控制箱与智慧插座重复负载被数据库拒绝。 | Vue 后台页面和真实设备扫码入库待 M08/M06-G。 | M06-C/D/E 接入协议后补真实状态;M08 实现管理页面。 |
| IOT-006 | MQTT 消息幂等 | M01/M06-C | DONE | `e795cdb` | 上行按租户、设备、Topic 和 payload SHA-256 唯一;QoS 1 重复消息只增加 `receive_count`,不重复更新命令或设备副作用;WSL MySQL 8.4.9 实测两次 ACK 仅一条事件。 | - | M06-D/E 继续复用同一消费链路。 |
| IOT-007 | 命令状态机 | M01/M06-C | DONE | `e795cdb` | 已实现 `PENDING/PUBLISHED/ACKED/FAILED/TIMEOUT/UNKNOWN/CANCELLED` 数据模型,发布失败、ACK 结果、超时和 13 位命令 ID 均有测试;发布成功不等于 ACK。 | - | M06-D/F 接入业务权限、补偿与过期取消。 |
+3 -3
View File
@@ -2,7 +2,7 @@
| 设备 | 当前资料 | 状态 | 下一步 | | 设备 | 当前资料 | 状态 | 下一步 |
|---|---|---|---| |---|---|---|---|
| 4G 智能门禁控电箱 | 待在参考资料中定位正式协议 | TODO | M06 前完成协议录入。 | | 4G 智能门禁控电箱 | V5.4 已固化命令与字段;PDF 原件未在当前仓库找到 | PARTIAL | M06-D 完成业务权限和控制;取得 PDF 后逐页复核。 |
| Sub-1G 智能门锁 | 待在参考资料中定位正式协议 | TODO | M06 完成绑定控制模型。 | | Sub-1G 智能门锁 | V5.4 已固化 `AddDevice/CtrlDevice`、subID/subtype 和结果码;PDF 原件缺失 | PARTIAL | M06-D 完成绑定控制、安全门禁与事件。 |
| 4G 智慧插座 | 待在参考资料中定位正式协议 | TODO | M06 前完成型号能力识别。 | | 4G 智慧插座 | V5.4 已固化查询、开关、本地任务和事件;PDF 原件缺失 | PARTIAL | M06-E 完成能力识别、计量和保护事件。 |
| EMQX Broker | 固定主机 `101.42.38.246`;已生成安装说明、ACL 模板和菜单检查 | PARTIAL | 生产 Ubuntu 安装、端口限制和 ACL 应用后复验。 | | EMQX Broker | 固定主机 `101.42.38.246`;已生成安装说明、ACL 模板和菜单检查 | PARTIAL | 生产 Ubuntu 安装、端口限制和 ACL 应用后复验。 |
+6 -6
View File
@@ -3,15 +3,15 @@
```yaml ```yaml
execution_cursor: execution_cursor:
current_module: M06 current_module: M06
current_stage: M06-C current_stage: M06-D
stage_status: TODO stage_status: TODO
last_completed_stage: M06-B last_completed_stage: M06-C
next_stage: M06-C next_stage: M06-D
last_engineering_commit: 74a67ac last_engineering_commit: e795cdb
last_push_verified: true last_push_verified: true
base_branch: main base_branch: main
blocked_reason: "" blocked_reason: ""
updated_at: 2026-06-22T21:05:00+08:00 updated_at: 2026-06-22T22:10:00+08:00
``` ```
| 模块 | 状态 | 最近提交 | 最近开发日志 | 备注 | | 模块 | 状态 | 最近提交 | 最近开发日志 | 备注 |
@@ -22,7 +22,7 @@ execution_cursor:
| M03 门店、房间、价格、营业时间 | DONE | `d563078` | docs/devlogs/2026-06-18-M03-D-场景码NFC与WiFi.md | M03-A/B/C/D 已完成门店房间、装修广告、媒体、地图选店、场景码/NFC 页面导航和受控 Wi-Fi;真实微信小程序码图片生成留待 M08 真机联调。 | | M03 门店、房间、价格、营业时间 | DONE | `d563078` | docs/devlogs/2026-06-18-M03-D-场景码NFC与WiFi.md | M03-A/B/C/D 已完成门店房间、装修广告、媒体、地图选店、场景码/NFC 页面导航和受控 Wi-Fi;真实微信小程序码图片生成留待 M08 真机联调。 |
| M04 订单、时段锁定、支付闭环 | DONE | `91801fe` | docs/devlogs/2026-06-20-M04-D-订单分享.md | M04-A/B/C/D 已完成可信定价、并发预占、订单状态机、续费取消换房、管理员调整、代下单和最小权限分享;Windows 全量回归与 WSL MySQL 8.4.9 模块回归通过。 | | M04 订单、时段锁定、支付闭环 | DONE | `91801fe` | docs/devlogs/2026-06-20-M04-D-订单分享.md | M04-A/B/C/D 已完成可信定价、并发预占、订单状态机、续费取消换房、管理员调整、代下单和最小权限分享;Windows 全量回归与 WSL MySQL 8.4.9 模块回归通过。 |
| M05 会员、余额、套餐、优惠券 | PARTIAL | `1680d73` | docs/devlogs/2026-06-22-M05-D-分账与收款配置.md | M05-A/B/C/D 工程闭环已完成:统一支付、微信支付退款、团购直订、门店收款账户、分账接收方、比例策略、授权门禁、幂等分账和对账查询均通过 Windows 与 WSL MySQL 回归;真实微信/团购/分账权限未提供,模块保持 PARTIAL/BLOCKED_EXTERNAL。 | | M05 会员、余额、套餐、优惠券 | PARTIAL | `1680d73` | docs/devlogs/2026-06-22-M05-D-分账与收款配置.md | M05-A/B/C/D 工程闭环已完成:统一支付、微信支付退款、团购直订、门店收款账户、分账接收方、比例策略、授权门禁、幂等分账和对账查询均通过 Windows 与 WSL MySQL 回归;真实微信/团购/分账权限未提供,模块保持 PARTIAL/BLOCKED_EXTERNAL。 |
| M06 设备、MQTT 与真实硬件联动 | PARTIAL | `74a67ac` | docs/devlogs/2026-06-22-M06-B-设备资产与拓扑.md | M06-A/B 已完成 MQTT 基础、设备资产、能力、控制通道、Sub-1G 父子拓扑、状态快照、告警/维护结构和门店权限;生产 Broker 与真实硬件仍待联调,继续 M06-C。 | | M06 设备、MQTT 与真实硬件联动 | PARTIAL | `e795cdb` | docs/devlogs/2026-06-22-M06-C-协议适配与消息幂等.md | M06-A/B/C 已完成 MQTT 基础、设备拓扑、三类协议适配器、命令状态、ACK 关联、QoS 1 去重和死信;协议 PDF 原件未在仓库找到,当前严格按 V5.4 已固化字段实现,继续 M06-D。 |
| M07 保洁、通知、任务和语音播报 | TODO | - | - | - | | M07 保洁、通知、任务和语音播报 | TODO | - | - | - |
| M08 微信原生小程序完整业务 | TODO | - | - | - | | M08 微信原生小程序完整业务 | TODO | - | - | - |
| M09 后台管理端完整业务 | TODO | - | - | - | | M09 后台管理端完整业务 | TODO | - | - | - |
+13 -4
View File
@@ -1,12 +1,12 @@
# MQTT 协议映射 # MQTT 协议映射
M06-A 已按正式协议固定 MQTT Topic、QoS 和客户端权限;具体命令字段、回包、超时和重试在 M06-C/D/E 继续录入 M06-C 已按 V5.4 中固化的厂商协议字段实现适配器、上行解析、命令关联、消息幂等与死信。仓库当前未找到总纲点名的两份 PDF 原件,因此尚不能完成 PDF 页码级复核;不得把此状态写成“PDF 已阅读”
| 设备 | Topic/命令 | 方向 | 字段 | 状态 | | 设备 | Topic/命令 | 方向 | 字段 | 状态 |
|---|---|---|---|---| |---|---|---|---|---|
| 4G 智能门禁控电箱 | `/devicesend/{DeviceID}``/devicewill/{DeviceID}``/deviceaccept/{DeviceID}` | 双向 | M06-C/D 补命令字段 | PARTIAL | | 4G 智能门禁控电箱 | `/devicesend/{DeviceID}``/devicewill/{DeviceID}``/deviceaccept/{DeviceID}` | 双向 | `basicInfo/mqttConfig/startVoice/task/taskconfig``ConctolPower``Crldoor``PlayTTS/stopTTS``CrlLED``task/addtask/canceltask` | PARTIAL |
| Sub-1G 智能门锁 | 经父控制箱使用相同三个 Topic | 双向 | M06-C/D 补 `subID/subtype` 与命令字段 | PARTIAL | | Sub-1G 智能门锁 | 经父控制箱使用相同三个 Topic | 双向 | `AddDevice``CtrlDevice``open/close/setkey/delkey/setcard/delcard/factoryreset` | PARTIAL |
| 4G 智慧插座 | `/devicesend/{DeviceID}``/devicewill/{DeviceID}``/deviceaccept/{DeviceID}` | 双向 | M06-C/E 补命令字段 | PARTIAL | | 4G 智慧插座 | `/devicesend/{DeviceID}``/devicewill/{DeviceID}``/deviceaccept/{DeviceID}` | 双向 | `basicInfo/workInfo``on/off``localtask``clearTask` | PARTIAL |
## M06-A ACL 基线 ## M06-A ACL 基线
@@ -17,3 +17,12 @@ M06-A 已按正式协议固定 MQTT Topic、QoS 和客户端权限;具体命
| 普通客户端 | 禁止 `$SYS/#``#``+/#` | 禁止未显式允许主题 | 模板已生成 | | 普通客户端 | 禁止 `$SYS/#``#``+/#` | 禁止未显式允许主题 | 模板已生成 |
后端 MQTT.js 固定使用 MQTT 3.1`protocolVersion: 3`)、QoS 1、持久会话、自动重连,并在每次连接成功后显式恢复两个上行订阅。单条应用消息默认限制为 64 KiB。 后端 MQTT.js 固定使用 MQTT 3.1`protocolVersion: 3`)、QoS 1、持久会话、自动重连,并在每次连接成功后显式恢复两个上行订阅。单条应用消息默认限制为 64 KiB。
## M06-C 消息规则
- 命令 ID 只允许 1-13 位数字,默认生成 10 位秒时间戳加 3 位滚动序号。
- 下发先写 `qipai_iot_commands=PENDING`MQTT 发布成功后转 `PUBLISHED`,有效 ACK 才转 `ACKED`
- `fail/busy/unconfirm/timeout/full` 统一转 `FAILED` 并保留厂商结果码;超时扫描可把未回包命令转 `TIMEOUT`
- 上行先校验 Topic、资产 DeviceID 和 JSON;异常 Topic、未知设备、非法 JSON/字段进入 `qipai_iot_dead_letters`
- QoS 1 重复消息命中唯一键后只增加 `receive_count`,不重复执行 ACK、状态快照或后续业务副作用。
- 原始 JSON 与标准化 JSON 分开保存;协议字段大小写和拼写不得在适配器外重新拼装。
+1
View File
@@ -14,3 +14,4 @@
| ISSUE-010 | 2026-06-22 | M05-C/GRP-001/GRP-002 | 美团/点评、抖音等团购核销与直订未完成真实平台联调。 | 高 | 已完成统一适配器、人工/Mock/API 核销、券码哈希、重复核销幂等、HMAC 回调、映射、人工队列和认领成单;后台配置与记录 API 已具备。 | 缺平台商家授权、Token、正式签名协议和回调测试环境。 | 获取授权后新增厂商专用适配器并执行验券、重复推送、取消和异常重试验收。 | BLOCKED_EXTERNAL | | ISSUE-010 | 2026-06-22 | M05-C/GRP-001/GRP-002 | 美团/点评、抖音等团购核销与直订未完成真实平台联调。 | 高 | 已完成统一适配器、人工/Mock/API 核销、券码哈希、重复核销幂等、HMAC 回调、映射、人工队列和认领成单;后台配置与记录 API 已具备。 | 缺平台商家授权、Token、正式签名协议和回调测试环境。 | 获取授权后新增厂商专用适配器并执行验券、重复推送、取消和异常重试验收。 | BLOCKED_EXTERNAL |
| ISSUE-011 | 2026-06-22 | M05-D/FRN-001 | 微信支付真实分账尚未联调。 | 高 | 已完成收款账户、接收方、比例策略、授权门禁、成功支付校验、API 请求签名、幂等批次、失败人工处理和查询;Mock 仅限非生产。 | 缺微信支付服务商/分账权限、已授权接收方和生产商户凭据。 | 取得权限后登记环境接收方映射,执行小额支付后多接收方分账、重复请求和失败对账验收。 | BLOCKED_EXTERNAL | | ISSUE-011 | 2026-06-22 | M05-D/FRN-001 | 微信支付真实分账尚未联调。 | 高 | 已完成收款账户、接收方、比例策略、授权门禁、成功支付校验、API 请求签名、幂等批次、失败人工处理和查询;Mock 仅限非生产。 | 缺微信支付服务商/分账权限、已授权接收方和生产商户凭据。 | 取得权限后登记环境接收方映射,执行小额支付后多接收方分账、重复请求和失败对账验收。 | BLOCKED_EXTERNAL |
| ISSUE-012 | 2026-06-22 | M06-A/IOT-001 | 生产 EMQX、正式 MQTT 客户端账号和 ACL 尚未现场验收。 | 高 | 已完成菜单 3 安装/更新、正式 Topic ACL、后端 MQTT 3.1/QoS 1、重连、订阅恢复、健康检查、消息限制和 Mock 客户端测试;WSL EMQX 服务级检查通过。 | Codex 不自动操作生产 Ubuntu,且尚无生产 MQTT 账号;WSL 本地最小权限账号也未配置。 | 管理员在 `101.42.38.246` 执行菜单 3 并建立账号/ACL;提供 Git 忽略的本地账号后执行错误密码、越权、TLS、遗嘱和三个 Topic 冒烟。 | BLOCKED_EXTERNAL | | ISSUE-012 | 2026-06-22 | M06-A/IOT-001 | 生产 EMQX、正式 MQTT 客户端账号和 ACL 尚未现场验收。 | 高 | 已完成菜单 3 安装/更新、正式 Topic ACL、后端 MQTT 3.1/QoS 1、重连、订阅恢复、健康检查、消息限制和 Mock 客户端测试;WSL EMQX 服务级检查通过。 | Codex 不自动操作生产 Ubuntu,且尚无生产 MQTT 账号;WSL 本地最小权限账号也未配置。 | 管理员在 `101.42.38.246` 执行菜单 3 并建立账号/ACL;提供 Git 忽略的本地账号后执行错误密码、越权、TLS、遗嘱和三个 Topic 冒烟。 | BLOCKED_EXTERNAL |
| ISSUE-013 | 2026-06-22 | M06-C/协议资料 | V5.4 点名的控制箱与智慧插座协议 PDF 原件未在 `参考/`、现有压缩包或仓库其他路径找到。 | 中 | M06-C 严格按 V5.4 已固化的 Topic、命令拼写、字段约束和结果枚举实现,并用 Mock/MySQL 验证;未伪称 PDF 已阅读。 | 协议原件未随当前工作区提供。 | 用户补充两份 PDF 后按页码复核字段、范围和完整枚举;若有差异,以 PDF 和实机结果修正适配器并记录迁移。 | BLOCKED_EXTERNAL |