Files
jellybit/openspec/changes/archive/2026-06-30-live-status/tasks.md
T
avandClaude Opus 4.8 ef75a0d302 Живые обновления прогресса и раздел «Раздача» (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>
2026-06-30 20:38:25 +03:00

5.2 KiB
Raw Blame History

1. Телеметрия в клиенте qBittorrent

  • 1.1 Добавить в qbt.Torrent поля Dlspeed, Eta, Ratio, NumSeeds, NumLeechs, Uploaded, Upspeed с json-тегами из /torrents/info (dlspeed, eta, ratio, num_seeds, num_leechs, uploaded, upspeed)
  • 1.2 Обновить комментарий-доку Torrent (подмножество полей расширено)

2. Снимок телеметрии в воркере

  • 2.1 Добавить тип worker.Live{Progress, DlSpeed, ETA, State, Seeding, Ratio, Seeds, Peers, Uploaded, UpSpeed} (курированный, без зависимости на qbt у читателей); Seeding вычислять через classify(state) == classReady
  • 2.2 Добавить в Worker поле снимка live map[string]Live + отдельный sync.RWMutex (не w.mu); инициализация в New
  • 2.3 В Poll собрать новую карту из полученного torrentsтри ключа на торрент (lowercase Hash/InfohashV1/InfohashV2, как byHash) — и атомарно подменить снимок сразу после построения byHash, до store- операций (телеметрия обновляется даже при последующем сбое reconcile)
  • 2.4 Реализовать Live(infohash string) (Live, bool) — чтение под RLock, ok=false при пустом/неизвестном infohash
  • 2.5 Тесты: снимок обновляется после Poll; Live отдаёт данные качающейся и сидирующей задачи (с верным Seeding); поиск по любому из трёх хэшей; неизвестный/пустой infohash → ok=false

3. Транспорт: контракт и фрагмент-роуты

  • 3.1 Объявить интерфейс LiveStatus в internal/httpapi и добавить поле Live LiveStatus в Deps
  • 3.2 Прокинуть Live: wrk в httpapi.Deps в cmd/jellybit/serve.go
  • 3.3 Добавить роуты GET /fragments/downloads/{id}/progress и GET /fragments/downloads/{id}/seeding в NewRouter
  • 3.4 Реализовать обработчики фрагментов: GetDownload → infohash/состояние
    • Live(infohash); рендер партиала; ok=false → деградация без живых значений
  • 3.5 Начальный рендер со значениями: расширить downloadView и downloadDetailView полями телеметрии; в handleIndex/handleDownload вызвать Live(infohash) для нужных задач и положить во view — одна модель для страницы и для фрагмент-роута (без мигания при первой загрузке)
  • 3.6 Добавить хелперы форматирования скорости/размера/ETA: человекочитаемые единицы (байты→КиБ/МиБ, скорость/с), sentinel'ы qBittorrent (eta=8640000→ «—»/«∞», ratio<0→«—»); зафиксировать выбор num_seeds/num_leechs

4. Шаблоны и живое обновление

  • 4.1 Партиал partials/progress.html (прогресс-бар + скорость + ETA); включить его в карточку index.html для активных загрузок
  • 4.2 Навесить на прогресс-блок активной карточки hx-get / hx-trigger="every 3s" / hx-swap="outerHTML"; при выходе из downloading фрагмент не содержит атрибутов поллинга (поллинг прекращается)
  • 4.3 Партиал partials/seeding.html (рейтинг, сиды/пиры, отдано, скорость отдачи); секция «Раздача» в download.html для сидирующих задач, с htmx-поллингом и деградацией при отсутствии данных
  • 4.4 Проверить, что фоновое обновление не сбрасывает фильтр/поиск/прокрутку на главной (поллинг точечный, на уровне карточки)
  • 4.5 При необходимости — стили прогресс-бара/раздачи в jellybit.css (использовать существующие токены, без инлайн-хардкода цветов)

5. Проверки и ревью

  • 5.1 task test (включая новые тесты воркера и httpapi-рендера фрагментов; в т.ч. тест «фрагмент при выходе из downloading отдаётся без htmx-атрибутов поллинга»)
  • 5.2 task lint, gofmt, openspec validate --strict
  • 5.3 Ревью кода (второй чекпоинт) перед archive: соответствие спекам и конвенциям (логирование без секретов, ошибки %w, отдельный RWMutex)