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

6.5 KiB
Raw Blame History

🐞 Обновлять карточку списка после завершения загрузки

  • Тип: 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» заказывает самообновление только для перехода catcheddownloading. Поэтому починка несёт дельту спеки, а не только правку кода.

Воспроизведение

  1. Открыть главную /, добавить раздачу, дождаться состояния downloading.
  2. Страницу не перезагружать. Дождаться, пока qBittorrent доведёт раздачу до 100% и воркер уведёт задачу из downloadingrecognizing, дальше в 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.goSelfPoll истинен для нетерминальных состояний и ложен для терминальных).
  • Правило записано в дельта-спеках обеих затронутых capability (оракул: openspec validate --strict и шаг канона в task gate).

Рамки

Чинится поллингом фрагментов: переход на SSE — отдельная задача sse-live-updates, и эта починка её не делает и не отменяет. Расширение самополлинга на все нетерминальные состояния добавляет фоновых запросов к БД — частота и её потолок решаются в предложении, а не молча.