Карточка списка на главной теперь даёт краткий обзор «от загрузки до
решения об удалении»: метка «ID:» перед идентификатором, дата добавления
(абсолютная + относительная, всегда), размер раздачи и рейтинг отдачи.
Спойлер контекста убран — контекст смотрят на /download/{id}.
Данные:
- рейтинг и общий размер — из живого снимка воркера (qbt total_size →
worker.Live.TotalSize); размер доступен для любой раздачи в снимке;
- размер-фолбэк, когда торрента нет в qBittorrent (orphaned) — сумма
размеров разложенных файлов: новая колонка file_link.size, layouter
пишет размер при линковке, ридер LayoutSizeByDownload суммирует по
странице одним запросом (дедуп по dst_path);
- дата — source_added_at → фолбэк created_at, показ в TZ сервера.
handleIndex читает снимок для всех карточек (map-lookup), рейтинг/размер
статичны на рендере (без поллинга). Миграция 0007, ER-схема обновлена.
Change download-card-lifecycle-overview влит в спеки и заархивирован.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.3 KiB
web-ui Specification (delta)
ADDED Requirements
Requirement: Обзор жизненного цикла в карточке списка
Карточка загрузки в списке SHALL показывать обзорную мета-строку для решения о
судьбе раздачи: метку ID: перед копируемым идентификатором загрузки, дату
добавления раздачи (всегда), размер раздачи и рейтинг отдачи. Контекст загрузки
MUST NOT показываться в карточке списка — он доступен на странице /download/{id}.
Дата добавления SHALL показываться всегда как абсолютная дата и относительная
давность (например «2026-06-30 · 5 дней назад»); источником SHALL быть время
добавления раздачи в источник (source_added_at, qBittorrent added_on) с
фолбэком на время создания загрузки (created_at), согласованным с порядком
списка.
Рейтинг отдачи SHALL браться из живого снимка телеметрии; если торрента нет в снимке (источник ушёл из qBittorrent), рейтинг SHALL отображаться прочерком «—».
Размер раздачи SHALL браться из живого снимка (общий размер торрента), а при отсутствии торрента в снимке — из суммарного размера разложенных файлов загрузки; если неизвестно ни то, ни другое — прочерк «—».
Scenario: Метка идентификатора
- WHEN рендерится карточка загрузки в списке
- THEN перед значением
download.idпоказана метка «ID:», а кнопка копирования копирует именноdownload.id
Scenario: Дата добавления показана всегда
- WHEN рендерится любая карточка списка
- THEN в ней показана дата добавления раздачи абсолютной датой и относительной давностью
- AND если
source_added_atнеизвестно, используетсяcreated_at
Scenario: Рейтинг из живого снимка
- WHEN торрент загрузки присутствует в живом снимке
- THEN в карточке показан его рейтинг отдачи
- AND если торрента в снимке нет, рейтинг показан прочерком «—»
Scenario: Размер с фолбэком на разложенные файлы
- WHEN торрент загрузки присутствует в живом снимке
- THEN размер раздачи в карточке берётся из общего размера торрента
- AND если торрента в снимке нет, но у загрузки есть разложенные файлы — размер берётся из суммарного размера этих файлов
Scenario: Контекст не в карточке
- WHEN у загрузки есть переданный контекст
- THEN он не показывается в карточке списка, но доступен на странице
/download/{id}
MODIFIED Requirements
Requirement: Клиентские взаимодействия без сборки
Веб-UI SHALL реализовывать клиентскую логику без шага сборки и без реактивных
фреймворков: копирование идентификатора загрузки (vanilla JS). Основной
копируемый идентификатор в карточке списка и в шапке страницы просмотра SHALL
быть download.id (ULID) — тот же ключ, что пишется в логи (download_id). Все
действия над загрузкой SHALL выполняться через формы/htmx (раундтрип на сервер),
без клиентского пересчёта доменного состояния.
Scenario: Копирование идентификатора загрузки
- WHEN пользователь нажимает кнопку копирования рядом с идентификатором
загрузки (
download.id) в карточке списка или шапке страницы просмотра - THEN значение
download.idкопируется в буфер обмена без перезагрузки страницы
Scenario: Действия только через раундтрип
- WHEN пользователь выполняет действие над загрузкой
- THEN оно исполняется формой/htmx-запросом на сервер, без клиентского пересчёта доменного состояния