# Steps数据显示问题修复总结

## 问题描述

步数（Steps）数据在健康数据查询中显示为 `N/A`，尽管这是手表最基本的数据，应该是存在的。

## 根本原因

**问题1：使用了错误的API**
- 原代码使用 `client.get_steps_data(date)` API
- 该API返回的是**96个15分钟间隔的分段数据**，而不是每日汇总
- 代码只取了列表的第一个元素（第一个15分钟段），导致数据不完整

**问题2：数据结构不匹配**
- `get_steps_data` 返回的数据字段为：`steps`, `startGMT`, `endGMT` 等
- 代码期望的字段为：`totalSteps`, `totalDistance`, `dailyStepGoal` 等
- 由于字段名不匹配，所有顶层字段都被设置为 `None`

**数据对比：**

错误API (`get_steps_data`) 返回的数据：
```json
[
  {
    "startGMT": "2026-01-18T16:00:00.0",
    "endGMT": "2026-01-18T16:15:00.0",
    "steps": 71,  // 只是一个15分钟段的步数
    "pushes": 0,
    "primaryActivityLevel": "sedentary"
  },
  // ... 共96个元素（一天24小时 × 4个15分钟段）
]
```

正确API (`get_daily_steps`) 返回的数据：
```json
[
  {
    "calendarDate": "2026-01-19",
    "totalSteps": 9741,  // 全天总步数
    "totalDistance": 7769,  // 总距离（米）
    "stepGoal": 10550  // 步数目标
  }
]
```

## 修复方案

### 1. 修改 `health/services/garmin_client.py`

**修改前：**
```python
def fetch_steps(self, target_date: date) -> Optional[StepsData]:
    raw_data_list = self._retry_api_call(
        self.client.get_steps_data, target_date.isoformat()
    )
    # ...
    raw_data = raw_data_list[0]  # 只取第一个15分钟段

    return StepsData(
        date=target_date,
        total_steps=raw_data.get("totalSteps"),  # 不存在
        total_distance_meters=raw_data.get("totalDistance"),  # 不存在
        calories_burned=raw_data.get("totalKilocalories"),  # 不存在
        step_goal=raw_data.get("dailyStepGoal"),  # 不存在
        raw_data=raw_data,
    )
```

**修改后：**
```python
def fetch_steps(self, target_date: date) -> Optional[StepsData]:
    # Use get_daily_steps to get daily summary instead of 15-min intervals
    raw_data_list = self._retry_api_call(
        self.client.get_daily_steps,
        target_date.isoformat(),
        target_date.isoformat()
    )
    # ...
    raw_data = raw_data_list[0]

    return StepsData(
        date=target_date,
        total_steps=raw_data.get("totalSteps"),  # ✅ 正确字段
        total_distance_meters=raw_data.get("totalDistance"),  # ✅ 正确字段
        calories_burned=raw_data.get("calories"),
        step_goal=raw_data.get("stepGoal"),  # ✅ 正确字段
        raw_data=raw_data,
    )
```

### 2. 创建重新同步脚本 `scripts/resync_steps.py`

用于批量重新同步已有的步数数据：

```bash
# 重新同步指定日期范围的步数数据
python scripts/resync_steps.py --start 2026-01-01 --end 2026-01-19

# 重新同步从指定日期到昨天的所有数据
python scripts/resync_steps.py --start 2026-01-01
```

## 验证结果

### 修复前：
```
🚶 Steps:
   Total Steps: N/A
```

### 修复后：
```
🚶 Steps:
   Total Steps: 12,373
   Distance: 9.85 km
```

### 统计数据示例：
```bash
$ python -m health.cli.query range steps 2026-01-14 2026-01-19 --stats

📊 STEPS - 6 records
date                 | total_steps          | total_distance_meters
------------------------------------------------------------------------
2026-01-14           | 10,461               | 8,365.00
2026-01-15           | 9,114                | 7,257.00
2026-01-16           | 12,373               | 9,851.00
2026-01-17           | 6,580                | 5,245.00
2026-01-18           | 10,118               | 8,060.00
2026-01-19           | 9,741                | 7,769.00

📈 Statistics Summary:
total_steps:
  Min: 6580
  Max: 12373
  Avg: 9731.17
  Count: 6
```

## 重新同步历史数据

如果你有大量历史数据需要重新同步，运行：

```bash
# 重新同步2024年的所有数据
python scripts/resync_steps.py --start 2024-01-01 --end 2024-12-31

# 重新同步2025年至今的所有数据
python scripts/resync_steps.py --start 2025-01-01

# 重新同步最近30天的数据
python scripts/resync_steps.py --start $(date -v-30d +%Y-%m-%d)
```

**注意：** Garmin API有速率限制，如果同步大量数据，可能需要分批进行。

## 技术细节

### Garmin API方法对比

| API方法 | 用途 | 返回数据量 | 数据粒度 |
|---------|------|-----------|---------|
| `get_steps_data(date)` | 获取详细活动数据 | 96条记录 | 15分钟 |
| `get_daily_steps(start, end)` | 获取每日汇总 | 1条记录/天 | 每日 |
| `get_weekly_steps(start, end)` | 获取每周汇总 | 1条记录/周 | 每周 |

### 建议

- **每日同步**：使用 `get_daily_steps` 获取汇总数据（推荐）
- **详细分析**：如果需要分析一天内的活动模式，使用 `get_steps_data` 并汇总所有15分钟段
- **长期趋势**：使用 `get_weekly_steps` 获取周汇总数据

## 未来改进

可以考虑同时存储两种数据：
1. 每日汇总数据 - 用于快速查询和统计
2. 15分钟分段数据 - 用于详细分析一天内的活动模式

这样可以支持更丰富的数据分析功能，例如：
- 一天中哪个时间段最活跃
- 久坐时间分析
- 活动模式识别
