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

65 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 1. Телеметрия в клиенте qBittorrent
- [x] 1.1 Добавить в `qbt.Torrent` поля `Dlspeed`, `Eta`, `Ratio`, `NumSeeds`,
`NumLeechs`, `Uploaded`, `Upspeed` с json-тегами из `/torrents/info`
(`dlspeed`, `eta`, `ratio`, `num_seeds`, `num_leechs`, `uploaded`, `upspeed`)
- [x] 1.2 Обновить комментарий-доку `Torrent` (подмножество полей расширено)
## 2. Снимок телеметрии в воркере
- [x] 2.1 Добавить тип `worker.Live{Progress, DlSpeed, ETA, State, Seeding,
Ratio, Seeds, Peers, Uploaded, UpSpeed}` (курированный, без зависимости на
qbt у читателей); `Seeding` вычислять через `classify(state) == classReady`
- [x] 2.2 Добавить в `Worker` поле снимка `live map[string]Live` + отдельный
`sync.RWMutex` (не `w.mu`); инициализация в `New`
- [x] 2.3 В `Poll` собрать новую карту из полученного `torrents` — **три ключа
на торрент** (lowercase `Hash`/`InfohashV1`/`InfohashV2`, как `byHash`) — и
атомарно подменить снимок **сразу после построения `byHash`, до store-
операций** (телеметрия обновляется даже при последующем сбое reconcile)
- [x] 2.4 Реализовать `Live(infohash string) (Live, bool)` — чтение под RLock,
`ok=false` при пустом/неизвестном infohash
- [x] 2.5 Тесты: снимок обновляется после `Poll`; `Live` отдаёт данные
качающейся и сидирующей задачи (с верным `Seeding`); поиск по любому из трёх
хэшей; неизвестный/пустой infohash → `ok=false`
## 3. Транспорт: контракт и фрагмент-роуты
- [x] 3.1 Объявить интерфейс `LiveStatus` в `internal/httpapi` и добавить поле
`Live LiveStatus` в `Deps`
- [x] 3.2 Прокинуть `Live: wrk` в `httpapi.Deps` в `cmd/jellybit/serve.go`
- [x] 3.3 Добавить роуты `GET /fragments/downloads/{id}/progress` и
`GET /fragments/downloads/{id}/seeding` в `NewRouter`
- [x] 3.4 Реализовать обработчики фрагментов: `GetDownload` → infohash/состояние
+ `Live(infohash)`; рендер партиала; `ok=false` → деградация без живых значений
- [x] 3.5 **Начальный рендер со значениями:** расширить `downloadView` и
`downloadDetailView` полями телеметрии; в `handleIndex`/`handleDownload`
вызвать `Live(infohash)` для нужных задач и положить во view — одна модель для
страницы и для фрагмент-роута (без мигания при первой загрузке)
- [x] 3.6 Добавить хелперы форматирования скорости/размера/ETA: человекочитаемые
единицы (байты→КиБ/МиБ, скорость/с), sentinel'ы qBittorrent (`eta=8640000`→
«—»/«∞», `ratio<0`→«—»); зафиксировать выбор `num_seeds`/`num_leechs`
## 4. Шаблоны и живое обновление
- [x] 4.1 Партиал `partials/progress.html` (прогресс-бар + скорость + ETA);
включить его в карточку `index.html` для активных загрузок
- [x] 4.2 Навесить на прогресс-блок активной карточки `hx-get` /
`hx-trigger="every 3s"` / `hx-swap="outerHTML"`; при выходе из downloading
фрагмент не содержит атрибутов поллинга (поллинг прекращается)
- [x] 4.3 Партиал `partials/seeding.html` (рейтинг, сиды/пиры, отдано, скорость
отдачи); секция «Раздача» в `download.html` для сидирующих задач, с
htmx-поллингом и деградацией при отсутствии данных
- [x] 4.4 Проверить, что фоновое обновление не сбрасывает фильтр/поиск/прокрутку
на главной (поллинг точечный, на уровне карточки)
- [x] 4.5 При необходимости — стили прогресс-бара/раздачи в `jellybit.css`
(использовать существующие токены, без инлайн-хардкода цветов)
## 5. Проверки и ревью
- [x] 5.1 `task test` (включая новые тесты воркера и httpapi-рендера фрагментов;
в т.ч. тест «фрагмент при выходе из downloading отдаётся без htmx-атрибутов
поллинга»)
- [x] 5.2 `task lint`, `gofmt`, `openspec validate --strict`
- [x] 5.3 Ревью кода (второй чекпоинт) перед archive: соответствие спекам и
конвенциям (логирование без секретов, ошибки `%w`, отдельный RWMutex)