Команды ревью проверяли только наличие раздачи в 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>
16 lines
1.1 KiB
Go
16 lines
1.1 KiB
Go
package worker
|
|
|
|
import "errors"
|
|
|
|
// ErrConflict — операция недопустима в текущем состоянии загрузки (напр. apply
|
|
// вне review/deferred, undo вне done). Это нормальный конфликт состояния, а не
|
|
// сбой сервера: транспорт матчит его через errors.Is и отвечает 409, не 500.
|
|
var ErrConflict = errors.New("conflict")
|
|
|
|
// ErrNotReady — источник (раздача) присутствует в qBittorrent, но ещё не
|
|
// докачан (не в классе classReady), поэтому команда, ведущая к распознаванию
|
|
// или раскладке, отклонена: хардлинки на неполные файлы недопустимы. Отдельно
|
|
// от ErrConflict (тоже 409), потому что причина actionable — «дождись докачки»
|
|
// — и транспорт показывает её конкретным текстом, а не генериком конфликта.
|
|
var ErrNotReady = errors.New("source not ready")
|