- секции `workouts` и `stateOfMind` покрыты разбором: тренировка лежит одной строкой вместе с маршрутом и внутренними рядами, запись — по ключу `род + id`; миграция 00007 заводит обе таблицы и возвращает в очередь `partial`-доставки с этими ключами - сущность заменяется целиком, но условно: приехавшая побеждает, если не теряет содержания сохранённой (множество ключей и длины верхнеуровневых массивов), а при равном содержании выигрывает версия из более поздней доставки ЖУРНАЛА — «побеждает приехавшая» было бы функцией порядка свёртки, и живая витрина расходилась бы с пересборкой молча - отпечаток витрины покрывает тренировки и записи и снимается одним снимком базы; отчёт `reindex` считает «было и стало» по каждой единице хранения
3.1 KiB
Идентичность тренировок при импорте родного экспорта
Приоритет: средний
Тренировка в витрине адресуется своим 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.