Files
jellybit/tasks/items/card-stale-after-download-finish.md
T
av 969926fae3 tasks: заведены баг устаревшей карточки и цель группового удаления
- fix card-stale-after-download-finish: карточка списка не обновляется после выхода задачи из downloading
- goal bulk-download-management + feature bulk-delete-page: удаление раздач с файлами пачкой на отдельной странице
2026-08-10 12:32:17 +03:00

78 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🐞 Обновлять карточку списка после завершения загрузки
- **Тип:** 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`, и эта починка её не делает и не отменяет. Расширение
самополлинга на все нетерминальные состояния добавляет фоновых запросов к БД —
частота и её потолок решаются в предложении, а не молча.