web-ui: карточка и страница обновляются, пока задачу может двигать фон
- условие самообновления — доменный предикат store.State.IsObservable() вместо фазы catched; один поллер на поверхность, интервалы 5 с и 15 с - отказ тика отвечает 200 и самозавершающимся фрагментом с корневым id цели вместо 404/500, который htmx не свопит - заведён ADR-2026-08-10-observability-is-not-terminality, переписан раздел «Живой поллинг» в конвенции веб-UI
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
## Why
|
||||
|
||||
Загрузка докачалась, воркер увёл её в распознавание и дальше в ревью — а в
|
||||
списке она по-прежнему «Загружается», без кнопки «Ревью →». Верное состояние
|
||||
появляется только после того, как человек сам перезагрузит страницу.
|
||||
|
||||
Живое обновление сегодня привязано к двум отдельным фазам: карточка опрашивает
|
||||
себя, пока задача в `catched`, а прогресс — пока она в `downloading`. Выйдя из
|
||||
`downloading`, задача не опрашивается ничем, хотя сменить состояние ей предстоит
|
||||
ещё не раз (распознавание, ревью, раскладка) и часть этих смен идёт вообще без
|
||||
участия того, кто смотрит на список: их делает воркер или человек из Telegram.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Самообновление карточки списка привязывается к **нетерминальности** задачи, а
|
||||
не к фазе `catched`: карточка обновляется, пока задача жива, и перестаёт —
|
||||
когда та встала окончательно.
|
||||
- У карточки остаётся **один** источник обновления. Сейчас в `downloading` их
|
||||
было бы два (сама карточка и вложенный фрагмент прогресса), и они опрашивали
|
||||
бы одно и то же дважды, подменяя разметку друг друга. Живые цифры прогресса
|
||||
приходят вместе с карточкой.
|
||||
- Страница `/download/{id}` живёт по тому же правилу: самообновляется, пока
|
||||
задача нетерминальна.
|
||||
- Частота обновления перестаёт быть одинаковой: карточка с живыми цифрами
|
||||
(скорость, ETA) обновляется чаще, чем карточка, у которой меняется только
|
||||
состояние. Цена тика у второй поверхности выше — сборка страницы загрузки
|
||||
считает предпросмотр раскладки и ходит в файловую систему.
|
||||
- Секция «Раздача» на странице загрузки перестаёт опрашивать сервер сама — она
|
||||
лежит внутри области, которую страница обновляет целиком, и два опроса на одну
|
||||
поверхность мешали бы друг другу.
|
||||
- Тик самообновления, не сумевший прочитать задачу, перестаёт быть молчаливым:
|
||||
он объясняет положение дел и прекращает опрос вместо бесконечного стука в
|
||||
сервер.
|
||||
- **BREAKING** для внутреннего контракта фрагментов: фрагменты прогресса и
|
||||
раздачи перестают быть самостоятельными поллерами. Наружного API это не
|
||||
касается — `/api/**` не меняется.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
Новых нет.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `web-ui`: требование «Отображение промежуточного состояния catched»
|
||||
обобщается — самообновление интерфейса перестаёт быть свойством одной фазы и
|
||||
становится свойством живой задачи; условие остановки — терминальное
|
||||
состояние.
|
||||
- `live-status`: требование «Живой прогресс активных загрузок» — сценарий
|
||||
«Завершение останавливает поллинг» сегодня описывает наблюдаемый дефект как
|
||||
норму. Прекращаться должен показ живых цифр, а не обновление карточки.
|
||||
|
||||
## Impact
|
||||
|
||||
- `internal/httpapi`: `toView` и `buildDownloadView` (условие самообновления),
|
||||
обработчики фрагментов карточки и прогресса;
|
||||
- `web/templates/partials/card.html`, `progress.html`, `download_main.html`;
|
||||
- нагрузка: число фоновых запросов на открытую страницу меняется — считается в
|
||||
`design.md`;
|
||||
- вне scope: переход на SSE (задача `sse-live-updates`), любые изменения
|
||||
`/api/**` и состава живой телеметрии;
|
||||
- вне scope и названо сознательно: экран `/review/{id}` сохраняет фазовое
|
||||
самообновление, заказанное спекой `review` («пока загрузка в `recognizing`»).
|
||||
Третья поверхность приводится к общему правилу отдельной задачей — иначе
|
||||
change тянет за собой ещё одну capability.
|
||||
Reference in New Issue
Block a user