Скан 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>
58 lines
4.6 KiB
Markdown
58 lines
4.6 KiB
Markdown
## Why
|
||
|
||
Пересканирование Jellyfin сейчас дёргается **только** при входе в `done` (после
|
||
успешной раскладки). Но наши библиотечные хардлинки меняются ещё в двух случаях:
|
||
**Undo** (`done → reverted`) и **Delete** (`… → deleted`) снимают ссылки. После них
|
||
Jellyfin продолжает показывать записи с битыми путями до следующего скана по
|
||
расписанию — рассинхрон видимого каталога с реальностью, который мы уже умеем
|
||
чинить, но не сигналим.
|
||
|
||
Интеграция готова целиком (`internal/jellyfin`, конфиг `[jellyfin]`, проводка
|
||
`SetScanner`) — не хватает лишь расширить условие срабатывания. Точка правки —
|
||
единый чекпоинт `transitionErr` (`internal/worker/worker.go`), через который уже
|
||
проходят оба пути снятия ссылок (`Undo`, `Delete`) и reconcile-производный
|
||
`deleted`.
|
||
|
||
## What Changes
|
||
|
||
- Расширить гейт пересканирования Jellyfin в `transitionErr` с
|
||
`state == done` на множество состояний **входа**, где наши библиотечные
|
||
хардлинки только что изменились: `done` (файлы разложены), `reverted` (Undo снял
|
||
ссылки), `deleted` (Delete снял ссылки / сверка констатировала их отсутствие).
|
||
- Гейт **по состоянию-цели** в едином чекпоинте: он естественно ловит и
|
||
пользовательские Undo/Delete, и reconcile-производный `deleted` — это
|
||
задумано и идемпотентно (лишний скан безвреден, инкрементальный скан дёшев).
|
||
- `target_missing` (и `orphaned`) в множество **не** включаем: это промежуточные
|
||
состояния рассинхрона, где раскладка ещё не «улеглась» — источник жив, задача
|
||
ждёт relink/восстановления и может залечиться обратно в `done`. Скан там
|
||
откладываем, чтобы не слать его на каждое колебание сверки; когда задача
|
||
придёт в `done`/`deleted`, скан сработает по общему правилу.
|
||
- Зафиксировать поведение в спеке `file-layout` (сейчас про Jellyfin-скан в
|
||
`openspec/specs/` нет ни слова) и поправить рукописные доки, где формулировка
|
||
«при входе в `done`» стала неверной.
|
||
|
||
## Capabilities
|
||
|
||
### New Capabilities
|
||
<!-- нет новых capability -->
|
||
|
||
### Modified Capabilities
|
||
- `file-layout`: фиксируется триггер пересканирования Jellyfin — не только после
|
||
раскладки (`done`), но и после снятия наших библиотечных хардлинков
|
||
(`reverted`, `deleted`), неблокирующе и опционально (`[jellyfin]`).
|
||
|
||
## Impact
|
||
|
||
- Код воркера: `internal/worker/worker.go` — расширить условие скана в
|
||
`transitionErr` (`state == done` → множество `{done, reverted, deleted}`),
|
||
обновить поясняющий комментарий.
|
||
- Тесты: `internal/worker/review_test.go` — позитивные тесты, что скан стреляет
|
||
на `reverted` (после `Undo`) и `deleted` (после `Delete`); при желании
|
||
негативный (скан не стреляет на входе, не меняющем наши ссылки).
|
||
- Доки: `docs/specs/architecture.md` («Пересканирование Jellyfin»),
|
||
`docs/specs/workflow.md` — формулировку «при входе в `done`» заменить на
|
||
«после раскладки и после снятия наших ссылок (Undo/Delete)».
|
||
- Данные/инварианты: не затрагиваются. Скан по-прежнему неблокирующий, вне
|
||
`w.mu`, в фоновом ctx; недоступность Jellyfin на состояние задачи не влияет.
|
||
Источник неприкосновенен — скан лишь читает библиотеку.
|