需求 3.5 / 3.6 / 4.4 / 4.5 / 4.8 / 4.9 - 删掉导航栏右上角那两个 Link,就是它们渲染成半透明椭圆的。 睡眠入口改为点健康页的睡眠卡片,每日入口移进趋势页内容里。 - 新增 lib/metrics.ts 作为唯一的指标注册表。label/unit/取值函数原本在 今日、健康、趋势各写一份,改一处要改三处,也就有三次写不一致的机会。 - /metric/:id/ 指标详情:大数值 + 参考区间 + 7/30/90/365 趋势图 + 平均最高最低达标天数 + 这个指标是什么 + 评分依据(取自后端,不在前端另写一份) - /activity/:id/ 运动详情:概览/数据/分段/图表,数据分组照搬手表的排法, 心率区间用单色顺序色阶(区间是有序刻度,不是分类,不能用分类色) - /body-age/ 身体年龄:逐步展示 VO₂max 基准与各项修正,以及每步的出处 - 趋势页 15 个 chip 占满一屏且像张表单,改成弹窗选择,页面上只留一行摘要 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
84 lines
5.2 KiB
Markdown
84 lines
5.2 KiB
Markdown
# Garmin Health Lab — 需求文档
|
||
|
||
记录所有已提出的需求、理解与进度。**每完成一条:更新本文件的状态 → commit → push。**
|
||
|
||
状态:`✅ 已完成` · `🚧 进行中` · `📋 待做` · `⏸ 已搁置`
|
||
|
||
最后更新:2026-08-24
|
||
|
||
---
|
||
|
||
## 一、基础平台
|
||
|
||
| # | 需求 | 理解 | 状态 |
|
||
|---|---|---|---|
|
||
| 1.1 | 新建项目分析佳明海外账号健康数据 | Gitea 自建仓库,Web 应用 | ✅ |
|
||
| 1.2 | 部署到 NAS (192.168.50.64),用 MariaDB | Flask + gunicorn + MariaDB(socket),SQLite 供开发 | ✅ |
|
||
| 1.3 | 公网可访问 | frp 隧道 NAS:8123 → Oracle:8123 | ✅ |
|
||
| 1.4 | 开发过程中写单元测试 | 324 项 pytest | ⏸ 用户 2026-08-24 要求暂停,优先做功能 |
|
||
| 1.5 | 一任务一 commit,完成即推送 | 已成为固定流程 | ✅ |
|
||
|
||
## 二、数据同步
|
||
|
||
| # | 需求 | 理解 | 状态 |
|
||
|---|---|---|---|
|
||
| 2.1 | 同步佳明所有数据,不只是运动 | 31 项每日指标 + 运动 + 徽章 + 个人纪录 | ✅ |
|
||
| 2.2 | 验证码在前端输入(人不在电脑前) | Web MFA:后台线程阻塞在 `prompt_mfa`,验证码经数据库跨 worker 交接 | ✅ |
|
||
| 2.3 | 同步改为用户手动触发,不自动跑 | 同步是界面动作 | ✅ |
|
||
| 2.4 | 每小时后台同步最新数据 | `job_locks` 抢占,多 worker 只跑一次 | ✅ |
|
||
| 2.5 | 「同步最新数据」按钮 | `POST /api/garmin/sync-latest`,窗口 1–7 天,同步返回 | ✅ 接口完成,🚧 界面按钮 |
|
||
| 2.6 | 同步频率可设置 | 30 分 / 1 时 / 3 时 / 6 时 / 12 时 / 1 天 | ✅ 接口完成,🚧 界面 |
|
||
| 2.7 | 同步历史范围可设置(多久以前 / 全部) | 7/30/90/180/365/730 天,或全部 | ✅ 接口完成,🚧 界面 |
|
||
| 2.8 | 同步界面简化设计 | 去掉冗长说明,状态 + 两个动作为主 | 📋 |
|
||
|
||
## 三、界面框架
|
||
|
||
| # | 需求 | 理解 | 状态 |
|
||
|---|---|---|---|
|
||
| 3.1 | 前端推倒重做,要求好看 | Framework7 React (iOS 主题),桌面与手机都要好看 | ✅ |
|
||
| 3.2 | Tab:今日 / 健康 / 趋势 / 运动 / 设置 | 每日是趋势的子页 | ✅ |
|
||
| 3.3 | 首页改三圆环:步数 / 睡眠 / HRV | 并列三环,满环=进入参考区间 | ✅ |
|
||
| 3.4 | 交互流畅、有动画 | 数字滚动、入场揭示、`prefers-reduced-motion` | ✅ |
|
||
| 3.7 | 主界面切到子界面加 loading 动画 | 路由切换时的过渡指示 | 📋 |
|
||
| 3.5 | 删掉各页右上角的半透明椭圆 | 导航栏右侧 `Link`(带 tooltip)渲染出来的,已移除 | ✅ |
|
||
| 3.6 | 睡眠入口不放右上角,改为点健康页睡眠卡片进入 | 入口跟着内容走;每日入口同样移进趋势页内容 | ✅ |
|
||
|
||
## 四、数据展示
|
||
|
||
| # | 需求 | 理解 | 状态 |
|
||
|---|---|---|---|
|
||
| 4.1 | 每日详情模块,看某天所有数据 | 每日页 | ✅ |
|
||
| 4.2 | 趋势模块,7 天 / 月 / 季 / 年 周期 | 按周期取日均,桶长不同也可比 | ✅ |
|
||
| 4.3 | 趋势覆盖全部 15 组指标,可自选显示/隐藏 | 指标选择器 | ✅ |
|
||
| 4.4 | 指标选择器太丑,改成选择弹窗 | 改为 F7 Popup,页面上只留一行「显示指标 n/15」 | ✅ |
|
||
| 4.5 | 所有卡片可点击进入详情 | `/metric/:id/`:大数值 + 参考区间 + 趋势图 + 统计 + 依据;新增 `lib/metrics.ts` 统一指标注册表 | ✅ 健康页完成,🚧 今日页 |
|
||
| 4.6 | 今日页左右箭头切换前一天/后一天 | | 📋 |
|
||
| 4.7 | 今日页顶部日期选择控件,可看历史任一天 | | 📋 |
|
||
| 4.8 | 点击每个运动看本次运动详情,数据全展示 | 概览/数据/分段/图表四个 Tab,含心率区间条与时间/距离横轴切换 | ✅ |
|
||
| 4.9 | 健康页增加身体年龄 | 健康页卡片 + `/body-age/` 展示每一步推算过程与出处 | ✅ |
|
||
|
||
## 五、设置
|
||
|
||
| # | 需求 | 理解 | 状态 |
|
||
|---|---|---|---|
|
||
| 5.1 | 设置项太少:身高/体重/年龄/性别 | `user_settings` 表 | ✅ 接口完成,🚧 界面 |
|
||
| 5.2 | 单位设置 | 公制 / 英制 | ✅ 接口完成,🚧 界面 |
|
||
| 5.3 | 评分依据要在设置说明中显示 | `GET /api/settings/rating-basis`,逐条列出每个参考区间的出处 | ✅ 接口完成,🚧 界面 |
|
||
|
||
## 六、AI
|
||
|
||
| # | 需求 | 理解 | 状态 |
|
||
|---|---|---|---|
|
||
| 6.1 | 多个大上下文文本模型,可切换 | gateway / gemini-flash / llama-70b / nemotron-49b / mistral-large | ✅ |
|
||
| 6.2 | 暂时隐藏 AI 模块 | `FEATURES.ai = false` | ✅ |
|
||
| 6.3 | AI 用来解释,不用来定阈值 | 阈值全部来自公开参考值,AI 只负责解读 | ✅ 已确认为设计原则 |
|
||
|
||
---
|
||
|
||
## 设计原则(已达成一致)
|
||
|
||
1. **AI 不定阈值。** 让模型现编「正常范围」会得到一个不可复现、无法追溯、却带着医学口吻的数字。所有参考区间来自公开来源(WHO、AASM、Garmin 官方分级、人群常模),AI 只做解读。
|
||
2. **依据必须可见。** 任何把数字判为「偏低 / 正常 / 优秀」的区间都是在下判断,出处在 设置 → 评分依据 里逐条列出。
|
||
3. **身体年龄是估算。** garminconnect 0.2.8 没有 Fitness Age 接口,Garmin 的模型也不公开。本地按 VO₂max 常模推算并展示每一步中间值,明确标注不是医学评估。
|
||
4. **缺数据就说缺数据。** 指标没有值时显示「—」并说明原因,不用 0 冒充。
|