Files
jellybit/openspec/changes/archive/2026-07-08-review-readiness-preflight/tasks.md
T
avandClaude Opus 4.8 b1bca98738 Ревью: 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>
2026-07-08 16:40:49 +03:00

46 lines
3.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.
## 1. Preflight готовности источника
- [x] 1.1 В `internal/worker/errors.go` добавить sentinel
`var ErrNotReady = errors.New(...)` (отдельный от `ErrConflict`).
- [x] 1.2 В `internal/worker/reconcile.go` добавить `ensureSourceReady(ctx, d, op)`:
найти торрент через `torrentByInfohash`; нет источника →
`reconcileToReality(false)` + `ErrConflict «источник удалён из qBittorrent»`;
есть, но `classify(t.State) != classReady``ErrNotReady «op: торрент ещё
качается»` без `reconcileToReality`.
- [x] 1.3 Заменить `ensureSourcePresent` на `ensureSourceReady` в командах
`Rerecognize`, `Refine`, `SetType`, `Relink` (`internal/worker/review.go`);
удалить осиротевший `ensureSourcePresent`.
- [x] 1.4 В `Apply` добавить проверку класса на уже полученном торренте
(`classify(t.State) != classReady → ErrNotReady «торрент ещё качается»`),
без второго запроса к qBittorrent.
## 2. Трансляция ошибки в транспортах
- [x] 2.1 `internal/httpapi` `classifyErr`: кейс
`errors.Is(err, worker.ErrNotReady) → 409, «торрент ещё качается, дождитесь
докачки»` (отдельно от генерик-`ErrConflict`).
- [x] 2.2 `internal/tgbot`: в обработчике callback-действий ветка
`errors.Is(err, worker.ErrNotReady)` → сообщение «Торрент ещё качается…»,
иначе прежний `opErr(...)`.
## 3. Тесты
- [x] 3.1 Тест: недокачанный источник (`downloading`-класс) отклоняет
`Rerecognize`/`Refine`/`SetType`/`Relink` с `ErrNotReady`, состояние задачи
не меняется, авто-раскладка не запускается.
- [x] 3.2 Тест: недокачанный источник отклоняет `Apply` — хардлинки не
создаются, состояние не меняется.
- [x] 3.3 Тест: готовый источник (`classReady`) пропускает те же команды как
раньше (регресс не сломан); отсутствие источника по-прежнему приводит к
реальности и отказывает.
- [x] 3.4 Тест транспорта: `classifyErr(ErrNotReady) == 409` с конкретным
текстом (`internal/httpapi`).
## 4. Ревью и сверка
- [x] 4.1 `task test` и `task lint` зелёные.
- [x] 4.2 Ревью кода (второй чекпоинт) перед archive.
- [x] 4.3 `openspec validate review-readiness-preflight --strict` зелёный;
удалить `docs/backlog/review-major5-readiness-preflight.md` из беклога и
строку из индекса (суть переехала в спеку).