web-ui: добавлена страница группового удаления загрузок
- выбор → поимённое подтверждение → отчёт: пачка до 20 загрузок, гарды входа на обеих границах, потолок времени и остановка после трёх подряд отказов внешнего сервиса - допуск полного удаления сведён в единую точку store.State.CanDelete() — worker, страница загрузки и Telegram больше не держат своих перечней
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
## 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` — внешний сервис,
|
||||
необратимая операция; число вызовов за один запрос человека растёт с одного
|
||||
до числа выбранных.
|
||||
Reference in New Issue
Block a user