пересмотрена архитектура под слои, свёртку в ответе и MCP

- агрегация появилась в ответе на запрос: род метрики измеряется сверкой
  слоёв, нижний слой HAE не суммируется никогда
- переведённые строки хранятся дословно с приписанным кодом HealthKit;
  снято правило «настройки данных у всех проходов одинаковы» — слой в ключе
- добавлены устаревание нижнего слоя по проверенному экспорту и MCP поверх
  read API; план вырос до 11 шагов
This commit is contained in:
av
2026-08-01 13:48:22 +03:00
parent 18d76d9610
commit 9d06509446
4 changed files with 363 additions and 95 deletions
+31 -15
View File
@@ -17,41 +17,57 @@ healthlog делает это один раз. Телефон шлёт данн
## Границы
Это **хранилище**, а не аналитика. healthlog принимает, дедуплицирует,
хранит и отдаёт. Он не считает агрегаты, не переименовывает поля Apple и не
интерпретирует значения — этим занимается тот, кто данные читает.
хранит и отдаёт. Он не переименовывает поля Apple и не интерпретирует
значения — этим занимается тот, кто данные читает.
Единственный источник — Health Auto Export (куплен, пожизненный премиум).
Другие источники не поддерживаем.
Одну уступку хранилище всё же делает: оно умеет свести метрику к запрошенной
сетке («шаги по дням»). Иначе каждый из клиентов повторял бы одну и ту же
логику выбора слоя, а ошибиться в ней легко — просуммировать не тот разрез и
получить завышение втрое. Но род свёртки не проставлен вручную, а **измерен**
сверкой слоёв между собой; где измерить не вышло, свёртка не предлагается
вовсе.
Источников два: Health Auto Export (куплен, пожизненный премиум) — ежедневный
поток, и родной экспорт Apple Health раз в 2–3 месяца — источник истины для
нижнего слоя.
## Как устроено
```
iPhone ──HTTPS POST──► healthlog ──► сырой архив (файлы, .json.gz)
iPhone ──HTTPS POST──► healthlog ──► сырой архив (.json.gz, 14 дней)
│ │
│ └── источник истины, не трогаем
│ └── страховка разбора, не склад
SQLite-витрина ──► HTTP read API ──► мои приложения
(пересобирается из архива)
SQLite ──┬──► HTTP read API ──► мои приложения
(точки по │
слоям) └──► MCP ───────────► агенты
экспорт Apple ──────────────┘ нижний слой, раз в 2–3 месяца
```
Приём сначала кладёт тело запроса на диск как есть и только потом разбирает.
Значит, ошибка в нашем разборе не может привести к потере данных: витрина
пересобирается из архива командой `healthlog reindex`.
Значит, ошибка в нашем разборе не может привести к потере данных: хранилище
пересобирается из архива командой `healthlog reindex`. Архив при этом
недолговечен — дальше истина в самих точках, и потому точки хранятся
дословно.
Подробности — [docs/architecture.md](docs/architecture.md).
## Состояние
В разработке. Готовы шаги 1–2 из 8: сервис принимает пакеты и складывает их в
сырой архив. Разбора, витрины и read API ещё нет — план в
В разработке. Готовы шаги 1–2 из 11: сервис принимает пакеты и складывает их в
сырой архив. Разбора, хранилища и read API ещё нет — план в
[docs/plan.md](docs/plan.md).
Разведка формата закончена: 41 находка на живом потоке, половина расходится с
документацией Health Auto Export — [docs/local-research.md](docs/local-research.md).
## Команды
```
healthlog serve приём + read API
healthlog import заливка файлов в архив и витрину (шаг 6)
healthlog reindex пересборка витрины из сырого архива (шаг 3)
healthlog serve приём + read API + MCP
healthlog import родной экспорт Apple Health (шаг 8)
healthlog reindex пересборка хранилища из архива (шаг 3)
healthlog healthcheck проверка живости для docker HEALTHCHECK
```