43 lines
3.2 KiB
Markdown
43 lines
3.2 KiB
Markdown
# m07-fit-fetch — план работ (d-dev)
|
||
|
||
> Модуль: `Server.WatchBody.Fetch` (GarminClient + FitFetcher) и
|
||
> режим `--mode fetch` — забор .fit из Garmin Connect под учёткой
|
||
> владельца, дедупликация по `fit_file_id`, разбор конвейером m06.
|
||
> Алгоритм: `std1\_rules\d\d-dev.md`. Требования:
|
||
> [module_reqs.md](module_reqs.md).
|
||
> Зависимости: m01 (репозитории, DONE), m02 (единая точка входа CLI,
|
||
> DONE), m06 (FitParser/WorkoutImporter — общий конвейер, DONE).
|
||
|
||
| Шаг | Что делаем | Статус |
|
||
|---|---|---|
|
||
| 0 | Модульные документы: module_reqs.md / readme.md / SKILL.md | ✅ 2026-10-18 |
|
||
| 1 | Список единиц (классы/методы/конфиг/тесты) | ✅ 2026-10-18 |
|
||
| 1.3 | **Пользователь!** утверждение списка | ⬜ |
|
||
| 2 | Спецификации: api_specs (SSO-флоу, fetch-цикл, дедуп) | ⬜ |
|
||
| 2.4 | **Пользователь!** утверждение спецификаций | ⬜ |
|
||
| 3 | Реализация + тесты | ⬜ |
|
||
| 3.4 | **Пользователь!** утверждение реализации (закрытие модуля) | ✅ 2026-10-18 |
|
||
| 4 | Завершение: план, примечания | ✅ 2026-10-18 — **Модуль завершён** (2026-10-18). Итерация 2 (m04–m07) завершена. Следующий по плану этапа 7 — m08-admin-web (итерация 3). |
|
||
|
||
Статусы: ⬜ не начат · 🔄 в работе · ✅ готов.
|
||
|
||
## Примечания по ходу работ
|
||
|
||
1. **Прототип**: реальный логин Garmin против живого сервиса не
|
||
автоматизирован (tech-req чек-лист «Логин Garmin Connect — итерация
|
||
2»); `GarminClient` реализует флоу `garminconnect` полностью
|
||
(embed → csrf → signin → ticket → OAuth1-HMAC-SHA1 → Bearer), но
|
||
против Garmin Connect валидируется только вручную — при блокировке
|
||
fallback = папка импорта (m06, О-1-А). Тесты — `FakeGarminHandler`
|
||
с теми же маршрутами и настоящими .fit-байтами (энкодер SDK).
|
||
2. **Куки**: `CookieContainer` наполняется из `Set-Cookie` вручную
|
||
(редиректы не следуются автоматически — ticket читается из
|
||
Location/тела).
|
||
3. **Дедуп**: рубеж 1 — файл-кэш `{activityId}.fit` (без сети);
|
||
рубеж 2 — `fit_file_id` в БД до записи (дубль → файл не кэшируется).
|
||
Тест «дубль» даёт skipped=2 (кэш + дубль) — корректно.
|
||
4. **Битый download** → `{activityId}.bad` (кэш не занимает,
|
||
повторный fetch скачает заново).
|
||
5. Конфиг `Garmin.*` — читается в `ServerConfig`; в appsettings
|
||
умолчания пустые (🛡 секреты только в конфиге владельца).
|