## 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** команда отклоняется с конфликтом «торрент ещё качается», хардлинки
  на неполные файлы не создаются, состояние загрузки не меняется
