- Очередью служит сама таблица: доставка ждёт свёртки в статусе `pending`, канал несёт только бит «есть работа». Переполнять нечего, падение процесса очередь не теряет, а подбор `pending` при старте — обычный проход воркера, а не отдельный код. Классификация исхода общая с пересборкой журнала. - Исход разбора начал отражать доставку, а не обстоятельства: отмена и занятость базы статус не меняют (иначе конкуренция за базу выводила бы доставку из очереди навсегда), паника свёртки больше не валит процесс, а учёт доставки идёт через транзакцию с повторами. - Длинный бюджет ответа выдан маршруту приёма, а не всему серверу: `write_timeout` в Go покрывает и чтение тела, и общий подъём снял бы защиту с остальных маршрутов.
62 lines
4.5 KiB
Markdown
62 lines
4.5 KiB
Markdown
# План
|
||
|
||
Это **порядок и его обоснование**, а не список работ. Единицы работы живут в
|
||
[беклоге](backlog/README.md) — одна задача, один файл, свой приоритет. План
|
||
отвечает «почему в таком порядке», беклог — «что брать следующим».
|
||
|
||
Отсюда правило: **содержимое шага здесь не перечисляется.** Шаг — это название
|
||
и статус; что именно в нём делается, знает задача. Иначе список работ живёт в
|
||
двух местах и расходится с каждой закрытой задачей. Меняется этот файл, когда
|
||
меняется порядок, а не когда закрывается задача.
|
||
|
||
## Ближайшая цель
|
||
|
||
Метрики разбираются и ложатся в часовые объекты: тела перестали быть
|
||
недифференцированной кучей. Приём отвечает `200`, не дожидаясь свёртки: её ведёт
|
||
фоновый воркер, для которого очередью служит сама таблица доставок.
|
||
|
||
**`reindex` сделан**: журнал проигрывается в свежую витрину, отпечатки
|
||
сравниваются, повторный прогон ничего не меняет. Доставки, числящиеся `pending`
|
||
после миграции 00005, подбираются им же — но применяется результат подменой
|
||
базы, а её делает человек при остановленном сервисе. Тем же кодом закрывается
|
||
половина задачи «разнести ответ и свёртку»: проигрывание журнала теперь готовая
|
||
операция.
|
||
|
||
Дальше — остаток разбора: тренировки и записи со своими `id` (это половина
|
||
потока: `workouts` и `stateOfMind` принимаются и хранятся, но не разбираются),
|
||
словарь категориальных значений.
|
||
|
||
Разведка закончена: правило вывода слоя, модель идентичности и формы точки
|
||
проверены на живом потоке, выводы — в [local-research.md](local-research.md).
|
||
|
||
## Шаги
|
||
|
||
- [x] **1. Каркас.**
|
||
- [x] **2. Приём без разбора.** ← **подключаем телефон по локальной сети**
|
||
- [~] **3. Разбор и хранилище.** Метрики и `reindex` — сделано; тренировки и
|
||
записи со своими `id`, словарь категориальных значений — нет.
|
||
- [ ] **4. Каталог и род агрегации.**
|
||
- [ ] **5. Read API.**
|
||
- [ ] **6. Самоописание.**
|
||
- [ ] **7. MCP.**
|
||
- [ ] **8. `healthlog import`.**
|
||
- [ ] **9. Устаревание нижнего слоя.**
|
||
- [ ] **10. Наблюдаемость.**
|
||
- [ ] **11. Деплой.**
|
||
|
||
Порядок неслучаен, и это единственное, чего нет в беклоге:
|
||
|
||
- **Каталог и род агрегации — перед Read API.** Без измеренного рода свёртка в
|
||
ответе неотличима от угадывания, а ошибиться здесь дорого: просуммировать
|
||
нижний слой значит завысить втрое.
|
||
- **`healthlog import` — перед устареванием нижнего слоя.** Пока импорт
|
||
экспорта не написан, помечать что-либо устаревшим не на основании чего.
|
||
- **Read API — перед MCP.** Адаптер собственной логики не несёт, он переводит
|
||
вызовы в те же обработчики; переводить пока нечего.
|
||
|
||
## Отложенное
|
||
|
||
Отложенных идей в плане нет: их место — [беклог](backlog/README.md) с пометкой
|
||
`[idea]`. Два дома для одной идеи расходятся, и тогда полного списка не даёт ни
|
||
один; вопрос «что мы решили отложить» задаётся беклогу.
|