Files
avandClaude Opus 4.8 1639ebfdd7 Пересканирование Jellyfin: расширить триггер на reverted и deleted
Скан Jellyfin (POST /Library/Refresh) слался только при входе в done.
После Undo (reverted) и Delete (deleted) наши хардлинки сняты, а Jellyfin
держал битые записи до скана по расписанию.

Гейт скана в едином чекпоинте transitionErr переведён с state == done на
предикат triggersScan(state) по множеству {done, reverted, deleted}: гейт по
состоянию-цели естественно ловит пользовательские Undo/Delete и
reconcile-производный deleted, идемпотентно. target_missing/orphaned —
промежуточный рассинхрон (ждём relink/лечения) — исключены.

OpenSpec: заведена и влита дельта file-layout (требование
«Пересканирование Jellyfin после изменения библиотечных ссылок»); change
архивирован. Синк рукописных доков architecture.md/workflow.md. Тесты:
скан стреляет на reverted и deleted, молчит на входе вне множества.
Закрыта задача беклога jellyfin-skan-posle-udaleniya.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 21:14:18 +03:00

5.1 KiB

ADDED Requirements

Requirement: Пересканирование Jellyfin после изменения библиотечных ссылок

При сконфигурированном пересканировании Jellyfin (секция [jellyfin] включена) система SHALL при входе задачи в одно из состояний множества {done, reverted, deleted} неблокирующе просить Jellyfin пересканировать медиатеку (POST /Library/Refresh, скан всех библиотек). Эти три состояния — точки, где раскладка задачи улеглась так, что видимый Jellyfin каталог мог рассинхронизироваться с диском: done — наши хардлинки разложены (или восстановлены сверкой); reverted — Undo снял наши ссылки; deleted — ссылки сняты (Delete) либо констатировано их отсутствие (сверка), задача терминальна.

Условие срабатывания система SHALL проверять по состоянию-цели перехода в едином чекпоинте записи состояния. Такой гейт SHALL естественно покрывать как пользовательские команды (Undo → reverted, Delete → deleted), так и reconcile-производный deleted — инициатор перехода роли не играет; повторный/ лишний скан безвреден (инкрементальный скан дёшев, операция идемпотентна).

Состояния вне этого множества система сканировать SHALL NOT. Сюда входят как входы, не меняющие наши ссылки (review, linking, cancelled через Dismiss), так и промежуточные состояния рассинхрона target_missing и orphaned: там раскладка ещё не улеглась — задача ждёт relink/восстановления и может «залечиться» обратно в done, поэтому скан на них система откладывает, а не шлёт на каждое колебание сверки. target_missing система не сканирует сознательно, хотя цель там пропала: это внешняя пропажа при живом источнике, не наше снятие.

Скан система SHALL выполнять вне блокировки воркера, в фоновом контексте и в отдельной горутине, со scoped-логгером задачи для корреляции. Недоступность Jellyfin на состояние задачи влиять SHALL NOT — ошибка вызова лишь логируется (её пишет клиент Jellyfin как запись внешнего вызова). Если пересканирование не сконфигурировано ([jellyfin] выключено), скан не дёргается ни в одном из этих переходов.

Scenario: Скан после раскладки

  • GIVEN пересканирование Jellyfin включено
  • WHEN задача входит в done после успешной раскладки хардлинков
  • THEN система неблокирующе дёргает POST /Library/Refresh

Scenario: Скан после отката (Undo)

  • GIVEN пересканирование Jellyfin включено, задача в done с разложенными ссылками
  • WHEN пользователь выполняет Undo и задача входит в reverted (наши ссылки сняты)
  • THEN система неблокирующе дёргает POST /Library/Refresh

Scenario: Скан после удаления (Delete)

  • GIVEN пересканирование Jellyfin включено, задача в done
  • WHEN пользователь выполняет Delete и задача входит в deleted (наши ссылки сняты)
  • THEN система неблокирующе дёргает POST /Library/Refresh

Scenario: Без конфигурации Jellyfin скан не дёргается

  • GIVEN пересканирование Jellyfin выключено ([jellyfin] не сконфигурировано)
  • WHEN задача входит в done, reverted или deleted
  • THEN система скан не дёргает

Scenario: Вход вне множества не сканирует

  • GIVEN пересканирование Jellyfin включено
  • WHEN задача входит в состояние вне {done, reverted, deleted} (например, review или промежуточный target_missing)
  • THEN система скан не дёргает