Files
healthlog/docs/tasks/items/entity-without-parsed-label.md
T
av bd832337df tasks: задачи спринта раздроблены до восьми гранулярных
- конверт и точки разложены на форму провода, точки за период и условный
  запрос; свёртка — на сетку, порог неполного ведра и предел размера ответа;
  тренировки и записи разъехались на два независимых маршрута
- openapi-swagger разложена на спеку, гейт против расхождения и Swagger UI —
  все три вне набора, вместе с mcp-server
- набор спринта 2026-08-04 — весь HTTP-слой чтения, восемь задач
2026-08-04 14:21:57 +03:00

45 lines
3.9 KiB
Markdown

# Сущность с id, но неразобранной меткой
- **Секция:** ядро
- **Зачем:** Тренировка с меткой в неизвестном формате пропадает целиком, а после включения ретеншена окно становится необратимым
- **Теги:** goal:parsing-completeness
**Решение принято владельцем 2026-08-03: вариант (1) — хранить с NULL-меткой.**
`start_utc`/`ts_utc` становятся NULLABLE, содержимое (включая маршрут) хранится,
метку восстановит пересборка, когда разбор научится читать формат. Вариант (3)
отвергнут при постановке: подстановка метки доставки — выдуманное измерение в
колонке, по которой идёт выборка.
**Берётся после [тренировок](read-api-workouts.md) и [записей](read-api-records.md) наружу.** Правило
чтения — что выборка «за период» делает со строками без метки — обязано
проектироваться вместе с читателем, иначе такие строки молча исчезнут из любого
ответа. Порядок тот же, что у [journal-order-on-ingest](journal-order-on-ingest.md)
после `/stats`: решение принято, момент взятия назван.
Остаток задачи «Дозакрыть находки ревью по слиянию сущностей» (архивный change
`dozakryt-nahodki-sushchnostej`). Та задача сделала мягким чтение заголовка:
поле не той формы стоит одного поля, а не сущности. Но метка исключение —
разбор кладёт сущность в `ts_utc`/`start_utc`, колонки `NOT NULL`, и сущность
с неразбираемой меткой по-прежнему пропускается целиком.
## Что известно
- Оракул: `internal/hae/entity_test.go`, случаи «метка в ином формате», «метка
Unix-эпохой», «метки нет вовсе» — сущность в результат разбора не попадает,
счётчик `SkippedEntityNoTime` растёт.
- После той задачи пропуск виден в базе: у доставки есть `skipped_entities`,
и ретеншен получает честный ответ «терять есть что». То есть событие больше
не молчит — но содержимое всё ещё не хранится.
- Достижимость из реального потока: замер на 118 доставках дал **ноль**
пропусков всех трёх классов. Дрейф формата дат у HAE при этом
задокументирован (`docs/research/apple-health.md`), то есть вход не выдуман.
## Чем платим за отсрочку
Вариант «не хранить» — то, чем живём сегодня: тело лежит в архиве, доставку
вернёт `reindex`. Отсрочка безопасна ровно до включения
[ретеншена](raw-archive-retention.md): после него окно становится необратимым.
Значит эти две задачи связаны порядком — ретеншен не включается раньше, чем
сущность без метки начнёт храниться, либо включается с явной записью о том,
что этот класс теряется.