feat: разбор и хранение тренировок и состояния разума
- секции `workouts` и `stateOfMind` покрыты разбором: тренировка лежит одной строкой вместе с маршрутом и внутренними рядами, запись — по ключу `род + id`; миграция 00007 заводит обе таблицы и возвращает в очередь `partial`-доставки с этими ключами - сущность заменяется целиком, но условно: приехавшая побеждает, если не теряет содержания сохранённой (множество ключей и длины верхнеуровневых массивов), а при равном содержании выигрывает версия из более поздней доставки ЖУРНАЛА — «побеждает приехавшая» было бы функцией порядка свёртки, и живая витрина расходилась бы с пересборкой молча - отпечаток витрины покрывает тренировки и записи и снимается одним снимком базы; отчёт `reindex` считает «было и стало» по каждой единице хранения
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
# Идентичность тренировок при импорте родного экспорта
|
||||
|
||||
**Приоритет:** средний
|
||||
|
||||
Тренировка в витрине адресуется своим `id` из HealthKit — его шлёт HAE. В
|
||||
`export.xml` этого идентификатора **нет вовсе**: у элемента `Workout` только
|
||||
тип, источник, даты и статистика. Значит `healthlog import` не сможет сопоставить
|
||||
тренировку из снапшота с той же тренировкой, уже приехавшей от HAE, и они
|
||||
задвоятся.
|
||||
|
||||
Это ровно та дыра, что была у точек, и там её закрыли ключом `start + end`
|
||||
(находка 47): `HKObject.uuid` в выгрузку не попадает, поэтому модель
|
||||
идентичности обязана выражаться через интервал.
|
||||
|
||||
Prior art: `dogsheep/healthkit-to-sqlite` адресует тренировку **хешем
|
||||
содержимого** (`hash_id` в sqlite-utils) — ровно потому, что идентификатора в
|
||||
экспорте нет. Нам это не подходит в лоб: у нас половина тренировок уже лежит под
|
||||
настоящим `id`, и хеш содержимого дал бы третий ключ рядом с двумя.
|
||||
|
||||
Варианты, которые надо будет сравнить:
|
||||
|
||||
- **Второй уникальный ключ `(start_utc, end_utc)`** у тренировки: импорт ищет по
|
||||
нему, HAE — по `id`. Цена: индекс и вопрос, что делать при столкновении двух
|
||||
разных тренировок с одним интервалом (бывает ли такое — неизвестно).
|
||||
- **Сопоставление на стадии импорта**, без изменения схемы: импорт читает уже
|
||||
сохранённые тренировки за период и приписывает найденным их `id`. Цена: логика
|
||||
сопоставления живёт в импорте и не проверяется ничем, кроме него.
|
||||
- **Считать тренировки из экспорта отдельным родом** и не сопоставлять вовсе.
|
||||
Цена: потребитель видит две тренировки вместо одной и обязан схлопывать сам —
|
||||
ровно то, чего проект старается не делать.
|
||||
|
||||
Решать до появления формы `healthlog import` значит угадывать: неизвестно,
|
||||
понадобятся ли тренировки из экспорта вообще (у HAE они полнее — с маршрутом и
|
||||
рядами, а в экспорте маршрут лежит отдельными GPX).
|
||||
|
||||
Связано: `docs/architecture.md` → «Тренировки и прочие секции», задача
|
||||
`import-eksporta-apple`.
|
||||
Reference in New Issue
Block a user