- fix card-stale-after-download-finish: карточка списка не обновляется после выхода задачи из downloading - goal bulk-download-management + feature bulk-delete-page: удаление раздач с файлами пачкой на отдельной странице
78 lines
6.5 KiB
Markdown
78 lines
6.5 KiB
Markdown
# 🐞 Обновлять карточку списка после завершения загрузки
|
||
|
||
- **Тип:** fix
|
||
- **Категория:** Ядро продукта
|
||
- **Зачем:** завершённая загрузка висит в списке с бейджем «Загружается» до ручной перезагрузки: карточка самополлится только в catched, а прогресс перестаёт поллить, выйдя из downloading — обновлять карточку становится некому
|
||
|
||
Карточка списка показывает состояние, которого уже нет: качание кончилось,
|
||
задача ушла в распознавание и дальше в ревью, а на экране прежний бейдж и
|
||
прежний набор действий.
|
||
|
||
Причина видна в коде. Самополлинг карточки включает поле `SelfPoll`, а оно
|
||
истинно только в `catched` (`internal/httpapi/httpapi.go:664`,
|
||
`web/templates/partials/card.html:2`). Внутренний фрагмент прогресса поллится,
|
||
пока состояние `downloading` (`internal/httpapi/live.go:88`,
|
||
`web/templates/partials/progress.html:1`). Задача, покинувшая `downloading`, не
|
||
опрашивается уже ничем. На странице `/download/{id}` то же самое:
|
||
`web/templates/partials/download_main.html:2` самополлится только в `catched`
|
||
(`internal/httpapi/download.go:116`).
|
||
|
||
Спека нынешнее поведение не запрещает: `live-status` → «Живой прогресс активных
|
||
загрузок» прямо требует прекращать поллинг прогресса на выходе из
|
||
`downloading`, а `web-ui` → «Отображение промежуточного состояния catched»
|
||
заказывает самообновление только для перехода `catched` → `downloading`.
|
||
Поэтому починка несёт дельту спеки, а не только правку кода.
|
||
|
||
## Воспроизведение
|
||
|
||
1. Открыть главную `/`, добавить раздачу, дождаться состояния `downloading`.
|
||
2. Страницу не перезагружать. Дождаться, пока qBittorrent доведёт раздачу до
|
||
100% и воркер уведёт задачу из `downloading` (в `recognizing`, дальше в
|
||
`review` или `done`).
|
||
3. Наблюдается: бейдж карточки остаётся «Загружается», прогресс-бар замирает на
|
||
последнем значении, кнопка «Ревью →» не появляется. Фоновых запросов от этой
|
||
карточки в панели сети больше нет.
|
||
4. Ожидается: карточка сама показывает новое состояние — бейдж, набор действий,
|
||
исчезнувший прогресс.
|
||
5. Перезагрузить страницу руками: карточка сразу показывает верное состояние —
|
||
расходится отображение, а не данные.
|
||
|
||
## Затрагивает
|
||
|
||
- фрагменты `GET /fragments/downloads/{id}/card` и
|
||
`GET /fragments/downloads/{id}/progress` (`internal/httpapi/live.go`);
|
||
- поле `SelfPoll` вида карточки и вида страницы загрузки
|
||
(`internal/httpapi/httpapi.go`, `internal/httpapi/download.go`);
|
||
- шаблоны `web/templates/partials/card.html`, `progress.html`,
|
||
`download_main.html`;
|
||
- спека `web-ui`, требование «Отображение промежуточного состояния catched» —
|
||
условие самообновления перестаёт быть привязанным к одной фазе;
|
||
- спека `live-status`, требование «Живой прогресс активных загрузок» и его
|
||
сценарий «Завершение останавливает поллинг» — прекращение поллинга прогресса
|
||
перестаёт означать прекращение обновления карточки.
|
||
|
||
## Критерии приёмки
|
||
|
||
- Карточка нетерминальной загрузки самополлится, и первый ответ фрагмента после
|
||
смены состояния несёт новый бейдж (оракул: тест `internal/httpapi` — рендер
|
||
карточки в `downloading` содержит `hx-get` на `/fragments/downloads/{id}/card`,
|
||
а подставной читатель, сменивший состояние на `review`, отдаёт карточку с
|
||
бейджем ревью).
|
||
- Терминальная карточка себя не опрашивает: фоновых запросов после `done`,
|
||
`failed`, `cancelled` и `deleted` нет (оракул: тот же тест — в разметке такой
|
||
карточки нет ни `hx-get`, ни `hx-trigger`).
|
||
- Появившееся действие видно без перезагрузки: карточка задачи, перешедшей в
|
||
`review`, несёт кнопку «Ревью →» (оракул: тест фрагмента карточки).
|
||
- Страница `/download/{id}` обновляет бейдж и блок действий по тому же правилу,
|
||
что и карточка (оракул: тест `internal/httpapi/download.go` — `SelfPoll`
|
||
истинен для нетерминальных состояний и ложен для терминальных).
|
||
- Правило записано в дельта-спеках обеих затронутых capability (оракул:
|
||
`openspec validate --strict` и шаг канона в `task gate`).
|
||
|
||
## Рамки
|
||
|
||
Чинится поллингом фрагментов: переход на SSE — отдельная задача
|
||
`sse-live-updates`, и эта починка её не делает и не отменяет. Расширение
|
||
самополлинга на все нетерминальные состояния добавляет фоновых запросов к БД —
|
||
частота и её потолок решаются в предложении, а не молча.
|