Files
jellybit/openspec/changes/archive/2026-08-10-bulk-delete-page/proposal.md
T
av 288be8ec34 web-ui: добавлена страница группового удаления загрузок
- выбор → поимённое подтверждение → отчёт: пачка до 20 загрузок, гарды входа
  на обеих границах, потолок времени и остановка после трёх подряд отказов
  внешнего сервиса
- допуск полного удаления сведён в единую точку store.State.CanDelete() —
  worker, страница загрузки и Telegram больше не держат своих перечней
2026-08-10 17:43:36 +03:00

4.8 KiB
Raw Blame History

Why

Удалить раздачу вместе с файлами сегодня можно только со страницы одной загрузки, из её danger-секции. Чтобы освободить место после десяти закрытых раздач, человек десять раз проходит путь «список → карточка → подтверждение». Работа механическая, а цена ошибки высокая: на каждом проходе он подтверждает необратимое действие заново и легко теряет, какие раздачи уже снёс.

What Changes

  • Появляется отдельная страница веб-UI «Удаление», доступная из шапки. На ней перечислены только те загрузки, для которых удаление с файлами разрешено поштучно (done, orphaned, target_missing), у каждой строки — чекбокс.
  • Одна кнопка «Удалить выбранные» ведёт на страницу подтверждения, где выбранные раздачи названы поимённо. Удаление уходит только оттуда: POST без признака подтверждения отклоняется, ни одного удаления не делает.
  • Результат показывается поимённо: что удалено и что отказало, с причиной каждого отказа. Отказ на одной загрузке не отменяет остальных.
  • Групповой путь прав не расширяет: каждая выбранная загрузка проходит ту же проверку состояния, что и поштучное удаление, и отклоняется тем же конфликтом.
  • Условие «удаление разрешено» переезжает в единую точку домена (store.State): сейчас оно записано дважды — в проверке воркера и в сборке представления страницы загрузки, — а групповая страница была бы третьим местом.
  • Страница намеренно не самообновляется: живая перерисовка карточек стёрла бы выбор человека. Это и есть причина, по которой режим выбора не вешается на основной список.

Не входит: групповое закрытие без файлов (Dismiss), автоматическая чистка по сроку хранения, изменение самой операции удаления одной загрузки.

Capabilities

New Capabilities

Новых нет: групповое удаление — это новая поверхность существующего поведения, а не новое поведение системы.

Modified Capabilities

  • web-ui: добавляется страница группового удаления с обязательным поимённым подтверждением и поимённым отчётом об исходе; ссылка на неё в шапке.
  • state-reconciliation: требование «Полное удаление загрузки пользователем» уточняется — подтверждение может быть одно на пачку, но остаётся обязательным и поимённым, а условия допустимости у каждой загрузки прежние и проверяются для каждой отдельно.

Impact

  • internal/httpapi: страница выбора, страница подтверждения, обработчик группового удаления и страница результата; ссылка в шапке.
  • web/templates: новый шаблон страницы и её партиалы, partials/header.html.
  • internal/store: единая точка «в этом состоянии удаление разрешено».
  • internal/worker: Reviewer.Delete зовётся по каждой выбранной загрузке; сама операция не меняется.
  • qBittorrent torrents/delete с deleteFiles=true — внешний сервис, необратимая операция; число вызовов за один запрос человека растёт с одного до числа выбранных.