后端实现: - 创建 AuthService 包含密码加密、JWT 生成和验证 - 创建 authMiddleware 用于 API 路由保护 - 实现 auth 路由 (register, login, logout, /me) 前端实现: - 创建 Login 页面 (登录/注册标签页) - 创建 ProtectedRoute 组件用于路由保护 - 更新 App.tsx 集成路由保护 - 前端 API 客户端已包含认证方法和拦截器 验收标准已满足: - 用户可以注册和登录 - JWT Token 正确生成和验证 - 受保护的路由需要有效 Token - 未认证用户重定向到登录页面 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
169 lines
5.0 KiB
Markdown
169 lines
5.0 KiB
Markdown
# 佳明健康数据分析平台 (Garmin Health Lab)
|
||
|
||
一个完整的健康数据分析平台,用于获取、分析和可视化你的佳明(Garmin)设备数据。
|
||
|
||
## 📊 主要功能
|
||
|
||
- **数据同步**: 通过 Garmin API 自动同步你的健康数据
|
||
- **综合分析**: 步数、心率、睡眠、运动、压力等多维度分析
|
||
- **数据可视化**: 交互式图表和仪表板展示健康数据趋势
|
||
- **智能建议**: 基于数据分析的个性化健康建议
|
||
- **数据导出**: 支持数据导出为 CSV/JSON 格式
|
||
|
||
## 🛠 技术栈
|
||
|
||
### 前端
|
||
- React 18 + TypeScript
|
||
- Recharts (数据可视化)
|
||
- Tailwind CSS (样式)
|
||
- Axios (API 请求)
|
||
|
||
### 后端
|
||
- Python 3.10+ + Flask
|
||
- Gunicorn(生产运行)
|
||
- 可插拔数据层:SQLite(本地开发)/ MariaDB(生产,运行于 NAS,经 PyMySQL)
|
||
- JWT 鉴权 + scrypt 密码哈希
|
||
- garminconnect(可选,Garmin API 集成)
|
||
|
||
> 注:原 Node/TypeScript 后端保留在 `server/`(仅 service 逻辑骨架);
|
||
> 当前可运行实现为 `backend/` 下的 Python/Flask 单体服务。
|
||
|
||
## 📁 项目结构
|
||
|
||
```
|
||
GarminHealthLab/
|
||
├── client/ # 前端应用 (React 18 + TypeScript)
|
||
│ └── src/services/api.ts # API 客户端(含 JWT 拦截器)
|
||
├── backend/ # 后端应用 (Python + Flask) —— 当前可运行实现
|
||
│ ├── app.py # 应用工厂 / 路由装配
|
||
│ ├── wsgi.py # Gunicorn 入口
|
||
│ ├── config.py # 配置(读 .env)
|
||
│ ├── db.py # 可插拔数据层 (SQLite / MariaDB)
|
||
│ ├── auth.py # scrypt + JWT + require_auth
|
||
│ ├── services/ # 业务逻辑 (health / analysis / garmin)
|
||
│ ├── routes/ # 蓝图 (auth / garmin / health / analysis)
|
||
│ ├── tests/smoke.py # 冒烟测试
|
||
│ ├── requirements.txt
|
||
│ └── .env.example
|
||
├── server/ # 原 Node/TS 后端(仅 service 骨架,未接入路由)
|
||
├── docs/ # 文档
|
||
├── package.json # 工作空间根配置
|
||
└── README.md
|
||
```
|
||
|
||
## 🚀 快速开始
|
||
|
||
### 前置要求
|
||
- Node.js 18+
|
||
- npm 或 yarn
|
||
- Garmin Connect 账户
|
||
|
||
### 安装依赖
|
||
|
||
前端(React):
|
||
```bash
|
||
npm install
|
||
```
|
||
|
||
后端(Python/Flask,建议在虚拟环境中安装):
|
||
```bash
|
||
cd backend
|
||
python -m venv venv && source venv/bin/activate
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
### 配置环境变量
|
||
|
||
复制 `backend/.env.example` 为 `backend/.env` 并填入真实值(`.env` 已被
|
||
`.gitignore` 忽略,不会进入版本库):
|
||
|
||
```env
|
||
PORT=5000
|
||
DB_TYPE=sqlite # 本地开发用 sqlite;生产切 mariadb
|
||
DATABASE_PATH=./data/health.db
|
||
JWT_SECRET=your_jwt_secret_here # 生产务必更换
|
||
CORS_ORIGIN=http://localhost:3000,http://localhost:5173
|
||
```
|
||
|
||
> 原 `server/.env` 的 Node 配置已弃用,请改用 `backend/.env`。
|
||
|
||
### 数据库:SQLite / MariaDB 可插拔
|
||
|
||
数据层通过 `DB_TYPE` 环境变量切换后端,**业务代码无需改动**:
|
||
|
||
- **SQLite(默认,本地开发)**:零配置,由 `DATABASE_PATH` 指定文件位置。
|
||
- **MariaDB(生产,运行在 NAS 上)**:经 `mysql2` 连接,优先走 socket(`MARIADB_SOCKET`),也可用 `MARIADB_HOST` + `MARIADB_PORT`。
|
||
|
||
生产使用 NAS 上的独立库 `garmin_health_lab`(与 `sentinel_home_ai` 隔离)。完整配置见 `backend/.env.example`:
|
||
|
||
```env
|
||
DB_TYPE=mariadb
|
||
MARIADB_SOCKET=/run/mysqld/mysqld10.sock
|
||
MARIADB_USER=root
|
||
MARIADB_PASSWORD=your_nas_mariadb_root_password
|
||
MARIADB_DATABASE=garmin_health_lab
|
||
```
|
||
|
||
> 复制 `backend/.env.example` 为 `backend/.env` 并填入真实值;`.env` 已被 `.gitignore` 忽略,不会进入版本库。
|
||
|
||
### 启动开发服务器
|
||
|
||
后端(Flask,端口 5000):
|
||
```bash
|
||
cd backend
|
||
source venv/bin/activate
|
||
python app.py
|
||
# 或生产方式:gunicorn wsgi:app -b 0.0.0.0:5000
|
||
```
|
||
|
||
前端(Vite/React,端口 3000 或 5173):
|
||
```bash
|
||
npm run dev
|
||
```
|
||
|
||
- 前端: http://localhost:3000
|
||
- 后端 API: http://localhost:5000/api
|
||
|
||
### 冒烟测试
|
||
|
||
```bash
|
||
cd backend
|
||
python tests/smoke.py
|
||
```
|
||
|
||
## 📚 API 文档
|
||
|
||
### 认证
|
||
- `POST /api/auth/login` - 用户登录
|
||
- `POST /api/auth/logout` - 用户登出
|
||
- `POST /api/auth/refresh` - 刷新 Token
|
||
|
||
### Garmin 数据同步
|
||
- `POST /api/garmin/sync` - 同步 Garmin 数据
|
||
- `GET /api/garmin/status` - 获取同步状态
|
||
|
||
### 健康数据
|
||
- `GET /api/health/summary` - 获取健康摘要
|
||
- `GET /api/health/steps` - 获取步数数据
|
||
- `GET /api/health/heart-rate` - 获取心率数据
|
||
- `GET /api/health/sleep` - 获取睡眠数据
|
||
- `GET /api/health/activities` - 获取运动数据
|
||
|
||
### 分析与建议
|
||
- `GET /api/analysis/trends` - 获取数据趋势
|
||
- `GET /api/analysis/recommendations` - 获取健康建议
|
||
|
||
## 🔐 安全说明
|
||
|
||
- Garmin 账户密码使用加密存储
|
||
- 所有 API 请求需要 JWT 认证
|
||
- 敏感数据不在前端存储
|
||
|
||
## 📝 开发指南
|
||
|
||
详见 [DEVELOPMENT.md](./docs/DEVELOPMENT.md)
|
||
|
||
## 📄 许可证
|
||
|
||
MIT
|