130 lines
9.1 KiB
Markdown
130 lines
9.1 KiB
Markdown
# TODO
|
||
|
||
Конкретные задачи на будущее, ранжированные по приоритету. Это не план
|
||
реализации (он — в [drafts/roadmap.md](drafts/roadmap.md)) и не свалка
|
||
идей ([drafts/ideas.md](drafts/ideas.md)): сюда попадает то, что уже решили
|
||
сделать, но ещё не сделали. Принятое и реализованное переезжает в
|
||
`docs/specs`/`docs/adr`.
|
||
|
||
Приоритет — грубая оценка «ценность / стоимость», не обязательство к
|
||
порядку.
|
||
|
||
## Высокий
|
||
|
||
### Проблема второго сезона
|
||
|
||
Если первый сезон сериала уже разложен, а мы добавляем второй/третий/…,
|
||
распознавание должно привязать новый сезон к **тому же** названию и папке,
|
||
а не завести рядом почти одинаковую вторую папку. Ключ — стабильный
|
||
`provider_id`: один и тот же `[tvdbid-…]` → одна папка сериала, новые
|
||
`Season NN` доливаются внутрь. Нужно: при матче учитывать уже существующие
|
||
в библиотеке сериалы (или прошлые распознавания с тем же провайдер-id) и
|
||
склонять LLM/выбор кандидата к согласованности с ними.
|
||
|
||
Связано: [recognition.md](specs/recognition.md) (модель уверенности,
|
||
матч в базе), [jellyfin-layout.md](specs/jellyfin-layout.md) (папка
|
||
сериала с провайдер-id).
|
||
|
||
### Название из контекста при добавлении в qBittorrent
|
||
|
||
При создании magnet-загрузки передавать в qBittorrent человекочитаемое имя
|
||
из контекста (если оно есть), чтобы в списке qBit не было безликих
|
||
`rutracker-topic-6852853`. Небольшая задача с заметной отдачей в
|
||
повседневной эксплуатации.
|
||
|
||
Связано: [architecture.md](specs/architecture.md) → «Транспорты», пакет
|
||
`ingest`/`qbt`.
|
||
|
||
### Рассинхрон состояния с реальностью (удалённый торрент / файлы)
|
||
|
||
Состояние jellybit может разойтись с тем, что реально лежит на диске.
|
||
Несколько сценариев разной остроты:
|
||
|
||
- **Жёсткий — удалён источник.** Раздачу удаляют (вручную или авто по
|
||
достижении seed limit), и qBittorrent стирает скачанные файлы. Тогда
|
||
хардлинк в библиотеке становится **последней** ссылкой на inode, и
|
||
обычный `undo` (`unlink` цели + чистка пустых каталогов) сотрёт
|
||
единственную копию насовсем — прямая потеря данных. Инвариант «источник
|
||
неприкосновенен» молчаливо перестаёт держаться: источника уже нет.
|
||
- **Мягкий — удалена цель.** Файлы убрали из библиотеки Jellyfin (вручную
|
||
или из самого Jellyfin), а jellybit по-прежнему числит загрузку в
|
||
`done`. Состояние врёт: ссылок уже нет, а сервис думает, что всё
|
||
разложено.
|
||
|
||
Нужно продумать сверку записанного состояния (`file_link`, состояние
|
||
загрузки) с фактом на ФС:
|
||
|
||
- как `worker` реагирует на исчезновение раздачи из qBittorrent
|
||
(состояние/пометка загрузки);
|
||
- как `undo` защищается, когда источник недоступен — например,
|
||
отказываться удалять, если у целевого файла счётчик ссылок == 1 (нет
|
||
второй копии) или исходный путь не существует, и явно об этом сообщать.
|
||
Откат снимает **лишний** хардлинк, а не последнюю копию файла;
|
||
- как ловить пропажу целевых файлов и отражать её в состоянии (напр.
|
||
периодическая сверка или проверка при показе — «разложено, но файлов
|
||
нет»), чтобы можно было осознанно перепривязать/переразложить.
|
||
|
||
Связано: [ADR-2026-06-13-hardlinks](adr/ADR-2026-06-13-hardlinks.md),
|
||
[architecture.md](specs/architecture.md) → «Раскладка файлов» (undo,
|
||
инвариант источника), [workflow.md](specs/workflow.md) (`done → reverted`).
|
||
|
||
## Средний
|
||
|
||
### Машина состояний на go-библиотеке
|
||
|
||
Сейчас FSM реализована вручную в `worker`. Выбрать подходящую go-библиотеку
|
||
для описания воркфлоу/машины состояний и перевести переходы на неё — ради
|
||
декларативности, проверяемости переходов и единого места правды. Кандидаты
|
||
для оценки: `looplab/fsm`, `qmuntal/stateless` (и аналоги). Граф и переходы
|
||
уже формализованы — переносим один в один.
|
||
|
||
Связано: [workflow.md](specs/workflow.md) (текущий граф состояний).
|
||
|
||
### Привязка уведомлений к источнику в ботах (мульти-бот)
|
||
|
||
Уведомления и запросы подтверждения должен получать тот, кто прислал
|
||
загрузку: автор сообщения о новой раздаче — адресат пингов и ревью по ней.
|
||
Транспортов-ботов может быть несколько (Telegram, в перспективе Matrix и
|
||
др.); каждый адресует «своему» отправителю. Веб-интерфейс остаётся
|
||
**единым для всех** и точкой правды по функциональности (боты — тонкие
|
||
адаптеры над тем же ядром). Нужно: хранить у загрузки источник/транспорт и
|
||
идентификатор отправителя, маршрутизировать пинги по нему.
|
||
|
||
Связано: [review-ux.md](specs/review-ux.md) (разделение труда транспортов,
|
||
веб = точные правки), [architecture.md](specs/architecture.md) →
|
||
«Транспорты».
|
||
|
||
### Добавление торрентов файлом/ссылкой — «единое окно»
|
||
|
||
Поддержать источники помимо magnet: `.torrent`-файл и URL (отдаём их в
|
||
qBittorrent, без исходящих запросов на пользовательский URL — SSRF
|
||
исключён). Идеал — одно поле «единого окна»: кидаем туда текст или файл, а
|
||
сервис сам разбирает, что это (magnet / ссылка / .torrent / сообщение
|
||
бота), и заводит загрузку.
|
||
|
||
Связано: [architecture.md](specs/architecture.md) → «Транспорты»
|
||
(`source_type = magnet|torrent|url` уже в схеме), пакет `ingest` (сейчас
|
||
поддержан только magnet).
|
||
|
||
## Низкий
|
||
|
||
### Многоступенчатая верификация привязки (тема для размышления)
|
||
|
||
Идея: несколько раз извлекать данные из раздачи и контекста разными
|
||
промптами, искать в метабазах, затем сводить результаты в общий вердикт
|
||
(голосование/консенсус) — выше точность ценой нескольких вызовов LLM и
|
||
запросов к базам. Требует проработки: когда включать, как мерджить
|
||
расхождения, стоимость/латентность.
|
||
|
||
Связано: [recognition.md](specs/recognition.md) (конвейер и модель
|
||
уверенности).
|
||
|
||
### Современный Web-UI как PWA
|
||
|
||
Переделать веб-интерфейс в современное PWA-приложение (устанавливаемое,
|
||
отзывчивое, удобное с телефона). Текущий server-rendered UI функционален,
|
||
поэтому это улучшение, а не блокер; большой объём работы.
|
||
|
||
Связано: [review-ux.md](specs/review-ux.md) (веб = точные правки),
|
||
пакет `httpapi`.
|