diff --git a/docs/todo.md b/docs/todo.md index b5234bb..254acf6 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -35,6 +35,39 @@ Связано: [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-библиотеке