# Room Status Moment 实时快照同步 ## 背景 将 Kafka 消费的 RCU 设备状态/控制事件(`0x36` 上报、`0x0F` 下发),在写入流水日志表 `rcu_action_events` 的同时,并行提取关键状态信息,以 Upsert 方式同步到独立的快照表 `room_status.room_status_moment`。 ## 变更范围 ### 新增文件 - `src/db/roomStatusManager.js` — 独立连接池 + Upsert SQL 封装 - `src/db/statusBatchProcessor.js` — 快照专用的批量聚合处理器(内存合并去重) - `src/processor/statusExtractor.js` — 从 Kafka payload 提取 `dev_loops`/`faulty_device_count` - `tests/status_extractor.test.js` — statusExtractor 单元测试 - `tests/status_batch_processor.test.js` — statusBatchProcessor 单元测试 ### 修改文件 - `src/config/config.js` — 新增 `roomStatusDb` 配置段 - `src/index.js` — 挂载 `StatusBatchProcessor` 并在消息处理流程中并行推送状态更新 - `.env.example` — 补充 `ROOM_STATUS_DB_*` 环境变量示例 ### 缺陷修复 (Bug Fixes) - `src/db/statusBatchProcessor.js` — 添加 `isFlushing` 状态锁防止高并发带来的重复刷新及数据库死锁 (`ON CONFLICT` 互锁)。 - `src/db/roomStatusManager.js` — 去除 `WHERE EXCLUDED.ts_ms >= room_status_moment.ts_ms` 条件限制,保证始终强制应用最新的状态覆盖。 - `src/schema/kafkaPayload.js` & `src/processor/statusExtractor.js` — 修正 `control_list` 的提取逻辑,兼容 Kafka 实际传输中的 `loop` 字段。 - `docs/plan-room-status-sync.md` — 明确 `sys_lock_status` 仅在 Kafka 传入的值非空时,才进行覆盖。 ## 设计约束 1. 状态表写入失败**不得**阻塞主流水表写入和 Kafka offset 提交 2. 同一批次中同设备多次更新需在内存中合并后再提交数据库 3. `dev_loops` JSONB 使用增量合并 (`||`),`faulty_device_count` 使用整体替换 4. 快照表使用独立数据库连接池,与流水表连接池资源隔离 ## 参考文档 - `docs/plan-room-status-sync.md` - `docs/room_status_moment.sql`