# ✨ Импортировать родной экспорт Apple Health - **Тип:** feature - **Категория:** Ядро - **Зачем:** Слой sample пуст: полная история и точные сэмплы лежат в zip-архиве и никуда не едут - **Теги:** goal:native-export-import Слой `sample` пуст: настоящих сэмплов HealthKit в потоке нет вовсе — HAE отдаёт посекундную развёртку, а не измерения (находка 34). Полная история и точные сэмплы лежат в zip родного экспорта. Это же основание для устаревания нижнего слоя и единственный способ поднять историю глубже недели: дыра старше недели проходами синхронизации не чинится. Формат разобран на девяти экспортах за 5.5 лет (находки 42–45), гадать не придётся: - **версии 11 → 13 → 14**, на 14 стоит больше года; за всё время **ни один тип записи не исчез**, только добавлялись. Значит незнакомый тип — новый тип, а не сломанный парсер: падать на нём нельзя; - **`Correlation`** — обёртка из двух записей, ею приезжает давление. Появилась только в 2026 году. Парсер по одним `` разберёт давление как две несвязанные метрики и потеряет их парность; - **`WorkoutStatistics`** внутри тренировки — с 2024 года; - **имя файла локализовано**: `экспорт.xml`, не `export.xml` — так во всех девяти архивах; - **DTD расходится с данными** (в v11 у `` на атрибут больше объявленного) — валидировать документ его же DTD нельзя; - объём: 1.6 ГБ XML и 3.6 млн записей в свежем экспорте — только потоковый разбор, документ целиком в память не влезет. Шаги: - потоковый разбор `экспорт.xml` в слой `sample`, включая `Correlation`; - `HeartRateVariabilityMetadataList` с `InstantaneousBeatsPerMinute` — это тот же `heartbeatSeries`, что в HAE (находка 39), 1.25 млн ударов; - маршруты GPX и ЭКГ отдельными файлами — их в XML нет; - заливка кусками по годам, идемпотентно: повторный импорт того же архива не должен ничего менять; - `export_cda.xml` игнорируем — это клинический формат тех же данных. Двигает строку «Завершения» цели: «Слой `sample` наполнен историей с 2019 года, повторный импорт того же экспорта ничего не меняет». ## Импорт выставляет пометку покрытия Импорт — единственный, кто знает, какой период каким слоем обеспечен, поэтому пометку ставит он, а не отдельный проход задним числом. Форма пометки решена в [lower-layer-expiry](lower-layer-expiry.md): **одна строка на диапазон** — `метрика + слой + период + «покрыто проверенным экспортом»`. Провенанс на каждую точку не заводим: вопрос диапазонный, а поле у точки стоило бы того же объёма, который устаревание нижнего слоя и приходит экономить. Два условия, оба из ограничителей той задачи: - пометка ставится **по проверенному** импорту, а не по факту запуска команды. Проверка та же, что уже названа в приёмке: непрерывность по дням и сходимость сумм с часовым слоем HAE на пересечении периодов. Не сошлось — пометки нет, и это не отказ импорта, а честный отказ от обещания; - пометка **ничего не удаляет**. Она только даёт устареванию нижнего слоя основание; само удаление включается отдельно и позже. **`stateOfMind` пометку не получает никогда** — его в экспорте Apple нет ни одним типом (находка 42), источник у него единственный, и устаревание к нему неприменимо. Это надо записать явно, а не оставить следовать из отсутствия данных. Готово, когда история за несколько лет лежит в слое `sample`, повторный импорт не меняет ничего, суммы по слою сходятся с часовым слоем HAE на пересечении периодов, а покрытые периоды помечены и видны без пересборки. Архивы: `/home/av/MediaEverything/HealthData/apple_health/` — девять штук, 2021-12 … 2026-08. Старые версии формата годятся как регрессионный набор.