@@ -1,13 +1,13 @@
# TODO
# Беклог
Конкретные задачи на будущее, ранжированные по приоритету. Это не план
Единый список будущих задач по проекту: то, что уже решили сделать, и
реализации (он — в [ drafts/roadmap.md ]( drafts/roadmap.md )) и не свалка
идеи, которые ещё надо обдумать. Это не план реализации (он — в
идей ( [drafts/ideas .md ](drafts/ideas.md )): сюда попадает то, что уже решил и
[drafts/roadmap .md ](drafts/roadmap.md )) и не источник истины: принятое и
сделать, но ещё не сделали. Принятое и реализованное переезжает в
реализованное переезжает в `docs/specs` / `docs/adr` .
`docs/specs` /`docs/adr` .
Приоритет — грубая оценка «ценность / стоимость», не обязательство к
Приоритет — грубая оценка «ценность / стоимость», не обязательство к
порядку.
порядку. Спекулятивные пункты (ещё без решения «делаем») помечены
_(идея)_ — их сперва надо проработать.
## Высокий
## Высокий
@@ -45,6 +45,32 @@ qBittorrent с файлами), подтверждение осознаннос
[architecture.md ](specs/architecture.md ) → «Раскладка файлов»,
[architecture.md ](specs/architecture.md ) → «Раскладка файлов»,
[workflow.md ](specs/workflow.md ).
[workflow.md ](specs/workflow.md ).
### Ревью: выбор источника совпадения и предпросмотр
Переработать страницу ревью так, чтобы показывать **все ** совпавшие
результаты по метабазам списком и дать выбрать из них. Принцип: совпадение
есть **всегда ** — мы лишь выбираем источник. Поэтому матч нейронки — это
отдельная строка в том же списке (наравне с кандидатами TMDB/TVDB), а не
особый режим.
Возможности экрана:
- список кандидатов из баз + строка «распознано нейронкой»;
- выбрать один кандидат, переключиться на другой, отменить матч с базой в
пользу нейронки;
- добавить кандидат вручную (по id/url базы), когда автопоиск промахнулся;
- при выборе/переключении — **предпросмотр полей ** (название, режиссёр,
год) и **предпросмотр раскладки ** (целевые пути) до применения.
Развивает «показывать матч с записью метабазы» (web-сторона), пересекается
с «Расширенной информацией о загрузке» (детальный экран) и быстрым выбором
в Telegram. Веб остаётся точкой точных правок.
Связано: [review-ux.md ](specs/review-ux.md ) (выбор кандидата, «без базы»,
переключатель типа), [recognition.md ](specs/recognition.md ) (кандидаты
матча, провайдер-id), [«Улучшения UI: показывать матч» ](#улучшения-ui-показывать-матч-с-записью-метабазы ),
пакет `httpapi` .
### Наблюдаемость: метрики и учёт стоимости LLM
### Наблюдаемость: метрики и учёт стоимости LLM
Сейчас единственное окно в систему — `slog` . Нет быстрых ответов на
Сейчас единственное окно в систему — `slog` . Нет быстрых ответов на
@@ -98,6 +124,33 @@ qBittorrent с файлами), подтверждение осознаннос
## Средний
## Средний
### Главная: список загрузок вместо таблицы
Переделать главную страницу из таблицы в **список ** карточек. Для каждой
загрузки: название (как распознали при добавлении в qBittorrent), `infohash`
с кнопкой быстрого копирования, статус и кнопки действий. Контекст (исходное
сообщение/magnet) спрятать под спойлер или вынести на отдельный детальный
экран (см. «Расширенная информация о загрузке»). Естественно сочетается с
фильтром/поиском/пагинацией по мере роста БД.
Связано: [«Расширенная информация о загрузке в web-UI» ](#расширенная-информация-о-загрузке-в-web-ui ),
[«Список загрузок: фильтр, поиск, пагинация» ](#список-загрузок-фильтр-поиск-пагинация ),
[review-ux.md ](specs/review-ux.md ), пакет `httpapi` .
### Расширенная информация о загрузке в web-UI
Отдельная страница просмотра одной загрузки — целиком отображение того, что
лежит в БД по задаче: актуальный статус (текущее состояние + лог переходов),
исходный контекст и magnet, распознанные данные и матч в метабазе (см.
«показывать матч»), а также **точная раскладка, если есть ** — целевые пути и
созданные хардлинки. Помогает разбираться, когда что-то пошло не так, без
чтения логов сервера. Сюда же выносится контекст с карточки в списке
загрузок.
Связано: [«Главная: список загрузок» ](#главная-список-загрузок-вместо-таблицы ),
[review-ux.md ](specs/review-ux.md ), [architecture.md ](specs/architecture.md )
→ «Хранилище» (`download` /`recognition` /`file_link` ), пакет `httpapi` .
### Машина состояний на go-библиотеке
### Машина состояний на go-библиотеке
Сейчас FSM реализована вручную в `worker` . Выбрать подходящую go-библиотеку
Сейчас FSM реализована вручную в `worker` . Выбрать подходящую go-библиотеку
@@ -139,16 +192,29 @@ qBittorrent с файлами), подтверждение осознаннос
[jellyfin-layout.md ](specs/jellyfin-layout.md ) (раскладка, идемпотентность),
[jellyfin-layout.md ](specs/jellyfin-layout.md ) (раскладка, идемпотентность),
[workflow.md ](specs/workflow.md ) (повторный прогон загрузки).
[workflow.md ](specs/workflow.md ) (повторный прогон загрузки).
### Улучшения UI клиентов : показывать матч с записью метабазы
### Улучшения UI: показывать матч с записью метабазы
Во всех транспортах (веб, Telegram) показывать, **с какой именно записью**
Во всех транспортах (веб, Telegram) показывать, **с какой именно записью**
метабазы (TMDB/TVDB) сматчилась загрузка: название, год, провайдер-id,
метабазы (TMDB/TVDB) сматчилась загрузка: название, год, провайдер-id,
ссылку. Сейчас результат распознавания непрозрачен — пользователь не видит,
ссылку. Сейчас результат распознавания непрозрачен — пользователь не видит,
к чему привязались, и не может быстро поймать ошибочный матч.
к чему привязались, и не может быстро поймать ошибочный матч. На web-стороне
развивается в полноценный выбор источника — см. [«Ревью: выбор источника
совпадения»](#ревью -выбор-источника-совпадения-и-предпросмотр).
Связано: [review-ux.md ](specs/review-ux.md ), [recognition.md ](specs/recognition.md )
Связано: [review-ux.md ](specs/review-ux.md ), [recognition.md ](specs/recognition.md )
(матч в базе), [architecture.md ](specs/architecture.md ) → «Транспорты».
(матч в базе), [architecture.md ](specs/architecture.md ) → «Транспорты».
### Аниме с абсолютной нумерацией
Релизы аниме часто нумеруют серии сквозным числом (`#137` ) без сезонов, а
Jellyfin ждёт `SxxEyy` . Нужен пересчёт абсолютной нумерации в сезон/серию —
надёжнее всего через TVDB (там есть absolute order). Отдельный крайний
случай распознавания; на стороне ревью — веб-хелпер «absolute → S·E».
Связано: [recognition.md ](specs/recognition.md ) (конвейер, сезон-паки),
[jellyfin-layout.md ](specs/jellyfin-layout.md ) (нумерация серий),
[review-ux.md ](specs/review-ux.md ) (крайние сценарии).
### Добавление торрентов файлом/ссылкой — «единое окно»
### Добавление торрентов файлом/ссылкой — «единое окно»
Поддержать источники помимо magnet: `.torrent` -файл и URL (отдаём их в
Поддержать источники помимо magnet: `.torrent` -файл и URL (отдаём их в
@@ -204,24 +270,31 @@ qBittorrent, без исходящих запросов на пользоват
верификации, но дешевле: учимся на уже собранных `hint` /`override` .
верификации, но дешевле: учимся на уже собранных `hint` /`override` .
Связано: [recognition.md ](specs/recognition.md ) (конвейер, промпт),
Связано: [recognition.md ](specs/recognition.md ) (конвейер, промпт),
[«Многоступенчатая верификация» ](#многоступенчатая-верификация-привязки-тема-для-размышлен ия ),
[«Многоступенчатая верификация» ](#многоступенчатая-верификация-привязки-иде я ),
[architecture.md ](specs/architecture.md ) → «Хранилище» (`hint` , `override` ).
[architecture.md ](specs/architecture.md ) → «Хранилище» (`hint` , `override` ).
### Список загрузок: фильтр, поиск, пагинация
### Список загрузок: фильтр, поиск, пагинация
Прямое следствие роста БД (см. «Ретеншн»): плоский список загрузок со
Прямое следствие роста БД (см. «Ретеншн»): плоский список загрузок со
временем становится непригоден. Нужны фильтр по состоянию, поиск по
временем становится непригоден. Нужны фильтр по состоянию, поиск по
названию и пагинация. Естественно ложится на экран расширенной информации.
названию и пагинация. Естественно ложится на список-карточки главной и на
экран расширенной информации.
Связано: [«Расширенная информация о загрузке в web-UI» ](#расширенная-информация-о-загрузке-в-web-ui ),
Частный случай как разумный дефолт: на главной **по умолчанию скрывать
загрузки в статусе `deleted` ** (терминальные, удалённые из источника и
цели — шум в ленте), с переключателем/фильтром «показать всё». Маленькая
часть, может приехать раньше полноценного фильтра.
Связано: [«Главная: список загрузок» ](#главная-список-загрузок-вместо-таблицы ),
[«Расширенная информация о загрузке в web-UI» ](#расширенная-информация-о-загрузке-в-web-ui ),
пакет `httpapi` .
пакет `httpapi` .
## Низкий
## Низкий
### Многоступенчатая верификация привязки (тема для размышлени я)
### Многоступенчатая верификация привязки _(иде я)_
Идея: н есколько раз извлекать данные из раздачи и контекста разными
Н есколько раз извлекать данные из раздачи и контекста разными промптами,
промптами, искать в метабазах, затем сводить результаты в общий вердикт
искать в метабазах, затем сводить результаты в общий вердикт
(голосование/консенсус) — выше точность ценой нескольких вызовов LLM и
(голосование/консенсус) — выше точность ценой нескольких вызовов LLM и
запросов к базам. Требует проработки: когда включать, как мерджить
запросов к базам. Требует проработки: когда включать, как мерджить
расхождения, стоимость/латентность.
расхождения, стоимость/латентность.
@@ -229,21 +302,14 @@ qBittorrent, без исходящих запросов на пользоват
Связано: [recognition.md ](specs/recognition.md ) (конвейер и модель
Связано: [recognition.md ](specs/recognition.md ) (конвейер и модель
уверенности).
уверенности).
### Расширенная информация о загрузке в web-UI
Экран просмотра деталей одной загрузки: исходный контекст и magnet, лог
переходов состояний, распознанные данные и матч в метабазе (см. «показывать
матч»), целевые пути и созданные хардлинки. Помогает разбираться, когда
что-то пошло не так, без чтения логов сервера.
Связано: [review-ux.md ](specs/review-ux.md ), пакет `httpapi` .
### Выбор из нескольких находок метабазы в Telegram
### Выбор из нескольких находок метабазы в Telegram
Когда распознавание даёт несколько подходящих кандидатов в метабазе,
Когда распознавание даёт несколько подходящих кандидатов в метабазе,
предлагать их в Telegram списком (кнопки) для ручного выбора, а не молча
предлагать их в Telegram списком (кнопки) для ручного выбора, а не молча
брать первый/лучший. Веб остаётся точкой точных правок, бот — быстр ый выбор
брать первый/лучший. Веб остаётся точкой точных правок (полн ый выбор
из готового короткого спис ка.
источника — см. [«Ревью: выбор источни ка
совпадения»](#ревью -выбор-источника-совпадения-и-предпросмотр)), бот —
быстрый выбор из готового короткого списка.
Связано: [review-ux.md ](specs/review-ux.md ) (боты — быстрые действия, веб —
Связано: [review-ux.md ](specs/review-ux.md ) (боты — быстрые действия, веб —
точные правки), [recognition.md ](specs/recognition.md ) (кандидаты матча).
точные правки), [recognition.md ](specs/recognition.md ) (кандидаты матча).
@@ -268,6 +334,35 @@ qBittorrent, без исходящих запросов на пользоват
Связано: [recognition.md ](specs/recognition.md ) (сверка с базой), пакеты
Связано: [recognition.md ](specs/recognition.md ) (сверка с базой), пакеты
`metadata` , `llm` .
`metadata` , `llm` .
### guessit как сервис-спутник _(идея)_
`go-ptn` слабее питоновского `guessit` . Если точности пред-парса не
хватит — завернуть `guessit` в крошечный HTTP-сервис (один файл,
поставляется рядом с бинарём jellybit) и спрашивать его на шаге
пред-парса. Сохраняет «доставку копированием»: два файла вместо одного.
Связано: [recognition.md ](specs/recognition.md ) → «На будущее» (пред-парс).
### Завершение загрузки через webhook _(идея)_
Сейчас завершение ловим поллингом qBittorrent раз в несколько секунд.
Альтернатива: «Run external program on torrent completion» в qBittorrent
дёргает эндпоинт jellybit. Реагирует быстрее, но связывает нас с конфигом
qBittorrent. Решим по опыту эксплуатации.
Связано: [architecture.md ](specs/architecture.md ) → «Отслеживание загрузки»,
пакет `worker` .
### Авторизация веб-UI (на будущее)
Решено для v1: без авторизации в доверенной LAN, опц. allowlist подсетей
(`http.trusted_subnets` ) — как умеет qBittorrent. Если понадобится защита:
токен/Basic в самом приложении или вынос за reverse-proxy с
аутентификацией.
Связано: [architecture.md ](specs/architecture.md ) → «Транспорты» (доступ к
веб-UI), пакет `httpapi` .
### Современный Web-UI как PWA
### Современный Web-UI как PWA
Переделать веб-интерфейс в современное PWA-приложение (устанавливаемое,
Переделать веб-интерфейс в современное PWA-приложение (устанавливаемое,