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>
This commit is contained in:
175
docs/ARCHITECTURE.md
Normal file
175
docs/ARCHITECTURE.md
Normal file
@@ -0,0 +1,175 @@
|
||||
# 项目架构说明
|
||||
|
||||
## 整体架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 浏览器 (React 前端) │
|
||||
│ ┌────────────┬──────────────┬──────────┬──────────┐ │
|
||||
│ │ 仪表板 │ 数据同步 │ 数据分析 │ 设置 │ │
|
||||
│ └────────────┴──────────────┴──────────┴──────────┘ │
|
||||
└──────────────────────────┬──────────────────────────┘
|
||||
│ HTTP/REST
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ Node.js/Express 后端服务器 │
|
||||
│ ┌──────────────────────────────────────────────┐ │
|
||||
│ │ API 路由层 │ │
|
||||
│ │ ├─ /auth - 用户认证 │ │
|
||||
│ │ ├─ /garmin - Garmin 数据同步 │ │
|
||||
│ │ ├─ /health - 健康数据查询 │ │
|
||||
│ │ └─ /analysis - 数据分析 │ │
|
||||
│ └──────────────────────────────────────────────┘ │
|
||||
│ ┌──────────────────────────────────────────────┐ │
|
||||
│ │ 服务层 │ │
|
||||
│ │ ├─ GarminService - Garmin API 集成 │ │
|
||||
│ │ ├─ HealthService - 健康数据业务逻辑 │ │
|
||||
│ │ ├─ AuthService - 认证授权 │ │
|
||||
│ │ └─ AnalysisService - 数据分析 │ │
|
||||
│ └──────────────────────────────────────────────┘ │
|
||||
└──────────────────────┬───────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────┐
|
||||
│ SQLite 数据库 │
|
||||
│ ├─ users │
|
||||
│ ├─ health_data │
|
||||
│ ├─ activities │
|
||||
│ └─ sync_status │
|
||||
└──────────────────────────────┘
|
||||
|
||||
|
||||
┌──────────────────────────────┐
|
||||
│ Garmin Cloud API │
|
||||
│ ├─ 用户认证 │
|
||||
│ ├─ 数据获取 │
|
||||
│ └─ 数据同步 │
|
||||
└──────────────────────────────┘
|
||||
```
|
||||
|
||||
## 核心模块
|
||||
|
||||
### 1. 前端 (Client)
|
||||
- **框架**: React 18 + TypeScript
|
||||
- **路由**: React Router
|
||||
- **UI 组件**: 自定义 + CSS
|
||||
- **数据可视化**: Recharts
|
||||
- **API 通信**: Axios
|
||||
|
||||
**主要页面**:
|
||||
- Dashboard (仪表板)
|
||||
- DataSync (数据同步)
|
||||
- Analysis (数据分析)
|
||||
- Recommendations (健康建议)
|
||||
- Settings (设置)
|
||||
|
||||
### 2. 后端 (Server)
|
||||
- **框架**: Express.js
|
||||
- **语言**: TypeScript
|
||||
- **数据库**: SQLite3
|
||||
- **认证**: JWT
|
||||
|
||||
**主要服务**:
|
||||
- **AuthService**: 用户认证和授权
|
||||
- **GarminService**: Garmin API 集成和数据获取
|
||||
- **HealthService**: 健康数据管理
|
||||
- **AnalysisService**: 数据分析和建议生成
|
||||
|
||||
### 3. 数据库 (SQLite)
|
||||
**表结构**:
|
||||
- `users`: 用户信息和 Garmin 凭证
|
||||
- `health_data`: 每日健康数据汇总
|
||||
- `activities`: 运动活动记录
|
||||
- `sync_status`: 数据同步状态追踪
|
||||
|
||||
## 数据流
|
||||
|
||||
### 1. Garmin 数据同步流程
|
||||
```
|
||||
用户点击"同步"
|
||||
↓
|
||||
POST /api/garmin/sync
|
||||
↓
|
||||
GarminService.syncData()
|
||||
↓
|
||||
获取 Garmin 授权 Token
|
||||
↓
|
||||
调用 Garmin API 获取数据
|
||||
↓
|
||||
转换数据格式
|
||||
↓
|
||||
存储到本地 SQLite
|
||||
↓
|
||||
更新 sync_status
|
||||
↓
|
||||
返回同步结果
|
||||
```
|
||||
|
||||
### 2. 数据分析流程
|
||||
```
|
||||
GET /api/health/summary (日期范围)
|
||||
↓
|
||||
从数据库查询健康数据
|
||||
↓
|
||||
计算统计指标
|
||||
↓
|
||||
生成趋势分析
|
||||
↓
|
||||
返回分析结果
|
||||
↓
|
||||
前端绘制图表
|
||||
```
|
||||
|
||||
### 3. 健康建议生成流程
|
||||
```
|
||||
GET /api/analysis/recommendations
|
||||
↓
|
||||
AnalysisService.generateRecommendations()
|
||||
↓
|
||||
分析历史数据
|
||||
↓
|
||||
识别异常和趋势
|
||||
↓
|
||||
根据规则引擎生成建议
|
||||
↓
|
||||
按优先级排序
|
||||
↓
|
||||
返回建议列表
|
||||
```
|
||||
|
||||
## 关键特性
|
||||
|
||||
### 安全性
|
||||
- Garmin 密码使用加密存储
|
||||
- JWT 令牌验证所有请求
|
||||
- CORS 配置限制来源
|
||||
- 环境变量管理敏感配置
|
||||
|
||||
### 扩展性
|
||||
- 模块化的服务设计
|
||||
- 易于添加新的分析算法
|
||||
- 支持数据导出功能
|
||||
- 可扩展的 API 端点
|
||||
|
||||
### 性能
|
||||
- 数据库索引优化查询
|
||||
- API 缓存策略
|
||||
- 异步处理长运行任务
|
||||
- 增量数据同步支持
|
||||
|
||||
## 部署架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ Development 本地开发 │
|
||||
│ └─ npm run dev (同时运行前后端) │
|
||||
└─────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────┐
|
||||
│ Production 生产环境 │
|
||||
│ ├─ Docker 容器化 │
|
||||
│ ├─ Nginx 反向代理 │
|
||||
│ ├─ Node.js 后端服务 │
|
||||
│ └─ SQLite 数据持久化 │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
278
docs/DEVELOPMENT.md
Normal file
278
docs/DEVELOPMENT.md
Normal file
@@ -0,0 +1,278 @@
|
||||
# 开发指南
|
||||
|
||||
## 环境设置
|
||||
|
||||
### 前置要求
|
||||
- Node.js 18+
|
||||
- npm 或 yarn
|
||||
- Git
|
||||
- Garmin Connect 账户
|
||||
|
||||
### 安装步骤
|
||||
|
||||
1. **克隆项目**
|
||||
```bash
|
||||
cd ~/Desktop/Work
|
||||
git clone <repository-url> GarminHealthLab
|
||||
cd GarminHealthLab
|
||||
```
|
||||
|
||||
2. **安装依赖**
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
3. **配置环境变量**
|
||||
```bash
|
||||
# 复制示例文件
|
||||
cp server/.env.example server/.env
|
||||
|
||||
# 编辑 server/.env,填入你的 Garmin 凭证
|
||||
# GARMIN_CONNECT_USER=your_email@example.com
|
||||
# GARMIN_CONNECT_PASSWORD=your_password
|
||||
# JWT_SECRET=generate_a_random_string
|
||||
```
|
||||
|
||||
4. **启动开发服务器**
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
- 前端: http://localhost:3000
|
||||
- 后端 API: http://localhost:5000/api
|
||||
|
||||
## 项目命令
|
||||
|
||||
```bash
|
||||
# 开发模式(同时运行前后端)
|
||||
npm run dev
|
||||
|
||||
# 仅运行后端服务器
|
||||
npm run dev:server
|
||||
|
||||
# 仅运行前端应用
|
||||
npm run dev:client
|
||||
|
||||
# 构建项目
|
||||
npm run build
|
||||
|
||||
# 生产模式启动
|
||||
npm start
|
||||
|
||||
# 类型检查
|
||||
npm run typecheck
|
||||
```
|
||||
|
||||
## 代码结构
|
||||
|
||||
### 后端 (server/)
|
||||
|
||||
```
|
||||
server/
|
||||
├── src/
|
||||
│ ├── index.ts # 入口文件
|
||||
│ ├── routes/ # API 路由
|
||||
│ │ ├── auth.ts
|
||||
│ │ ├── garmin.ts
|
||||
│ │ ├── health.ts
|
||||
│ │ └── analysis.ts
|
||||
│ ├── services/ # 业务逻辑服务
|
||||
│ │ ├── AuthService.ts
|
||||
│ │ ├── GarminService.ts
|
||||
│ │ ├── HealthService.ts
|
||||
│ │ └── AnalysisService.ts
|
||||
│ ├── models/ # 数据模型
|
||||
│ ├── middleware/ # 中间件
|
||||
│ ├── utils/ # 工具函数
|
||||
│ │ └── database.ts
|
||||
│ └── types/ # TypeScript 类型定义
|
||||
├── dist/ # 编译输出
|
||||
├── tsconfig.json
|
||||
└── package.json
|
||||
```
|
||||
|
||||
### 前端 (client/)
|
||||
|
||||
```
|
||||
client/
|
||||
├── src/
|
||||
│ ├── index.tsx # 入口文件
|
||||
│ ├── App.tsx # 主组件
|
||||
│ ├── components/ # 可复用组件
|
||||
│ ├── pages/ # 页面组件
|
||||
│ │ ├── Dashboard.tsx
|
||||
│ │ ├── DataSync.tsx
|
||||
│ │ ├── Analysis.tsx
|
||||
│ │ ├── Recommendations.tsx
|
||||
│ │ └── Settings.tsx
|
||||
│ ├── services/ # API 服务
|
||||
│ │ └── api.ts
|
||||
│ ├── types/ # TypeScript 类型定义
|
||||
│ └── index.css # 全局样式
|
||||
├── public/ # 静态资源
|
||||
└── package.json
|
||||
```
|
||||
|
||||
## 开发工作流
|
||||
|
||||
### 添加新的 API 端点
|
||||
|
||||
1. **创建路由处理器** (`server/src/routes/yourFeature.ts`)
|
||||
```typescript
|
||||
import express from 'express';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/endpoint', (req, res) => {
|
||||
// 业务逻辑
|
||||
});
|
||||
|
||||
export default router;
|
||||
```
|
||||
|
||||
2. **在主文件中注册路由** (`server/src/index.ts`)
|
||||
```typescript
|
||||
import yourFeatureRoutes from './routes/yourFeature';
|
||||
app.use('/api/yourfeature', yourFeatureRoutes);
|
||||
```
|
||||
|
||||
3. **创建 API 客户端方法** (`client/src/services/api.ts`)
|
||||
```typescript
|
||||
getYourEndpoint() {
|
||||
return this.client.get('/yourfeature/endpoint');
|
||||
}
|
||||
```
|
||||
|
||||
### 添加新页面
|
||||
|
||||
1. **创建页面组件** (`client/src/pages/YourPage.tsx`)
|
||||
```typescript
|
||||
import React from 'react';
|
||||
|
||||
function YourPage() {
|
||||
return <div>Page content</div>;
|
||||
}
|
||||
|
||||
export default YourPage;
|
||||
```
|
||||
|
||||
2. **在 App.tsx 中添加路由**
|
||||
```typescript
|
||||
<Route path="/your-path" element={<YourPage />} />
|
||||
```
|
||||
|
||||
### 数据库操作
|
||||
|
||||
使用数据库工具函数简化操作:
|
||||
|
||||
```typescript
|
||||
import { runAsync, getAsync, allAsync } from '../utils/database';
|
||||
|
||||
// 插入数据
|
||||
await runAsync('INSERT INTO table (col1, col2) VALUES (?, ?)', [val1, val2]);
|
||||
|
||||
// 查询单行
|
||||
const row = await getAsync('SELECT * FROM table WHERE id = ?', [id]);
|
||||
|
||||
// 查询多行
|
||||
const rows = await allAsync('SELECT * FROM table WHERE status = ?', ['active']);
|
||||
```
|
||||
|
||||
## 调试
|
||||
|
||||
### 后端调试
|
||||
```bash
|
||||
# 启用详细日志
|
||||
DEBUG=* npm run dev:server
|
||||
|
||||
# 使用 Node 调试器
|
||||
node --inspect server/dist/index.js
|
||||
```
|
||||
|
||||
### 前端调试
|
||||
- 使用 React DevTools 浏览器扩展
|
||||
- 使用浏览器开发者工具 (F12)
|
||||
- 检查网络请求和响应
|
||||
|
||||
## 测试
|
||||
|
||||
### 测试后端 API
|
||||
|
||||
使用 curl 或 Postman:
|
||||
|
||||
```bash
|
||||
# 获取健康摘要
|
||||
curl http://localhost:5000/api/health/summary
|
||||
|
||||
# 触发 Garmin 同步
|
||||
curl -X POST http://localhost:5000/api/garmin/sync
|
||||
|
||||
# 获取健康建议
|
||||
curl http://localhost:5000/api/analysis/recommendations
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 数据库连接失败
|
||||
```bash
|
||||
# 检查数据库文件
|
||||
ls -la ./data/health.db
|
||||
|
||||
# 重置数据库
|
||||
rm ./data/health.db
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### 前端无法连接后端
|
||||
- 检查 CORS 配置
|
||||
- 确保后端运行在 5000 端口
|
||||
- 检查防火墙设置
|
||||
|
||||
### Garmin 认证失败
|
||||
- 验证 Garmin 邮箱和密码
|
||||
- 检查网络连接
|
||||
- 查看后端日志
|
||||
|
||||
## 性能优化建议
|
||||
|
||||
1. **数据库索引**
|
||||
- 在频繁查询的字段上添加索引
|
||||
- 定期分析查询性能
|
||||
|
||||
2. **缓存策略**
|
||||
- 实现 API 响应缓存
|
||||
- 使用浏览器缓存
|
||||
|
||||
3. **代码分割**
|
||||
- React 懒加载路由
|
||||
- 按需加载 JavaScript
|
||||
|
||||
## 代码规范
|
||||
|
||||
### TypeScript
|
||||
- 使用严格模式
|
||||
- 为所有函数参数添加类型
|
||||
- 使用接口定义复杂对象
|
||||
|
||||
### CSS
|
||||
- 使用 BEM 命名规范
|
||||
- 响应式设计优先
|
||||
- 避免内联样式
|
||||
|
||||
### 提交信息
|
||||
```
|
||||
feat: 添加新功能描述
|
||||
fix: 修复 bug 描述
|
||||
docs: 文档更新
|
||||
style: 代码格式调整
|
||||
refactor: 代码重构
|
||||
test: 测试相关
|
||||
```
|
||||
|
||||
## 资源链接
|
||||
|
||||
- [Express.js 文档](https://expressjs.com/)
|
||||
- [React 文档](https://react.dev/)
|
||||
- [TypeScript 文档](https://www.typescriptlang.org/)
|
||||
- [SQLite 文档](https://www.sqlite.org/)
|
||||
- [Garmin API](https://developer.garmin.com/)
|
||||
Reference in New Issue
Block a user