From 9472bfdd839399eaa355ac75638b7c9c4c7a9e0a Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Sat, 11 Jul 2026 09:46:28 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=BF=D0=B5=D0=BA=D0=B8+=D0=B1=D0=B5?= =?UTF-8?q?=D0=BA=D0=BB=D0=BE=D0=B3:=20=D0=B7=D0=B0=D0=BA=D1=80=D1=8B?= =?UTF-8?q?=D1=82=D0=B8=D0=B5=20=D0=B1=D0=B0=D1=82=D1=87=D0=B0=20UI-=D0=B7?= =?UTF-8?q?=D0=B0=D0=B4=D0=B0=D1=87=20(favicon,=20cancelled,=20=D0=B7?= =?UTF-8?q?=D0=BD=D0=B0=D1=87=D0=BE=D0=BA=20=D1=82=D0=B8=D0=BF=D0=B0,=20el?= =?UTF-8?q?lipsis,=20oob-=D0=BF=D0=B0=D0=BD=D0=B5=D0=BB=D1=8C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Реализованное поведение перенесено в openspec/specs: - web-ui: cancelled скрыт по умолчанию наравне с deleted; значок типа в карточке; - review: панель действий обновляется oob-фрагментом при свопе источника. Пять закрытых задач удалены из docs/backlog + индекса. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/backlog/README.md | 5 --- docs/backlog/favicon.md | 5 --- docs/backlog/panel-review-vne-swap.md | 7 ----- docs/backlog/skryvat-otmenennye-v-spiske.md | 35 --------------------- docs/backlog/spisok-znachok-tipa.md | 25 --------------- docs/backlog/torrent-fayl-dlinnoe-imya.md | 30 ------------------ openspec/specs/review/spec.md | 8 ++++- openspec/specs/web-ui/spec.md | 20 ++++++++---- 8 files changed, 21 insertions(+), 114 deletions(-) delete mode 100644 docs/backlog/favicon.md delete mode 100644 docs/backlog/panel-review-vne-swap.md delete mode 100644 docs/backlog/skryvat-otmenennye-v-spiske.md delete mode 100644 docs/backlog/spisok-znachok-tipa.md delete mode 100644 docs/backlog/torrent-fayl-dlinnoe-imya.md diff --git a/docs/backlog/README.md b/docs/backlog/README.md index 5afc6a4..1cddb1d 100644 --- a/docs/backlog/README.md +++ b/docs/backlog/README.md @@ -40,12 +40,9 @@ Tududi (проект `jellybit`) больше **не** держит беклог ## Низкий -- [Значок типа (фильм/сериал) в списке загрузок](spisok-znachok-tipa.md) — показать 🎬/📺 в строке списка; media type сейчас не доходит до листинга (нужно протащить в запрос и card.html) - [Ревью уведомлений в Telegram (аудит текстов и формата)](telegram-revyu-uvedomleniy.md) — зонтичный проход по всем текстам бота: полнота карточек, единый язык, оформление; порождает под-задачи - [Download id в Telegram моноширинным (code) для tap-to-copy](telegram-download-id-code.md) — слать id как `code`; требует включить parse mode (HTML) в send() + escape всех текстов - [Кнопка «Обновить имя»: полный формат ярлыка (Название (режиссёр, год), сезон)](knopka-obnovit-imya-polnyj-format.md) — Перелив имени даёт усечённое «Title (Year)» вместо полного формата add-шага (режиссёр+сезон); нужный `render` уже есть -- [Скрывать отменённые (cancelled) в общем списке наравне с удалёнными](skryvat-otmenennye-v-spiske.md) — cancelled шумит в ленте; тумблер «показать удалённые» должен раскрывать и cancelled, и deleted -- [Панель действий ревью вне htmx-свопа блока источника](panel-review-vne-swap.md) — При выборе источника одним кликом обновляется только блок источника (#source-block)… - [Мгновенные обновления через SSE](sse-obnovleniya.md) — Живые обновления прогресса сейчас на htmx-поллинге (фаза 2 веб-UI) — просто и работает… - [Шум ERROR фоновых циклов при недоступной зависимости](oshibki-klassifikaciya-i-konvencii-logirovaniya.md) — Остаток задачи логирования: ext.* ERROR-шторм при недоступном qBittorrent + эскалация устойчивого сбоя тика _(ревью Fable)_ - [Версии/качество одного тайтла (репаки, апгрейд 1080p → 2160p)](versii-kachestvo-repaki.md) — По калибровке болей (2026-07-02) — не боль, из приоритета выпало @@ -53,7 +50,6 @@ Tududi (проект `jellybit`) больше **не** держит беклог - [Выбор из нескольких находок метабазы в Telegram](telegram-vybor-nahodok.md) — Когда распознавание даёт несколько подходящих кандидатов в метабазе, предлагать их в… - [Улучшения UI: показывать матч с записью метабазы в Telegram](telegram-match-metabazy.md) — Название/год/провайдер+id в боте уже выводятся; осталась кликабельная ссылка на запись - [Добавление торрентов файлом/ссылкой — «единое окно» (остаток: URL)](dobavlenie-edinoe-okno.md) — magnet и .torrent-файл приняты; остался фетч .torrent по URL (нужен SSRF-гард) -- [Форма приёма: длинное имя .torrent-файла ломает верстку add-row](torrent-fayl-dlinnoe-imya.md) — длинное имя файла распирает лейбл файл-пикера, поле source сжимается — нужен ellipsis - [Раздачи-копии диска (DVD/BluRay: VIDEO_TS/BDMV)](disk-kopii-video-ts-bdmv.md) — Иногда для очень редких фильмов скачивается не один видеофайл, а полная копия диска… - [Проверка свободного места перед copy-fallback](svobodnoe-mesto-copy-fallback.md) — Когда хардлинк невозможен (EXDEV/ENOTSUP/…), layout копирует файл, дублируя место на диске - [Кэш метабаз (и опционально LLM)](kesh-metabaz.md) — Повторные и ретраящиеся прогоны распознавания бьют TMDB/TVDB/TVMaze одним и тем же… @@ -61,7 +57,6 @@ Tududi (проект `jellybit`) больше **не** держит беклог - [[идея] Завершение загрузки через webhook](webhook-zavershenie-zagruzki.md) — ИДЕЯ (решим по опыту эксплуатации) - [Авторизация веб-UI (на будущее)](avtorizaciya-web-ui.md) — Решено для v1: без авторизации в доверенной LAN, опц - [Современный Web-UI как PWA](web-ui-pwa.md) — Переделать веб-интерфейс в современное PWA-приложение (устанавливаемое, отзывчивое… -- [Сделать фавиконку для jellybit](favicon.md) — мелкая косметика: иконка вкладки/PWA для веб-UI - [Идентичность инфохэшей: split v1/v2 одного торрента + крафт-магнет отравляет владение (F4, F5)](review-f4-f5-infohash-identity.md) — split v1/v2 идентичность и крафт-магнет отравляют владение инфохэшами _(ревью 2026-07-08)_ - [Приём/UI: мелкие фиксы границ и парсинга (F7, F8, F9, F10, N2)](review-f7-f10-ingest-ui-fixes.md) — мелочи приёма/UI: oversized→500, гонки дедупа, парсинг magnet, cap контекста, руны _(ревью 2026-07-08)_ - [Жизненный цикл: мелкие находки (MINOR-8, MINOR-9, NIT-11, NIT-12)](review-lifecycle-minor.md) — claim-token распознавания, I/O под глобальным mutex, мелкие lookup/retry _(ревью 2026-07-08)_ diff --git a/docs/backlog/favicon.md b/docs/backlog/favicon.md deleted file mode 100644 index 5c1f65c..0000000 --- a/docs/backlog/favicon.md +++ /dev/null @@ -1,5 +0,0 @@ -# Сделать фавиконку для jellybit - -**Приоритет:** низкий - -_Описание не заполнено._ diff --git a/docs/backlog/panel-review-vne-swap.md b/docs/backlog/panel-review-vne-swap.md deleted file mode 100644 index 01a62ea..0000000 --- a/docs/backlog/panel-review-vne-swap.md +++ /dev/null @@ -1,7 +0,0 @@ -# Панель действий ревью вне htmx-свопа блока источника - -**Приоритет:** низкий - -При выборе источника одним кликом обновляется только блок источника (#source-block) htmx-свопом, а нижняя панель действий (кнопка «Применить», завязанная на HasLinks) — вне блока и не обновляется до полной перезагрузки. Практически не мешает (хардлинки только по явному «Применить», Apply без плана вернёт ошибку), но в краевом случае (источник с пустым предпросмотром из-за коллизии) кнопка может остаться/пропасть не синхронно. Решение намечено в дизайне review-unified-source-block: обновлять панель hx-swap-oob из того же партиала. - -Связано: openspec/specs/review, openspec/specs/web-ui, пакет httpapi. diff --git a/docs/backlog/skryvat-otmenennye-v-spiske.md b/docs/backlog/skryvat-otmenennye-v-spiske.md deleted file mode 100644 index bb1619a..0000000 --- a/docs/backlog/skryvat-otmenennye-v-spiske.md +++ /dev/null @@ -1,35 +0,0 @@ -# Скрывать отменённые (cancelled) в общем списке наравне с удалёнными - -**Приоритет:** низкий · **Теги:** web-ui - -Отменённые загрузки (`cancelled`) должны по умолчанию скрываться в общем списке -так же, как удалённые (`deleted`), а тумблер «Показать всё, включая удалённые» -(`web/templates/index.html:52`) должен показывать **и те, и те**. Сейчас под -группой `all` скрыт только `deleted`, а `cancelled` всегда виден и шумит в ленте -— тем более что новый стоп-кран «Закрыть» будет плодить `cancelled`-записи. - -Где править: -- `internal/store/list.go:62-66` — ветка `else if !f.IncludeDeleted` под группой - `all` скрывает только `StateDeleted` (`state <> ?`). Расширить до - `state NOT IN (deleted, cancelled)`. -- Осмыслить семантику флага `ListFilter.IncludeDeleted` (`list.go:45`): теперь он - «показывать скрытые терминальные» (deleted **и** cancelled). Либо переименовать - (`IncludeHidden`/`IncludeTerminal`), либо оставить имя и уточнить комментарий. -- Метка тумблера (`index.html:52`) и текст — при желании подправить («…включая - отменённые и удалённые»); `ShowAll`/`all=1` уже управляет показом. -- Комментарии-инварианты про «под all видны» в `internal/store/list.go:22-26` и - `statesInGroup` (cancelled/reverted/deleted не имеют чипа) — привести в - соответствие. - -Замечания: -- `cancelled` своей группы-чипа не имеет (`statesInGroup`, `list.go:29-40`) — под - группами `review/active/done/problem` он и так не появляется, правка нужна - только в ветке `all`. -- `reverted` пользователь не упоминал — по умолчанию оставляем видимым; при - желании обсудить симметрию отдельно. -- Обновить тест `TestListDownloadsPageFilterAndDeleted` - (`internal/store/list_test.go`) — добавить `cancelled` в скрытые по умолчанию и - видимые под `IncludeDeleted`. - -Связано: `openspec/specs/web-ui`, пакеты `internal/store`, `internal/httpapi`, -конвенция [web-ui](../conventions/web-ui.md). diff --git a/docs/backlog/spisok-znachok-tipa.md b/docs/backlog/spisok-znachok-tipa.md deleted file mode 100644 index 0b6978b..0000000 --- a/docs/backlog/spisok-znachok-tipa.md +++ /dev/null @@ -1,25 +0,0 @@ -# Значок типа (фильм/сериал) в списке загрузок - -**Приоритет:** низкий - -В строке списка загрузок показывать значок типа контента — 🎬 фильм / 📺 сериал, -как уже делается на экране деталей/ревью и в карточке бота -(`internal/tgbot/render.go:231-233`). Сейчас партиал строки списка -`web/templates/partials/card.html` (define `"card"`) типа не показывает — только -заголовок, ID, дату/размер, статус-бейдж и прогресс. - -Что учесть: - -- Media type в модели строки списка отсутствует: `downloadView` - (`internal/httpapi/httpapi.go:200`) и `store.Download` - (`internal/store/download.go:175`) его не несут. В detail/review он берётся из - `rd.Plan.Type` (`internal/httpapi/download.go:139`). Каноничный тип — - `recognize.MediaType` (`movie`/`series`). -- Нужно протащить `MediaType`/`IsSeries` в листинг: расширить запрос - `ListDownloadsPage` (сейчас через LEFT JOIN тянет только `rec_title`) и сборку - `buildCardView`, затем добавить значок в `card.html`. -- Тип может быть ещё не распознан (загрузка на раннем шаге) — предусмотреть - отсутствие значка/нейтральный плейсхолдер. - -Связано: `internal/httpapi`, `web/templates/partials/card.html`, -[docs/specs/architecture.md](../specs/architecture.md). diff --git a/docs/backlog/torrent-fayl-dlinnoe-imya.md b/docs/backlog/torrent-fayl-dlinnoe-imya.md deleted file mode 100644 index 01a8b55..0000000 --- a/docs/backlog/torrent-fayl-dlinnoe-imya.md +++ /dev/null @@ -1,30 +0,0 @@ -# Форма приёма: длинное имя .torrent-файла ломает верстку add-row - -**Приоритет:** низкий · **Теги:** web-ui, ingest - -При выборе `.torrent`-файла с длинным именем (типичный релиз с трекера, напр. -«Бухта вдов Widow's Bay Сезон 1 Серии 1-10 из 10 (Хиро Мурай) [2026, США, …, -WEB-DL 1080p] 7 x MVO (HDr [rutracker-6869937].torrent») кнопка-лейбл файл-пикера -раздувается на всю ширину и ломает раскладку строки добавления: поле `source` -сжимается/прячется, «Добавить» уезжает. - -Причина: onchange пишет полное `files[0].name` в `[data-file-label]` -(`web/templates/index.html:26-30`), а у `.btn-file` нет ограничения ширины -(`web/static/css/jellybit.css:194` — только цвет). В `.add-row` -(`display:flex`, `.input{flex:1}`) лейбл распирается по контенту и съедает строку. - -Фикс (косметика, без домена): -- CSS `.btn-file`: `max-width` + `overflow:hidden; text-overflow:ellipsis; - white-space:nowrap` — имя усекается многоточием, а не растягивает строку. -- Опц.: показывать базовое имя без `.torrent` и класть полное в `title` - (тултип). Полное имя всё равно уходит на сабмит через сам file-input - (`header.Filename`), правка чисто визуальная. - -Смежное (проверить заодно, не обязательно тем же фиксом): на приёме `source_ref` -выводится из имени раздачи/файла и может быть очень длинным. В списке/карточке он -усечён (`shorten(oneLine(d.SourceRef), 120)` — `internal/httpapi/download.go:67`), -так что отображение ок; убедиться лишь, что нет жёсткого лимита колонки в БД, -роняющего сам приём длинного имени. - -Связано: `openspec/specs/ingest`, `openspec/specs/web-ui`, пакет `httpapi`, -конвенция [web-ui](../conventions/web-ui.md). diff --git a/openspec/specs/review/spec.md b/openspec/specs/review/spec.md index d82f475..c70802b 100644 --- a/openspec/specs/review/spec.md +++ b/openspec/specs/review/spec.md @@ -117,7 +117,11 @@ qBittorrent, но и **готов к раскладке** — раздача в выполняться через раундтрип на сервер (форма/htmx), без клиентского пересчёта доменного состояния; при этом инфо-часть и предпросмотр раскладки SHALL немедленно обновляться под выбранный источник (частичный своп блока, без полной -перезагрузки страницы). Экран SHALL позволять операции над этим списком: +перезагрузки страницы). Тем же ответом свопа SHALL синхронно обновляться панель +действий — в частности доступность команды **Применить**, зависящая от наличия +предпросмотра раскладки, — через out-of-band-фрагмент, чтобы кнопка не +рассинхронизировалась с блоком источника (например при пустом предпросмотре +из-за коллизии путей). Экран SHALL позволять операции над этим списком: выбрать кандидата базы, переключиться на другого кандидата и снять матч с базы обратно на нейронку («без базы»). Список источников SHALL показываться только при наличии плана распознавания. @@ -139,6 +143,8 @@ qBittorrent, но и **готов к раскладке** — раздача в отдельного нажатия кнопки «выбрать» - **AND** инфо-часть и предпросмотр раскладки сразу обновляются под выбранного кандидата без полной перезагрузки страницы +- **AND** панель действий обновляется тем же ответом (out-of-band): доступность + «Применить» синхронна наличию предпросмотра раскладки #### Scenario: Снятие матча в пользу нейронки diff --git a/openspec/specs/web-ui/spec.md b/openspec/specs/web-ui/spec.md index 9dcb714..0c366e9 100644 --- a/openspec/specs/web-ui/spec.md +++ b/openspec/specs/web-ui/spec.md @@ -93,10 +93,12 @@ self-hosted шрифтов, единая дизайн-система (`jellybit. и страницу просмотра одной загрузки (`/download/{id}`) с распознаванием, файлами→раскладкой, историей, блоком информации о торренте и — для сидирующих задач — секцией живой статистики раздачи. Карточки активных (downloading) -загрузок в списке SHALL содержать индикатор прогресса. Фильтр, поиск и номер +загрузок в списке SHALL содержать индикатор прогресса. Карточка загрузки с +распознанным типом SHALL нести значок типа (фильм/сериал). Фильтр, поиск и номер страницы SHALL передаваться GET-параметрами запроса (например `f`, `q`, `page`) -и SHALL работать без клиентского JavaScript. Состояние `deleted` SHALL быть -скрыто в списке по умолчанию (с переключателем «показать всё»). Механика живого +и SHALL работать без клиентского JavaScript. Терминальные состояния `deleted` и +`cancelled` SHALL быть скрыты в списке по умолчанию (переключатель «показать +всё» раскрывает оба). Механика живого обновления прогресса и наполнение секции раздачи определяются capability `live-status`. @@ -112,12 +114,18 @@ self-hosted шрифтов, единая дизайн-система (`jellybit. - **THEN** её карточка содержит индикатор прогресса (прогресс-бар со скоростью и ETA) -#### Scenario: Удалённые скрыты по умолчанию +#### Scenario: Отменённые и удалённые скрыты по умолчанию -- **WHEN** в списке есть загрузки в состоянии `deleted` и фильтр «показать - всё» не включён +- **WHEN** в списке есть загрузки в состоянии `deleted` или `cancelled` и фильтр + «показать всё» не включён - **THEN** они не отображаются, но доступны при включённом переключателе +#### Scenario: Значок типа в карточке списка + +- **WHEN** загрузка в списке имеет распознанный тип (`movie` или `series`) +- **THEN** её карточка показывает значок типа (🎬 фильм / 📺 сериал); при + отсутствии распознанного типа значок не показывается + #### Scenario: Пагинация списка - **WHEN** загрузок под текущим фильтром больше, чем помещается на одну