- цель parsing-and-storage закрыта по своему критерию; незакрываемый остаток (новые формы от источника, ручные секции задним числом) переехал в тему parsing-completeness - цель mcp поглощена целью read-api, переименованной в «Чтение данных клиентами»: адаптер — последний шаг того же направления, а не своё - read-api-points разложена на конверт с точками, свёртку по сетке и тренировки с записями; спринт 2026-08-04 набран пятью задачами
4.4 KiB
Конверт ответа и точки за период
- Секция: ядро
- Зачем: Точки лежат в витрине и наружу не отдаются: ни один потребитель не может спросить «вес за год» иначе как sqlite3 на хосте
- Теги: goal:read-api
Потребитель получает значения метрики за период одним запросом
?from&to, и из ответа видно, что именно ему отдали: слой, род свёртки и
границу окна, в котором род измерен.
Первая из трёх частей, на которые разложена read-api-points. Здесь решается
конверт — форма, которую унаследуют все остальные маршруты чтения и оба
транспорта.
Форма провода решается здесь, один раз. Сегодня типы internal/catalog
сами несут json-теги, а транспорт владеет только обёрткой: переименование поля
в домене меняет публичный контракт без касания httpapi, и держит это один
байтовый тест непустого ответа. Либо объявить в architecture.md, что типы
чтения и есть форма провода для всех транспортов (HTTP и MCP отдают её байт в
байт), либо завести DTO в транспорте. Выбрать надо до того, как образец
скопируют соседние задачи.
Машинерия условного запроса готова — её берут, а не пишут заново.
store.VersionedRead держит правило «версией, снятой после чтения, не
подписывать»; httpapi умеет If-None-Match и 304. Новое здесь одно: метка
обязана нести область действия — у точек ответ есть функция параметров
запроса, поэтому etag(scope, version) требует их канонизированной формы, иначе
304 ответит на другой набор данных. Детали — docs/architecture.md,
«Условный запрос».
Клиент обязан видеть границы окна измерения. Род метрики измерен по 48 самым
свежим общим часам, а не по последним 48 часам календаря: выключенная
минутная автоматизация HAE останавливает пополнение множества общих часов, и
окно замирает, продолжая объявлять род. Единственный след — last_hour в
ответе; конверт обязан его нести.
Критерии приёмки
- «вес за год» отвечается одним запросом без доступа к файлу базы — оракул: запрос к поднятому сервису на живом архиве
- в ответе всегда видны
layer,aggregationиlast_hour— оракул: тест на форме ответа - повторный запрос с
If-None-Matchдаёт304, а тот же запрос с другими параметрами —200с другим телом — оракул: тест на паре запросов с разной областью действия метки - форма провода объявлена в
docs/architecture.md— доменные типы или DTO, — и соседние маршруты ссылаются на это решение, а не повторяют выбор — оракул: глазами по разделу
Рамки
Схема не трогается, данные только читаются, сервис перезапускается. Против
./data — только task up / task run.
Связано: docs/architecture.md → «Read API», «Условный запрос», «Измерение рода
агрегации».