JianFeeeee
044a664cc3
fix(push): HMS 每日额度按**批次**计,且挪到"确认能发"之后
审查报告 `docs/reviews/push-and-gui-review.md` §二.1 记的两条,都在**线上**
(已部署二进制是 f51c9c8 的构建,此修复未上线)。
## ① 计数单位错:按 token 数扣,变量名与文案都说"条"
`hms.go` 原先 `h.reserveDaily(len(tokens))`,而变量名 `dayCount`、
注释、报错文案(「达到每日推送上限 N **条**」)说的都是"条"。
华为的测试消息额度是按 **`messages:send` 的调用次数**计的
(一次请求一条消息,无论 `message.token[]` 里有几个设备)。
⇒ **3 个设备收到 1 封邮件就吃掉 3 条额度,实际只发出 1 条。**
多设备自部署用户会按 1/设备数 的速度提前耗尽 1000 条/天。
修法:`reserveDaily(1)` —— 一次 `Send` = 一条消息。
## ② 扣在投递**之前**:一条都没发出去,额度却已经扣了
原顺序:reserveDaily → accessToken → HTTP 请求。
`accessToken` 失败 / HTTP 失败 / 华为回非成功码,这三种情况
**一条都没发出去**而额度已扣,且失败只 `log.Printf`
⇒ 一次网络抖动静默烧掉配额。
修法:挪到 `accessToken` **之后**、真正发请求之前。
★ 为什么不是"发送成功后再扣":那会超发(并发下多个 goroutine
都能通过检查)。保留前置预留、但放在"确认能发"之后,是
**宁可少算也不多发**的取舍 —— 少算的代价是偶尔一次失败
没计入,超发的代价是真超额被华为拒。
## 验证
`server/internal/push/push_test.go` 补 3 格(+27 行):
按批次计(多设备一封邮件只扣 1)
accessToken 失败**不**扣额度
reserveDaily 的单位是"条消息"而非 n 个 token
2026-09-28 08:26:41 +08:00
..
2026-09-08 19:16:35 +08:00
2026-09-14 08:32:22 +08:00
2026-09-25 16:29:19 +08:00
2026-09-26 09:18:39 +08:00
2026-09-08 19:16:35 +08:00
2026-09-26 07:44:33 +08:00
2026-09-14 15:49:45 +08:00
2026-09-15 11:51:58 +08:00
2026-09-28 08:26:41 +08:00
2026-09-26 14:20:23 +08:00
2026-09-08 19:16:35 +08:00
2026-09-28 08:26:29 +08:00
2026-09-14 11:07:03 +08:00