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

8.1 KiB

live-status Specification

Purpose

TBD - created by archiving change live-status. Update Purpose after archive.

Requirements

Requirement: Снимок живой телеметрии

Воркер — единственный сэмплер qBittorrent — SHALL на каждом тике поллинга обновлять in-memory снимок телеметрии всех известных раздач. Снимок MUST NOT персиститься в БД: он волатилен и переживает только до рестарта процесса.

Scenario: Обновление снимка на тике

  • WHEN воркер завершает успешный тик поллинга qBittorrent
  • THEN снимок телеметрии содержит актуальные данные по каждой раздаче, присутствующей в ответе qBittorrent

Scenario: Снимок волатилен

  • WHEN процесс только что перезапущен и первый тик поллинга ещё не прошёл
  • THEN снимок пуст, а UI отображает задачи без живых значений, не падая

Requirement: Состав телеметрии

Телеметрия одной раздачи SHALL включать прогресс (доля 0..1), скорость загрузки, ETA и общий размер раздачи (total size); а для сидирующих раздач дополнительно — рейтинг, число сидов и пиров, объём отданного и скорость отдачи. Общий размер SHALL быть доступен для любой раздачи, присутствующей в снимке (не только сидирующей). Значения SHALL извлекаться из ответа qBittorrent /torrents/info без дополнительного сетевого вызова.

Scenario: Телеметрия качающейся задачи

  • WHEN торрент задачи находится в состоянии загрузки
  • THEN в снимке для неё доступны прогресс, скорость загрузки и ETA

Scenario: Общий размер доступен для любой раздачи в снимке

  • WHEN торрент задачи присутствует в снимке в любом состоянии
  • THEN в телеметрии для неё доступен общий размер раздачи

Scenario: Телеметрия сидирующей задачи

  • WHEN торрент задачи завершён и раздаётся
  • THEN в снимке для неё доступны рейтинг, число сидов/пиров, объём отданного и скорость отдачи

Requirement: Чтение телеметрии транспортом

Сервис SHALL предоставлять чтение снимка телеметрии по задаче через изолированный контракт, не зависящий от способа доставки в браузер (поллинг сейчас, SSE в будущем). Если для задачи нет записи в снимке (соответствующий торрент отсутствовал в qBittorrent на последнем тике), чтение SHALL сообщать об отсутствии данных, а UI MUST деградировать без живых значений, не падая.

Scenario: Данные есть

  • WHEN транспорт читает телеметрию задачи, чей торрент был в последнем тике
  • THEN он получает живые значения этой задачи

Scenario: Данных нет

  • WHEN транспорт читает телеметрию задачи, торрента которой нет в qBittorrent
  • THEN он получает признак отсутствия данных и рендерит страницу без живых значений

Requirement: Свежесть не выше тика поллинга

Живые значения, видимые в браузере, SHALL быть не свежее последнего тика поллинга воркера; браузер MUST NOT опрашивать qBittorrent напрямую. Любой запрос UI за телеметрией SHALL обслуживаться из in-memory снимка, не порождая обращения к qBittorrent — поэтому частота обновления UI может быть выбрана свободно (в т.ч. чаще тика для плавности), не нагружая qBittorrent.

Scenario: Браузер не обгоняет воркер

  • WHEN браузер запрашивает фрагмент телеметрии чаще, чем длится тик поллинга
  • THEN он получает значения последнего тика, и обращения к qBittorrent при этом не происходит

Requirement: Живой прогресс активных загрузок

Веб-UI SHALL обновлять прогресс активных (downloading) загрузок на главной без перезагрузки страницы — поллингом фрагмента через htmx. Обновление MUST NOT сбрасывать клиентские фильтр, поиск и прокрутку. Когда задача покидает состояние downloading, поллинг её прогресса SHALL прекращаться.

Scenario: Прогресс растёт без перезагрузки

  • WHEN загрузка качается и пользователь смотрит на главную
  • THEN её прогресс-бар, скорость и ETA обновляются на месте без перезагрузки страницы

Scenario: Клиентское состояние сохраняется

  • WHEN применён фильтр или поиск и происходит фоновое обновление прогресса
  • THEN выбранный фильтр, текст поиска и позиция прокрутки не сбрасываются

Scenario: Завершение останавливает поллинг

  • WHEN загрузка переходит из downloading в другое состояние
  • THEN фоновый поллинг прогресса для этой карточки прекращается

Requirement: Секция раздачи на странице загрузки

Страница /download/{id} SHALL показывать секцию «Раздача» с живой статистикой (рейтинг, число сидов и пиров, объём отданного, скорость отдачи) для задач, чей торрент сидирует. Если живых данных по задаче нет, секция SHALL отсутствовать либо явно показывать «нет данных», не ломая остальную страницу.

Scenario: Сидирующая задача показывает раздачу

  • WHEN открыта страница задачи, торрент которой раздаётся
  • THEN в секции «Раздача» видны рейтинг, сиды/пиры, отдано и скорость отдачи

Scenario: Нет живых данных — секция деградирует

  • WHEN открыта страница задачи, торрента которой нет в qBittorrent
  • THEN секция «Раздача» отсутствует или показывает «нет данных», а распознавание, файлы и история отображаются нормально