Commit Graph

4 Commits

Author SHA1 Message Date
ericwyuan
34940cc387 feat(sync): 运动详情改为同步入库,详情页只读本地
按需回源是错的:点一次运动要等七个 Garmin 接口,网络好的时候慢,
网络差的时候直接超时(实测公网下 Network Error)。

- sync_data 顺带补齐缺详情的运动
- POST /api/garmin/sync-details 后台补齐存量,GET 查进度
- 详情页只读本地库;没有就提示去同步,不再回源
- 同步页新增「补齐运动详情」按钮,带进度

身体年龄:加入公开的阻尼系数
- 34 岁 VO₂max 46 原本算出 21 岁。不是算错,是方法本身会饱和:
  人与人之间的 VO₂max 标准差约 7,而年龄每年只带来约 0.35 的衰减,
  于是稍微能练的人都会撞到参考表最年轻一档。
- 按 50% 向实际年龄收拢,收敛范围 ±20 → ±12 岁,同一算例现在给 27 岁。
- 去掉「高于最年轻一档按 20 岁计」的硬地板,那是一道正好落在用户身上的悬崖。
- 界面同时显示未收拢的原始值,阻尼系数写进评分依据。

路由:为每个路径补无斜杠别名
- F7 写地址栏时去掉尾斜杠,于是 /daily/ 在地址栏是 /daily,
  而那个地址匹配不到任何路由,刷新或分享就落到「找不到页面」。

布局:让页面结构上无法被撑宽
- 网格改用 minmax(min(210px,100%),1fr):裸的 minmax(210px,1fr) 允许
  两列加起来超过窄屏宽度,第二张卡就被切掉在屏幕外。
- .ring-row 用 minmax(0,1fr),1fr 会以 min-content 兜底,一句长说明就能
  把整行顶宽。
- .page-inner 加 overflow-x: clip。
- html/body 用 100dvh:手机浏览器把自己的地址栏盖在布局视口上,
  100% 高的应用会把底部 Tab 栏顶到它们下面——对用户来说就是没有 Tab 栏。

测试:新增 122 项(设置 44、身体年龄 44、运动详情 42),全量 446 项通过。

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-24 04:03:49 +08:00
ericwyuan
7ab150537d [阶段10] 前端以 Framework7 重建,采用 iOS 原生形态
按要求废弃手写外壳,改用 Framework7 React(theme=ios)。参照 PeakWatch
的信息架构与卡片语言。

保留(这些是资产,不该重来):
- 数据层 services/api.ts、聚合 lib/aggregate.ts、参考区间 lib/ranges.ts
- 图表组件 Chart / Ring / Sparkline / BandBar / MetricCard / MetricStrip
- 经校验的配色令牌(色盲安全 + 对比度,浅深两档)

替换:
- 路由与外壳交给 F7:五个 Tab 各自独立导航栈,推入详情页不影响其他 Tab
- 页面转场、橡皮筋滚动、大标题折叠、半透明栏 —— 这些正是换框架的理由,
  手写做不像
- 底部标签栏改用 F7 Toolbar,触控目标与安全区由框架处理

配色接入:
- 新增 f7theme.css 把我们的令牌映射到 F7 的 CSS 变量,让它的导航栏/
  列表/面板与我们的图表同属一套设计,而不是两种视觉打架
- F7 的深色靠 .dark 类,我们的靠 data-theme,两者在 App 里同步切换

fix: 图标显示为原始名称(squ/hea/cale…)
- iconIos/iconMd 引用的是 framework7-icons 字体,没装就只会渲染出名字

其他:
- tsconfig moduleResolution 改为 bundler —— F7 用 exports 映射,
  node 解析方式找不到它的类型
- 登录页不套 Tab 外壳,未登录时不该出现导航

桌面与手机都要好看:内容在宽屏收进 1100px 居中列并加密卡片列数,
窄屏走底部标签栏;两档都已实机核对。

bundle 190KB -> 399KB,是换取原生手感的代价。

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-23 23:38:21 +08:00
ericwyuan
ad88ec7e41 [阶段7] 前端重做:31 项指标全部露出,配色经色盲校验
原来仪表板只有 4 张卡片和 4 张图,31 项指标里绝大多数没有出口。

信息架构重组为 7 个页面(原 5 个):
- 今日   按活动 / 心率压力 / 睡眠呼吸三组展示 16 项指标
- 趋势   15 组指标可切换,5 档时间窗口(最长一年)
- 睡眠   新增。分期堆叠图 + 夜间血氧/呼吸/压力
- 成就   新增。奖励徽章按年份分组、个人纪录、运动记录
- 建议 / 同步 / 设置 保持

配色(依据 dataviz 规范,用校验器实测而非目测):
- 采用验证过的分类色板并按既定 slot 顺序取色 —— 顺序本身就是
  色盲安全机制,不是审美选择,因此只取不循环
- 浅色 worst adjacent CVD ΔE 9.1 / 常视觉 22.9
  深色 worst adjacent CVD ΔE 8.4 / 常视觉 19.8,两档全部通过
- 浅色表面下 aqua 2.74:1、yellow 2.11:1 低于 3:1,按规范提供
  "relief":每张图都带表格视图,且图例始终与文字标签同现
- 深色不是自动反色,是同色相针对深色表面重新取阶并单独校验
- 状态色(good/warning/serious/critical)保留专用,绝不当作
  第 N 个系列色;且始终图标 + 文字同现,不靠颜色单独表意

图表规范:
- 单一 y 轴,绝不双轴;量纲不同的指标拆成不同图
- 2px 线宽、4px 圆角柱端锚定基线、堆叠段间 2px 表面色间隙、
  悬停标记 2px 表面色描边
- 两系列以上必有图例,单系列不加(标题已经点明)
- 折线 connectNulls,设备漏记的日子不把线打断
- 数值文字一律用文字色令牌,不染系列色

其他:
- 主题切换(自动/浅色/深色),选择写入 localStorage 并标在 <html>
- 导航改为顶部横向,移动端可横滑
- 表格、徽章、空状态等组件统一到设计令牌

验证方式: DOM 审计确认 2px 线宽、圆角为 A 4,4 弧、堆叠段
2px 间隙、图例数量与系列数匹配、两档主题令牌各自解析到校验过的色值。

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-23 21:17:08 +08:00
ericwyuan
d73405decb Initial commit: Set up Garmin Health Lab project structure
- Initialize monorepo with root workspace configuration
- Set up Express.js backend with TypeScript
- Set up React 18 frontend with TypeScript
- Create database schema with SQLite
- Implement project architecture and documentation
- Add development and deployment guidelines

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-23 11:11:29 +08:00