diff --git a/CLAUDE.md b/CLAUDE.md index aa7a3f4..276e22b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -116,6 +116,12 @@ cd backend && .venv/bin/python tests/smoke.py 的话,每次客户端缓存过期(15 分钟)、每个 gunicorn worker、每次部署重启,都会 从库里读回同一个过期令牌再换一次,而这个端点按账号限流、能封几小时。 2026-09-03 排查一整天的根因就是这个。 + **窗口内每次尝试都会延长封锁**(实测:一次同步把截止时间从 00:41 推到 15:26)。 + 所以 `sync_status.rate_limit_source` 区分 `sso` / `data`:只有 sso 冷却会拒绝 + 动作,且只拒绝「刷新令牌」和「重新绑定」这两个真的会打登录端点的操作——库里 + 令牌没过期就照常同步。**重新输账号密码换新令牌解决不了**:`garth.login()` 是 + 同一个端点、更重的流程,限流按账号计,换设备换网络都绕不开。用户可用 force + 推翻我们自己猜的 24 小时。 数据端点另有节流:所有调用经 `services/garmin_throttle.py` 的代理,默认间隔 0.5s + 单次预算 1200 次(依据见该文件顶部)。 429 退避 24h,`rate_limited_until` 以 **DB 为准**(多 worker 内存不一致会卡死