补最终修复报告,并标注计划文档里已过时的手工 SQL
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1524,24 +1524,30 @@ Expected: 后端测试全绿,全部文件语法通过
|
|||||||
|
|
||||||
1. `git push origin master` → Gitea Actions 自动部署后端(3–8 分钟)
|
1. `git push origin master` → Gitea Actions 自动部署后端(3–8 分钟)
|
||||||
2. 验证:`curl https://wxserver.ymxixi.space/api/health`
|
2. 验证:`curl https://wxserver.ymxixi.space/api/health`
|
||||||
3. 验证后端对**线上旧版**小程序仍兼容:旧版不会调 `/api/subscribe`,且 `reminder.js` 对 `balance = 0` 的老用户会全部记 skipped——**这是本次上线最大的风险点**,见下方说明
|
3. 验证后端对**线上旧版**小程序仍兼容:旧版不会调 `/api/subscribe`,老用户 `balance = 0`——见下方说明(合并前评审已修,风险大幅下降)
|
||||||
4. 确认无误后再上传小程序 → 体验版自测 → 提交审核 → 发布
|
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
|
```bash
|
||||||
# 在群晖上对生产库执行(先备份)
|
# 已由 db.js 的 migrateV1() 自动完成,保留在此仅供理解口径
|
||||||
cp /volume1/docker/apps/birthday-server/data/birthday.db{,.bak-$(date +%F)}
|
# INSERT INTO subscribe_quota (openid, balance, grantedTotal, sentTotal, updateTime)
|
||||||
sqlite3 /volume1/docker/apps/birthday-server/data/birthday.db "
|
# SELECT openid, COUNT(*), COUNT(*), 0, strftime('%s','now')*1000
|
||||||
INSERT INTO subscribe_quota (openid, balance, grantedTotal, sentTotal, updateTime)
|
# FROM anniversaries GROUP BY openid
|
||||||
SELECT openid, COUNT(*), COUNT(*), 0, strftime('%s','now')*1000
|
# ON CONFLICT(openid) DO NOTHING;
|
||||||
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)}
|
||||||
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user