- `GET /api/v1/metrics/{name}?from&to&layer` — ряд точек за период; конверт
объявляет слой, измеренный род, его применимость к отданному ряду и границу
окна измерения, а сам ряд собирается из одного слоя, выбранного по охвату
точек внутри периода
- use-case вынесен в `internal/points`, чтение — одним входом `store.ReadSeries`
под одной транзакцией; правило выбора слоя остаётся в домене и приходит в
хранилище колбэком
- `writeJSON` перестал экранировать HTML-символы и перестал глушить отказ
записи: дословность содержимого точки иначе не удерживается, а оборванное
тело уходило под видом успешного `200`
- род метрики выводится сверкой минутного слоя с часовым: часовое значение
сходится с суммой минутных — накопительная, со средним — мгновенная, иначе
`unknown` и свёртка не предлагается вовсе. На живом архиве (123 доставки,
31 метрика) 7 накопительных, 9 мгновенных, противоречащих часов ноль
- `GET /api/v1/metrics` под токеном чтения отдаёт единицы, слои с границами и
род вместе с основанием измерения; род нигде не хранится — он функция витрины,
а витрина функция журнала, устаревать в нём нечему
- миграция 00009: покрывающий индекс, чтобы каталог отвечал по учётным колонкам,
не разжимая содержимое объектов
- Очередью служит сама таблица: доставка ждёт свёртки в статусе `pending`,
канал несёт только бит «есть работа». Переполнять нечего, падение процесса
очередь не теряет, а подбор `pending` при старте — обычный проход воркера, а
не отдельный код. Классификация исхода общая с пересборкой журнала.
- Исход разбора начал отражать доставку, а не обстоятельства: отмена и
занятость базы статус не меняют (иначе конкуренция за базу выводила бы
доставку из очереди навсегда), паника свёртки больше не валит процесс, а
учёт доставки идёт через транзакцию с повторами.
- Длинный бюджет ответа выдан маршруту приёма, а не всему серверу:
`write_timeout` в Go покрывает и чтение тела, и общий подъём снял бы защиту с
остальных маршрутов.
Триаж свёл 62 сырые находки девяти проходов к 33 причинам: 3 блокера,
4 «сейчас», 2 развилки. Все закрыты регрессионными тестами.
- схема точки сна определяется по самой точке, а не по индексу в исходном
массиве: одна пропущенная точка меняла эпизод и сводку местами
- доставка сворачивается одной транзакцией: частичное состояние было
недетерминированным (восемь прогонов — семь состояний)
- граница размера на распакованном теле: 400 КиБ gzip разворачивались в
400 МиБ мимо max_body_mb
- столкновение — расхождение канонических форм, а не байтов; WARN с
координатами объекта; payload без HTML-экранирования
- выравнивание по местной метке: получасовые зоны уводили часовую выгрузку
в minute
- доставка из одних суточных сводок больше не отвергается целиком
- единицы не переписываются молча; счётчик считает сохранённые точки
- все выходы Fold логируются, исход пишется на переживающем отмену контексте
Четыре развилки вынесены блокерами в беклог.
- POST /api/v1/ingest: токен, лимит тела, gzip, durable-запись тела в сырой
архив, учёт доставки в SQLite
- код ответа отражает доставку, а не разбор: битый JSON — 400, непонятое
содержимое — 200, данные уже сохранены и доразберутся позже
- сохраняется полный набор заголовков запроса с вычисткой секретов по имени
и по совпадению значения с токеном