Живые обновления прогресса и раздел «Раздача» (live-status)

Воркер ведёт in-memory снимок телеметрии раздач (прогресс, скорость, ETA,
рейтинг, сиды/пиры, отдано) под отдельным RWMutex, обновляя его на каждом
тике поллинга сразу после построения byHash — без лишних вызовов qBittorrent
и без хранения в БД (волатильно). qbt.Torrent дополнен полями телеметрии.

Веб-UI читает снимок через узкий контракт LiveStatus: карточки активных
загрузок показывают живой прогресс-бар (htmx-поллинг фрагмента every 3s,
точечно — без сброса фильтров), на странице загрузки появилась секция
«Раздача» для сидирующих задач. Начальный кадр рендерится сразу со
значениями; при отсутствии данных UI деградирует штатно.

Капабилити live-status (OpenSpec), web-ui дополнен. Change заархивирован.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
av
2026-06-30 20:38:25 +03:00
co-authored by Claude Opus 4.8
parent b646381cf9
commit ef75a0d302
22 changed files with 1094 additions and 14 deletions
@@ -0,0 +1,57 @@
## Why
Сейчас прогресс скачивания в веб-UI виден только при ручной перезагрузке
страницы, а статистики раздачи (рейтинг, сиды/пиры, отдано) нет вовсе — в
фазе 1 секцию намеренно отложили до появления живых данных. Воркер уже
опрашивает qBittorrent каждые несколько секунд и держит свежее состояние
каждой задачи — нужно лишь сохранить эту телеметрию в памяти и показать её в
UI без перезагрузки. Это «однооконный» сервис: смотреть, как идёт загрузка,
должно быть видно вживую.
## What Changes
- Воркер на каждом тике поллинга сохраняет **in-memory снимок** телеметрии
всех известных раздач (прогресс, скорость загрузки, ETA + для раздачи:
рейтинг, число сидов/пиров, отдано, скорость отдачи). Снимок волатильный,
в БД не пишется.
- `qbt.Torrent` дополняется полями телеметрии (`dlspeed`, `eta`, `ratio`,
`num_seeds`, `num_leechs`, `uploaded`, `upspeed`) из `/torrents/info`
лишний сетевой вызов не добавляется, они приходят в том же ответе.
- `httpapi` получает новую зависимость-источник телеметрии и **фрагмент-роут**;
активные карточки на главной поллят свой прогресс через htmx и обновляют
прогресс-бар/скорость/ETA на месте, без перезагрузки страницы и без сброса
клиентских фильтров.
- На странице загрузки `/download/{id}` появляется секция **«Раздача»** с
живой статистикой (рейтинг, сиды/пиры, отдано, скорость отдачи) для задач,
чей торрент сидирует.
- htmx, который уже вендорится и грузится, впервые задействуется (`hx-*`).
## Capabilities
### New Capabilities
- `live-status`: живая телеметрия загрузок и раздач — воркер как единственный
сэмплер qBittorrent ведёт in-memory снимок прогресса/скорости/ETA и
статистики раздачи; веб-UI отображает её в реальном времени (поллинг
фрагментов) без перезагрузки страницы и без хранения в БД.
### Modified Capabilities
- `web-ui`: страница загрузки `/download/{id}` получает секцию живой
статистики раздачи (в фазе 1 явно вынесена из scope «вводится вместе с
живыми обновлениями»); карточки активных загрузок на главной показывают
живой прогресс-бар через htmx-поллинг.
## Impact
- **Код:** `internal/qbt` (поля `Torrent`), `internal/worker` (снимок +
геттер телеметрии под отдельным RWMutex), `internal/httpapi` (dep-интерфейс
`LiveStatus`, фрагмент-роут, секция раздачи, прогресс во view), `cmd/jellybit`
(инъекция снимка в `httpapi.Deps`), `web/templates` (прогресс-бар на
карточках + htmx-атрибуты, секция «Раздача»), `web/static/css` при
необходимости (стили прогресс-бара уже есть в дизайн-системе).
- **БД:** изменений нет — телеметрия волатильна, миграций/ER не требуется.
- **Внешние вызовы:** дополнительных нет (расширяется только разбор
существующего ответа `/torrents/info`).
- **Безопасность:** телеметрия не содержит секретов; контракт чтения снимка
изолируется так, чтобы будущий апгрейд доставки до SSE не ломал API.