VEU.WathBody/1-docs/4-modules/m07-fit-fetch/api_specs/01-garmin-client.md

52 lines
2.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Спецификация 01: GarminClient — SSO и API Garmin Connect
Источники: tech-req разд. 5 (FitFetcher — «по контракту семьи
библиотек garminconnect»), Ф-8.1, vision (SSO-последовательность).
Прототип: против живого Garmin не автоматизируется; тесты —
фейковый `HttpMessageHandler` с теми же маршрутами.
## 1. Сигнатуры
```csharp
public class GarminClient
{
public GarminClient(string login, string password,
string baseUrl, HttpMessageHandler? handler = null);
public void Login(CancellationToken ct = default); // SSO → Bearer
public List<GarminActivity> ListActivities(int limit, CancellationToken ct = default);
public byte[] DownloadFit(long activityId, CancellationToken ct = default);
}
public sealed record GarminActivity(
long ActivityId, DateTime StartTimeLocal, string ActivityType);
```
## 2. Маршруты (по контракту garminconnect; `{base}` = `Garmin.BaseUrl`)
| Шаг | Запрос | Что берём |
|---|---|---|
| 1 | `GET {base}/sso/embed` | cookies (SSO) |
| 2 | `GET {base}/sso/signin` | csrf из html (`name="_csrf"`) |
| 3 | `POST {base}/sso/signin` (form: username, password, embed, csrf) | ticket из редиректа (`?ticket=…`); неуспех → `GarminAuthException` |
| 4 | `GET {base}/modern/?ticket=…` | cookies современного домена |
| 5 | `POST {base}/sso/api/2.0/oauth/exchange/service/user/2.0` (OAuth1-подпись тестовыми consumer key/secret) | Bearer `access_token` |
| 6 | `GET {base}/activitylist-service/activities/search/activities?limit=N&start=0` | JSON список: `activityId`, `startTimeLocal`, `activityType.typeKey` |
| 7 | `GET {base}/download-service/files/activity/{id}` | байты .fit |
Все запросы после шага 5 — заголовок `Authorization: Bearer …`.
Таймаут HttpClient — 30 с. 🛡 пароль и токены в логи не попадают
(исключения — без credential-текста).
## 3. Тестовый handler
`FakeGarminHandler : HttpMessageHandler` — маршруты разд. 2 на
`{base}`; список и байты .fit задаёт тест (`FitParser.WriteTestFile`);
режим `FailLogin` — шаг 3 возвращает 401.
## 4. Ошибки
- `GarminAuthException` — шаги 1–5 (логин/MFA/блокировка); текст
содержит шаг и код ответа, **не содержит** пароль;
- `HttpRequestException`/`TaskCanceledException` — сеть/таймаут
(сеть сбоит в тестах подменой handler).