Files
jellybit/docs/backlog/udalenie-edinoe-okno.md
T
avandClaude Opus 4.8 a43adea723 Беклог: переоформить path-2 удаления в одну задачу «полное удаление»
Обсудили: для сервиса одного окна основное действие — удалить всё разом (раздачу
+ файлы в библиотеке), чтобы освободить место. Из-за хардлинков иначе место и не
вернуть — снять надо обе ссылки на инод. Задача udalenie-edinoe-okno переписана в
одну конкретную:

- действие «Удалить» на загрузке: снять живые хардлинки (undo-механика, superseded
  пропускаем) + удалить раздачу с файлами из qBittorrent (новый метод qbt);
  осознанно обходим предохранитель последней копии; обязательное подтверждение;
- undo (перераспознать, гард включён) vs delete (освободить место, гард выключен)
  зафиксированы как разные действия;
- терминальное состояние — переиспользуем deleted, инициатора (user/reconcile)
  пишем в лог перехода; в граф добавить ребро done→deleted;
- тайтл-группа и экран состава выкинуты как оверинжиниринг; мультивыбор в списке —
  опциональный шаг.

Реализовать как OpenSpec-change. Приоритет высокий (недостающая половина одного
окна, частый сценарий «досмотрел → освободить место»).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 15:43:26 +03:00

53 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Полное удаление загрузки из jellybit («единое окно», path 2)
**Приоритет:** высокий
Безопасная половина «единого окна» уже в проде: распознавание ручного удаления и
пометка рассинхрона (state-reconciliation — `target_missing`/`orphaned`/`deleted`,
undo с nlink-гардом, preflight). Осталась вторая половина — **удалять из самого
jellybit**, не идя руками в qBittorrent/Jellyfin.
Основной сценарий одного окна — «досмотрел → освободить место»: удалить и раздачу,
и файлы в библиотеке разом. Из-за хардлинков иначе место и не вернуть — файл в
`downloads/` (qBittorrent) и наша ссылка в библиотеке указывают на **один инод**,
диск освобождается только когда исчезает последняя ссылка. Значит delete обязан
снять **обе** стороны.
## Действие «Удалить» (одна загрузка)
- Снять живые хардлинки загрузки (переиспользуем undo-механику: `superseded`
пропускаем) **+** удалить раздачу с файлами из qBittorrent (новый метод в `qbt`,
`deleteTorrents` с `deleteFiles=true`).
- **Осознанно обходим** предохранитель последней копии (undo при «источник удалён,
цель — последняя копия» отказывает — `worker/review.go:499`; здесь мы наоборот
хотим снять последнюю копию).
- Обязательное **подтверждение** — это выход за инвариант «источник
неприкосновенен», не по случайному клику. Логировать как осознанное удаление
источника.
## undo vs delete (зафиксировать различие)
- **undo** — «перераспознать»: снимает только наши ссылки, раздачу в qBittorrent
сохраняет, данные бережёт (гард включён). Уже готов.
- **delete** — «убрать окончательно, освободить место»: снимает наши ссылки И
сносит раздачу+файлы, гард выключен, состояние терминальное.
## Терминальное состояние
Переиспользуем существующий `deleted` (исход тот же: и источник, и цель сняты) —
**без** нового статуса. Инициатора (`user` против reconciliation) пишем в причину/
лог перехода. В граф переходов добавить явное пользовательское ребро
`done → deleted` (сейчас `deleted` выводит только сверка с реальностью).
## Опционально (если понадобится)
Мультивыбор в списке + «удалить выбранное» — тонкая обёртка над тем же действием
для редкого случая «снести сериал целиком». Вычисляемую группу-«тайтл» и экран
состава **не** делаем — оверинжиниринг ради редкого сценария.
Оформить как OpenSpec-change (дельта `state-reconciliation`/`review` + метод `qbt`
+ ребро графа + action в UI/боте).
Связано: drafts/logical-title-model.md §5.3/§6.4, ADR-2026-06-13-hardlinks,
openspec/specs/state-reconciliation, specs/workflow.md, пакеты qbt, worker, layout.