Files
avandClaude Opus 4.8 bb245a90a3 Веб-UI: обзор жизненного цикла в карточке загрузки
Карточка списка на главной теперь даёт краткий обзор «от загрузки до
решения об удалении»: метка «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>
2026-07-04 10:34:45 +03:00

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-запросом на сервер, без клиентского пересчёта доменного состояния