# 测试报告 ## 基本信息 - 运行时间: 2026-01-29 - 运行方式: 控制台启动 `npm run dev`,运行约 60 秒后 Ctrl + C 终止 - 测试目标: 验证 Kafka 消费与入库链路,定位无入库原因 ## 控制台关键日志 ``` {"level":"error","message":"Message processing failed","timestamp":1769734880590,"context":{"error":"[\n {\n \"expected\": \"number\",\n \"code\": \"invalid_type\",\n \"path\": [\n \"hotel_id\"\n ],\n \"message\": \"Invalid input: expected number, received string\"\n }\n]","type":"PARSE_ERROR","stack":"ZodError: ...","rawPayload":"{\"ts_ms\":1769692878011,\"hotel_id\":\"2147\",\"room_id\":\"8209\",\"device_id\":\"099008129081\",\"direction\":\"上报\",\"cmd_word\":\"36\",\"frame_id\":52496,...}","validationIssues":[{"expected":"number","code":"invalid_type","path":["hotel_id"],"message":"Invalid input: expected number, received string"}]}} ``` ## 结论 - 数据未入库的直接原因: Kafka 消息在解析阶段触发 Zod 校验失败,`hotel_id` 为字符串类型而非文档要求的 Number,导致 `PARSE_ERROR`,数据库插入流程未执行。 ## 与文档格式的一致性检查 对照 [kafka_format.md](file:///e:/Project_Class/BLS/Web_BLS_RCUAction_Server/docs/kafka_format.md): - `hotel_id`: 文档要求 Number,但实测为字符串 (示例: `"2147"`),不一致。 - `cmd_word`: 文档要求 `"0x36"`/`"0x0F"`,实测为 `"36"`,不一致。 - `control_list`: 文档要求 Array/可选,但实测为 `null`,不一致。 - 其余关键字段如 `ts_ms`, `room_id`, `device_id`, `direction`, `udp_raw` 均存在。 ## 已增强的控制台错误输出 为了便于定位异常,以下模块已经增加详细错误输出到 PowerShell 控制台: - Kafka 处理异常: 输出 `type`, `stack`, `rawPayload`, `validationIssues`, `dbContext` - 数据库插入异常: 输出 `schema`, `table`, `rowsLength` - Redis 入队与重试异常: 输出详细错误信息 相关改动文件: - [index.js](file:///e:/Project_Class/BLS/Web_BLS_RCUAction_Server/bls-rcu-action-backend/src/index.js) - [databaseManager.js](file:///e:/Project_Class/BLS/Web_BLS_RCUAction_Server/bls-rcu-action-backend/src/db/databaseManager.js) - [errorQueue.js](file:///e:/Project_Class/BLS/Web_BLS_RCUAction_Server/bls-rcu-action-backend/src/redis/errorQueue.js) ## 建议修改方向 以下为解决无入库问题的可选方案,由你决定是否执行: 1. 上游严格按文档输出: - `hotel_id` 改为 Number - `cmd_word` 改为 `"0x36"` / `"0x0F"` - `control_list` 用 `[]` 或省略字段,避免 `null` 2. 下游放宽校验并做类型转换: - 将 `hotel_id` 支持字符串并转换为 Number - 继续兼容 `cmd_word = "36"` 的写法 - `control_list/device_list/fault_list` 接受 `null` 并转为空数组 当前代码已兼容 `cmd_word="36"` 和 `control_list=null`,但 `hotel_id` 仍按文档严格要求 Number。