Ревью: preflight готовности источника для команд ревью (MAJOR-5)
Команды ревью проверяли только наличие раздачи в qBittorrent, но не её готовность. Недокачанную задачу можно припарковать в deferred, затем «Распознать заново» → recognizing → авто-раскладка (Rerecognize/Refine/ SetType не ставят force_review) → хардлинки на неполные файлы. Даже ручной Apply не имел preflight завершённости. Вводим ensureSourceReady (classify(t.State)==classReady) вместо ensureSourcePresent во всех командах, которым нужен источник (Relink/ Rerecognize/Refine/SetType), и inline-проверку класса в Apply — последний рубеж перед хардлинками. Недокачанный источник → отдельный sentinel ErrNotReady (409) с actionable-текстом «торрент ещё качается» в web и Telegram, без reconcile (состояние deferred/review легитимно). Change review-readiness-preflight заархивирован, дельта влита в openspec/specs/review. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Команды ревью и их эффекты
|
||||
|
||||
Экран ревью SHALL предоставлять команды: **Применить** (создать хардлинки по
|
||||
эффективному плану), **Уточнить** (добавить подсказку → перераспознать),
|
||||
**Распознать заново** (повторный прогон без новой подсказки), **Игнор файла**,
|
||||
**Позже** (`deferred`), **Отклонить** (`cancelled`), **Undo** (снять созданные
|
||||
ссылки → `reverted`) и **Привязать заново** (из
|
||||
`reverted`/`cancelled`/`target_missing` → перераспознавание с ручным
|
||||
подтверждением). Экран ревью MUST NOT содержать команду переключения типа
|
||||
movie↔series: тип показывается read-only, а его корректировка выполняется
|
||||
мягкой подсказкой через **Уточнить**. Команды из любого транспорта SHALL
|
||||
сериализоваться worker'ом под единой блокировкой; применяется последняя валидная
|
||||
команда.
|
||||
|
||||
Команды, которым нужен источник (**Применить**, **Уточнить**, **Распознать
|
||||
заново**, **Привязать заново**, а также фиксация типа), SHALL синхронно (без
|
||||
дебаунса) проверять перед действием, что источник не только присутствует в
|
||||
qBittorrent, но и **готов к раскладке** — раздача в готовом классе состояния
|
||||
(`uploading`/`stalledUP`/`pausedUP`/… с учётом различий имён qBit v4/v5),
|
||||
т.е. файлы докачаны. Если источник ещё качается (любое `downloading`-подобное
|
||||
или переходное `moving`/`checking` состояние), команда SHALL отказывать с
|
||||
конфликтом и причиной «торрент ещё качается», НЕ создавая хардлинки и НЕ меняя
|
||||
состояние загрузки (её нахождение в `review`/`deferred`/… легитимно, приводить
|
||||
к реальности нечего). Отсутствие источника в qBittorrent SHALL по-прежнему
|
||||
приводить состояние к реальности (`orphaned`/`deleted`) и отказывать. Так
|
||||
недокачанная задача не может пройти через перераспознавание в авто-раскладку
|
||||
или ручное применение и захардлинкать неполные файлы, обойдя финальность
|
||||
состояния `completed`.
|
||||
|
||||
#### Scenario: Применение создаёт раскладку
|
||||
|
||||
- **GIVEN** загрузка в `review` с эффективным планом
|
||||
- **WHEN** пользователь выбирает «Применить»
|
||||
- **THEN** создаются хардлинки по плану, задача переходит к раскладке
|
||||
|
||||
#### Scenario: Отклонить и привязать заново
|
||||
|
||||
- **GIVEN** загрузка в `review`
|
||||
- **WHEN** пользователь «Отклонить», затем «Привязать заново»
|
||||
- **THEN** задача уходит в `cancelled`, а затем снова на распознавание с ручным
|
||||
подтверждением (авто-раскладка не делается)
|
||||
|
||||
#### Scenario: Тип не переключается кнопкой
|
||||
|
||||
- **GIVEN** загрузка в `review` с распознанным типом
|
||||
- **WHEN** пользователь открывает экран ревью
|
||||
- **THEN** отдельной команды/кнопки переключения movie↔series на экране нет
|
||||
- **AND** тип показан read-only в инфо-части выбранного источника
|
||||
|
||||
#### Scenario: Недокачанный источник отклоняет перераспознавание
|
||||
|
||||
- **GIVEN** загрузка припаркована в `deferred`, а её раздача в qBittorrent ещё
|
||||
качается (`downloading`, файлы не докачаны)
|
||||
- **WHEN** пользователь выбирает «Распознать заново» (или «Уточнить»/«Привязать
|
||||
заново»/фиксацию типа)
|
||||
- **THEN** команда отклоняется с конфликтом и причиной «торрент ещё качается»
|
||||
- **AND** загрузка остаётся в `deferred`, хардлинки не создаются, авто-раскладка
|
||||
не запускается
|
||||
|
||||
#### Scenario: Недокачанный источник отклоняет ручное применение
|
||||
|
||||
- **GIVEN** загрузка в `review`, чья раздача в qBittorrent ещё качается
|
||||
- **WHEN** пользователь выбирает «Применить»
|
||||
- **THEN** команда отклоняется с конфликтом «торрент ещё качается», хардлинки
|
||||
на неполные файлы не создаются, состояние загрузки не меняется
|
||||
Reference in New Issue
Block a user