Files
jellybit/docs/todo.md
T

9.1 KiB
Raw Blame History

TODO

Конкретные задачи на будущее, ранжированные по приоритету. Это не план реализации (он — в drafts/roadmap.md) и не свалка идей (drafts/ideas.md): сюда попадает то, что уже решили сделать, но ещё не сделали. Принятое и реализованное переезжает в docs/specs/docs/adr.

Приоритет — грубая оценка «ценность / стоимость», не обязательство к порядку.

Высокий

Проблема второго сезона

Если первый сезон сериала уже разложен, а мы добавляем второй/третий/…, распознавание должно привязать новый сезон к тому же названию и папке, а не завести рядом почти одинаковую вторую папку. Ключ — стабильный provider_id: один и тот же [tvdbid-…] → одна папка сериала, новые Season NN доливаются внутрь. Нужно: при матче учитывать уже существующие в библиотеке сериалы (или прошлые распознавания с тем же провайдер-id) и склонять LLM/выбор кандидата к согласованности с ними.

Связано: recognition.md (модель уверенности, матч в базе), jellyfin-layout.md (папка сериала с провайдер-id).

Название из контекста при добавлении в qBittorrent

При создании magnet-загрузки передавать в qBittorrent человекочитаемое имя из контекста (если оно есть), чтобы в списке qBit не было безликих rutracker-topic-6852853. Небольшая задача с заметной отдачей в повседневной эксплуатации.

Связано: 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, architecture.md → «Раскладка файлов» (undo, инвариант источника), workflow.md (done → reverted).

Средний

Машина состояний на go-библиотеке

Сейчас FSM реализована вручную в worker. Выбрать подходящую go-библиотеку для описания воркфлоу/машины состояний и перевести переходы на неё — ради декларативности, проверяемости переходов и единого места правды. Кандидаты для оценки: looplab/fsm, qmuntal/stateless (и аналоги). Граф и переходы уже формализованы — переносим один в один.

Связано: workflow.md (текущий граф состояний).

Привязка уведомлений к источнику в ботах (мульти-бот)

Уведомления и запросы подтверждения должен получать тот, кто прислал загрузку: автор сообщения о новой раздаче — адресат пингов и ревью по ней. Транспортов-ботов может быть несколько (Telegram, в перспективе Matrix и др.); каждый адресует «своему» отправителю. Веб-интерфейс остаётся единым для всех и точкой правды по функциональности (боты — тонкие адаптеры над тем же ядром). Нужно: хранить у загрузки источник/транспорт и идентификатор отправителя, маршрутизировать пинги по нему.

Связано: review-ux.md (разделение труда транспортов, веб = точные правки), architecture.md → «Транспорты».

Добавление торрентов файлом/ссылкой — «единое окно»

Поддержать источники помимо magnet: .torrent-файл и URL (отдаём их в qBittorrent, без исходящих запросов на пользовательский URL — SSRF исключён). Идеал — одно поле «единого окна»: кидаем туда текст или файл, а сервис сам разбирает, что это (magnet / ссылка / .torrent / сообщение бота), и заводит загрузку.

Связано: architecture.md → «Транспорты» (source_type = magnet|torrent|url уже в схеме), пакет ingest (сейчас поддержан только magnet).

Низкий

Многоступенчатая верификация привязки (тема для размышления)

Идея: несколько раз извлекать данные из раздачи и контекста разными промптами, искать в метабазах, затем сводить результаты в общий вердикт (голосование/консенсус) — выше точность ценой нескольких вызовов LLM и запросов к базам. Требует проработки: когда включать, как мерджить расхождения, стоимость/латентность.

Связано: recognition.md (конвейер и модель уверенности).

Современный Web-UI как PWA

Переделать веб-интерфейс в современное PWA-приложение (устанавливаемое, отзывчивое, удобное с телефона). Текущий server-rendered UI функционален, поэтому это улучшение, а не блокер; большой объём работы.

Связано: review-ux.md (веб = точные правки), пакет httpapi.