ericwyuan
|
f6687d2b5d
|
fix(deploy): push.sh 报「部署成功」,但跑的还是旧代码
服务是开机时以 root 起的(DSM 任务计划 → S99garmin.sh),所以 logs/
error.log 和 access.log 归 root。以 ericwyuan 重启会立刻失败——gunicorn
连自己的错误日志都打不开;而 stop.sh 同样杀不掉 root 进程,于是旧 master
继续占着 :8124,start.sh 的健康检查看到 200,高高兴兴报了「started」。
这次 AI 教练部署就撞上了:文件推上去了,接口却一直 404,查了半天才发现
在跑的是几小时前那个进程。
- 重启改走 sudo,和服务实际的运行身份一致(密码问一次,或走 NAS_PASSWORD)
- 健康检查加一条:只有 200 不算数——那正是旧 master 会给的答案。比对重启
前后 gunicorn 的 pid,没变就报错退出
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-01 14:11:17 +08:00 |
|
ericwyuan
|
526ece7d14
|
refactor(sync): 手动同步与自动同步彻底分开
「历史范围」原本放在设置页,却只对同步页的一个按钮起作用;而同步页最
显眼的主按钮「同步最新数据」写死 2 天,根本不看这个设置。选了「全部
历史」再点主按钮,表现就是应用无视你 —— 这正是反复出现的「只同步下来
两天」。
现在两条链路各管各的:
* 自动同步:只在设置页配置(开关 + 频率),窗口固定 SYNC_DAYS,不再
读 history_days。措辞也改成「拉取最近几天」,不再暗示会补历史。
* 手动同步:范围就在同步页当场选,紧挨着用它的按钮,并标出每个范围的
实际代价(自上次同步 / 7 天 / … / 全部历史约 730 天、20-40 分钟)。
两个按钮合成一个「开始同步」,写死 2 天的那个删掉。
history_days 保留为「上次手动选的范围」,只有同步页读它;默认值改成
-1(自上次同步),对日常使用是正确的起点。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-01 09:20:52 +08:00 |
|
ericwyuan
|
4d55fb4776
|
chore(deploy): 别把 macOS 的 xattr 塞进 tar,群晖读不懂只会刷警告
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-01 09:09:21 +08:00 |
|
ericwyuan
|
1c48435b9d
|
chore(deploy): NAS 的 ssh 端口是 2222
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-01 09:05:35 +08:00 |
|
ericwyuan
|
41b7ae82e4
|
fix(sync): 「全部历史」真的拉全部历史,自动同步不再每次静默失败
四个独立的 bug 叠在一起,表现为「只同步两天、没有进度」:
* 前端 `...(days ? { days } : {})` 把 days=0 当成未传。「全部历史」
存的就是 0,请求体里根本没有 days,后端退回 7 天默认值。
* scheduler 用 `s[0]` 读 query_one 返回的 dict,抛 KeyError 后被
per-account 的 except 吞掉。只要用户存过一次设置,每 30 分钟的
自动同步就一次都没成功过——库里那 2 天全是手动点出来的。
* 增量同步查 `health_daily`(表其实叫 health_data),后台线程直接
死掉,状态永远卡在 syncing,进度条不动。
* UI 完全不看 /sync 的返回值,rate_limited 时按钮点了没反应;轮询
结束时又把 rate_limited 归进 else 分支报「同步完成」。
顺带:
* 日循环遇到 429 立即退避并保留已拉到的天数,而不是当成「跳过一天」
继续往下捶 700 天——这正是之前限流死循环的来源之一。
* 定时循环显式传 SYNC_DAYS。历史范围按 UI 文案只描述手动全量同步,
让半小时一次的 tick 重拉 730 天必然把限流撞得更深。
* 短同步逐天上报进度(原来每 5 天一次,7 天的同步全程停在 0)。
* /sync 路由重复解析 body,空 body 会 None.get 崩。
* 4 个 StubGarth 缺 configure(),7 个测试在此之前一直是红的。
新增 deploy/push.sh:NAS 只认密码,脚本开一个 ssh 复用连接,密码只
输一次,后面推送 / 重启 / 健康检查全走它。不碰 .env、.venv 和数据库。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-01 08:11:24 +08:00 |
|
ericwyuan
|
15fba8c25c
|
feat: NAS 部署 + auth-hub 认证 + 同步逻辑修复
部署:
- 后端 Python/Flask,数据层可插拔 SQLite/MariaDB
- NAS 部署路径 /volume1/web/garmin-health-lab,端口 8124
- Gunicorn 生产服务器 (2 workers / 4 threads)
- 开机自启脚本 deploy/S99garmin.sh
- frp 隧道甲骨文 8124 → NAS 8124,外网访问
- 前端构建产物纳入版本管理 (backend/static/)
认证:
- auth-hub OAuth2/OIDC 统一登录接入
- 新建 NAS 专用 client,注册内外网回调地址
- 前端 LoginPage 支持回调路由 /auth/callback
- 数据同步页增加 Garmin 邮箱输入框
同步逻辑修复:
- 自动同步调度器读取用户 history_days 设置,不再固定 2 天
- 前端 0(全部历史)不再被 || 吞掉,改为 ?? 处理
- 后端路由和 sync_data 中 0 不再被当成 falsy 回退默认值
- sync_data 和调度器中 0 → 730 天(全部历史=最大范围)
- 已同步天数显示数据库实际总天数 (totalDays)
- 历史范围新增「自上次同步」增量选项 (days=-1)
- 后端 settings.py HISTORY 添加 -1 值
项目文档:
- 创建 PROGRESS.md 跟踪项目进度
|
2026-09-01 07:39:09 +08:00 |
|
ericwyuan
|
283d530f82
|
fix(deploy): 启动脚本等端口真正释放,并确认服务可用后才报成功
上一次部署里旧 worker 没随 master 退出,一直占着 8123。新 master 启动、
打印 started、然后什么都不服务——日志每一行看起来都正常,站点却是挂的。
- stop.sh 等进程真正退出,超时后 -9
- start.sh 停完等端口释放,起来后 curl 健康检查通过才算成功,否则返回非零
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
|
2026-08-24 04:23:05 +08:00 |
|
ericwyuan
|
6de7562cd8
|
[阶段5.1] 开机自启 + 接入真实 garminconnect,修复同步的三处 API 误用
fix(garmin): 同步代码调用的 garminconnect API 全是错的
装上库核对签名后发现(garminconnect 0.2.8),原代码从未被真正
执行过,三处调用都不成立:
1. get_activities(date) —— 该方法签名是 (start, limit),收的是
分页下标和条数,不是日期。传日期等于在问"第 2026-08-23 条运动",
而且少传一个参数必然 TypeError。
改为 get_activities_by_date(start, end),整个窗口一次取回,
顺带把原来"每天一次调用"减为一次。
2. 睡眠数据不在 get_user_summary 里,是独立的 get_sleep_data(cdate);
原代码从 summary 里读 sleep 字段,结果会把每一晚都记成无睡眠数据。
HRV 同理,走 get_hrv_data(cdate)。
3. 字段名不符:实际是 totalSteps / totalKilocalories /
averageStressLevel,原代码用的是 steps / calories.total /
stress.average。
其他改进:
- 运动记录改用 Garmin 自己的 activityId 作主键,重复同步同一窗口
不再产生重复行(原来每次同步都会把同一条运动再插一遍)
- 某天无数据时返回全 None,不再写入空行让读端点再过滤掉
- 原来 bare except 吞掉每天的异常,全部失败也报 success;
现在全窗口失败会如实返回 error 并记录原因
- 同步天数、是否走 Garmin 中国区改为环境变量可配
tests/test_garmin_sync.py (23 通过):
- 用 StubClient 模拟真实 0.2.8 的接口形状,无需库、凭证或网络
- 回归用例覆盖上述三处误用:活动必须按日期区间一次取回、
睡眠与 HRV 必须走各自端点
- 重复同步不产生重复的天和重复的运动记录
- 单天失败跳过、全窗口失败报错、登录失败如实上报
部署:
- NAS 安装 garminconnect(pydantic-core 有 cp38 x86_64 轮子,
无需 gcc)
- 新增 deploy/S99garmin.sh 开机自启脚本,与 NAS 上既有的
S99frpc.sh 同一套惯例;以 root 启动但降权到 ericwyuan 运行,
因为服务不需要特权而 .env 里有数据库和 API 凭证
- PID 文件放应用目录而非 /var/run(非特权用户写不了)
NAS 真机全量测试: 240 passed
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
|
2026-08-23 19:05:19 +08:00 |
|