В карточке списка и шапке /download/{id} показываем и копируем download.id
(ULID) — тот же ключ, что в логах (download_id), удобно грепать. Infohash
остаётся в блоке «Информация о торренте». Поиск по списку расширен: матчит
любой идентификатор (download.id ИЛИ infohash), плюс название/контекст.
Удалены осиротевшие поля Infohash/InfohashShort и хелпер shortenHash.
Дельта web-ui влита в спеки, change заархивирован.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
67 lines
4.9 KiB
Markdown
67 lines
4.9 KiB
Markdown
## MODIFIED Requirements
|
|
|
|
### Requirement: Страницы веб-UI
|
|
|
|
Веб-UI SHALL предоставлять страницы: список загрузок с единым окном
|
|
добавления, **серверными фильтром по группе состояний, поиском и постраничной
|
|
выдачей (пагинацией)** (`/`), экран ревью одной загрузки (`/review/{id}`)
|
|
и страницу просмотра одной загрузки (`/download/{id}`) с распознаванием,
|
|
файлами→раскладкой, историей, блоком информации о торренте и — для сидирующих
|
|
задач — секцией живой статистики раздачи. Карточки активных (downloading)
|
|
загрузок в списке SHALL содержать индикатор прогресса. Фильтр, поиск и номер
|
|
страницы SHALL передаваться GET-параметрами запроса (например `f`, `q`, `page`)
|
|
и SHALL работать без клиентского JavaScript. Состояние `deleted` SHALL быть
|
|
скрыто в списке по умолчанию (с переключателем «показать всё»). Механика живого
|
|
обновления прогресса и наполнение секции раздачи определяются capability
|
|
`live-status`.
|
|
|
|
#### Scenario: Просмотр одной загрузки
|
|
|
|
- **WHEN** клиент открывает `GET /download/{id}` существующей загрузки
|
|
- **THEN** отрисовывается страница с её распознаванием, файлами, раскладкой и
|
|
историей
|
|
|
|
#### Scenario: Прогресс активной загрузки в списке
|
|
|
|
- **WHEN** в списке есть загрузка в состоянии `downloading`
|
|
- **THEN** её карточка содержит индикатор прогресса (прогресс-бар со скоростью
|
|
и ETA)
|
|
|
|
#### Scenario: Удалённые скрыты по умолчанию
|
|
|
|
- **WHEN** в списке есть загрузки в состоянии `deleted` и фильтр «показать
|
|
всё» не включён
|
|
- **THEN** они не отображаются, но доступны при включённом переключателе
|
|
|
|
#### Scenario: Пагинация списка
|
|
|
|
- **WHEN** загрузок под текущим фильтром больше, чем помещается на одну
|
|
страницу, и клиент запрашивает `GET /?page=N`
|
|
- **THEN** возвращается N-я страница результатов и элементы навигации по
|
|
страницам, сохраняющие текущие фильтр и поисковый запрос
|
|
|
|
#### Scenario: Серверный фильтр и поиск
|
|
|
|
- **WHEN** клиент запрашивает список с параметрами фильтра по состоянию и/или
|
|
строкой поиска (`GET /?f=review&q=дюна`)
|
|
- **THEN** сервер возвращает только подходящие загрузки (по группе состояний и
|
|
совпадению строки в названии, любом идентификаторе загрузки — `download.id`
|
|
ИЛИ infohash — и контексте), отфильтрованные на стороне БД, а не на клиенте
|
|
|
|
### Requirement: Клиентские взаимодействия без сборки
|
|
|
|
Веб-UI SHALL реализовывать клиентскую логику без шага сборки и без реактивных
|
|
фреймворков: копирование идентификатора загрузки (vanilla JS) и раскрытие
|
|
контекста нативным `<details>`. Основной копируемый идентификатор в карточке
|
|
списка и в шапке страницы просмотра SHALL быть `download.id` (ULID) — тот же
|
|
ключ, что пишется в логи (`download_id`). Все действия над загрузкой SHALL
|
|
выполняться через формы/htmx (раундтрип на сервер), без клиентского пересчёта
|
|
доменного состояния.
|
|
|
|
#### Scenario: Копирование идентификатора загрузки
|
|
|
|
- **WHEN** пользователь нажимает кнопку копирования рядом с идентификатором
|
|
загрузки (`download.id`) в карточке списка или шапке страницы просмотра
|
|
- **THEN** значение `download.id` копируется в буфер обмена без перезагрузки
|
|
страницы
|