diff --git a/docs/superpowers/plans/2026-08-15-订阅消息额度.md b/docs/superpowers/plans/2026-08-15-订阅消息额度.md index c4938dd..1164d62 100644 --- a/docs/superpowers/plans/2026-08-15-订阅消息额度.md +++ b/docs/superpowers/plans/2026-08-15-订阅消息额度.md @@ -1524,24 +1524,30 @@ Expected: 后端测试全绿,全部文件语法通过 1. `git push origin master` → Gitea Actions 自动部署后端(3–8 分钟) 2. 验证:`curl https://wxserver.ymxixi.space/api/health` -3. 验证后端对**线上旧版**小程序仍兼容:旧版不会调 `/api/subscribe`,且 `reminder.js` 对 `balance = 0` 的老用户会全部记 skipped——**这是本次上线最大的风险点**,见下方说明 +3. 验证后端对**线上旧版**小程序仍兼容:旧版不会调 `/api/subscribe`,老用户 `balance = 0`——见下方说明(合并前评审已修,风险大幅下降) 4. 确认无误后再上传小程序 → 体验版自测 → 提交审核 → 发布 -### ⚠️ 上线首日的额度真空问题 +### ⚠️ 上线首日的额度真空问题(已在合并前评审中修掉,此处保留背景) -新版 `reminder.js` 在 `balance <= 0` 时**不发任何请求**。而 `subscribe_quota` 表是新建的,所有存量用户的初始 `balance` 都是 0——这意味着**后端一上线,所有存量用户的提醒会立刻全部停发**,而新版小程序还在审核中,用户没有任何途径补额度。 +**原风险**:`reminder.js` 在 `balance <= 0` 时不发任何请求,而 `subscribe_quota` 是新建表,所有存量用户初始 `balance` 都是 0——后端一上线,存量用户的提醒会立刻全部停发,而新版小程序还在审核中,用户没有任何途径补额度。 -处理办法:部署后立刻给存量用户补一个初始余额,让他们至少维持现状不倒退。存量用户过去每存一条纪念日就授权过一次,所以按「该用户的纪念日条数」补是合理的估算: +**现状:不需要再手工执行任何 SQL。** 合并前评审拍板了两条修复,均已落地: + +1. **自动迁移**(`server/src/db.js`):下面这条 SQL 已经做成 `PRAGMA user_version` 驱动的一次性迁移,容器启动即执行,幂等(`user_version` 版本号 + `INSERT OR IGNORE`),只补 `subscribe_quota` 里尚无记录的 openid。**再手工敲一遍无害但完全多余。** +2. **探针机制**(`server/src/reminder.js`):即使余额为 0,每个用户每轮仍会把优先级最高的那条发出去探路;探针成功就继续正常发送。所以「记账低估 = 停发」这个前提本身已经不成立了。 + +原手工 SQL(仅作为迁移口径的备查,**不要执行**): ```bash -# 在群晖上对生产库执行(先备份) -cp /volume1/docker/apps/birthday-server/data/birthday.db{,.bak-$(date +%F)} -sqlite3 /volume1/docker/apps/birthday-server/data/birthday.db " -INSERT INTO subscribe_quota (openid, balance, grantedTotal, sentTotal, updateTime) -SELECT openid, COUNT(*), COUNT(*), 0, strftime('%s','now')*1000 -FROM anniversaries GROUP BY openid -ON CONFLICT(openid) DO NOTHING; -" +# 已由 db.js 的 migrateV1() 自动完成,保留在此仅供理解口径 +# INSERT INTO subscribe_quota (openid, balance, grantedTotal, sentTotal, updateTime) +# SELECT openid, COUNT(*), COUNT(*), 0, strftime('%s','now')*1000 +# FROM anniversaries GROUP BY openid +# ON CONFLICT(openid) DO NOTHING; ``` -这一步**必须在后端部署完成后、当天 9 点定时任务触发前**执行完毕。 +按 `MAINTENANCE.md` 的惯例,部署前依然建议先备份生产库: + +```bash +cp /volume1/docker/apps/birthday-server/data/birthday.db{,.bak-$(date +%F)} +```