12451
c3a3ea7c3a
fix(api)+fix(device): 状态取值收敛、超时方向守门补齐、在线判据口径订正
1) cabinets.status 写入侧收敛(此前 body.status 是 i8,0/99/-1 都能落库)
- create_cabinet 的 INSERT **显式写 status = 1**,不再依赖列默认值 0:
冻结口径是「2 = 禁用,其余 = 启用」,但列默认会产生第二种"启用"表示,
任何按 status = 1 做的统计都会悄悄漏掉新建柜子(见「踩过的坑」第 5 条)。
- PUT /api/cabinets/:id/status 增加白名单 {1,2},抽成纯函数 is_valid_cabinet_status
并配守门单测(i8 全量遍历断言,杜绝"只挡住我知道的那几个")。
白名单校验放在**鉴权之后**:越权恒 403,不会因参数非法而先返回 400
(否则 400/403 的差异会变成"该柜子是否存在"的探测信号)。
- 已实测自证:把白名单放宽成 [0,1,2] → 用例 FAILED / exit 101;还原 → 通过。
- 生产库实测 68 台**全部已是 status=1**,故无需数据迁移。
2) order_timeout.rs 的超时方向守门(此前只在文档里留了「遗留」标记)
- 选单 SQL 抽成常量 EXPIRED_ORDER_SCAN_SQL;
- 补 3 个单测:SQL 文本方向断言(含**反证**写反形态)+ 纯函数孪生体双向断言
(刚建 5 分钟不命中 / 超 10 小时 1 分钟命中 / 差 1 分钟不命中 + 反证)+ 常量合理性。
- Why:本文件与 report_worker.rs 是**等价但写法不同**的超时判据
(那边绑负数、这边把 start_time 往前推),修好一边而另一边没有守门 = 漏网;
方向写反**零报错、零日志、单测全绿**,只会静默提前结单、提前结算电量。
- 已实测自证:反写成 start_time < TIMESTAMPADD(HOUR, ?, NOW())
→ test_expired_order_scan_sql_points_backwards FAILED / exit 101;还原 → 3 passed。
3) device-server 的在线判据注释订正(原文与代码事实不符)
- 原文称在线键 device:{imei} "在验签前就会被写" —— **逐行核对后确认是错的**:
online=1 只由 api-server 的 report_worker 在 handle_login 的
sign == expected_sign 分支内(mark_device_online)以及 handle_status_post
(write_device_state,该 act 已被登录门控挡住)写入;handle_auth_str 不写 online。
- 真正不能拿它判下发的原因是另一条:它的 TTL 语义是"最近 300 秒收到过任意报文",
断连后仍存活最多 5 分钟 ⇒ 会出现"管理端显示已下发成功、设备实际收不到"。
- 另注:server.rs::update_device_route 在 auth_str/login **到达时**写 node_id 并
EXPIRE 300 —— 只刷 TTL、不写 online;与协议 §2.3 一致,故保留,但同样说明
该键不能当"可下发"判据。
验收:api cargo check --all-targets 零 error/零 warning,单测 182 passed;
device 30 passed;两产物交叉编译通过,已按 device→api 顺序发布到测试与生产。
2026-09-20 04:31:42 +08:00
..
2026-09-19 23:41:09 +08:00
2026-09-19 23:41:09 +08:00
2026-09-19 23:41:09 +08:00
2026-07-02 05:38:01 +08:00
2026-09-20 04:31:42 +08:00
2026-09-19 23:41:09 +08:00
2026-09-20 03:23:00 +08:00