6.4 KiB
ADDED Requirements
Requirement: Ручной повтор обработки файла
POST /api/v1/files/{file_id}/retry SHALL требовать DOCUMENT_EDIT и видимость ЮЛ. Повтор разрешён для
текущего задания tabular в timeout/TIMEOUT или dlq/NO_ACK при attempt < max_attempts, отсутствии документов
и файле ERROR. Успех SHALL вернуть 202 с карточкой файла и новым текущим заданием. Несуществующий или чужой файл — 404.
Scenario: После таймаута
- WHEN табличный файл ОСВ РБ завершился timeout/TIMEOUT, attempt = 1, max_attempts = 3
- THEN 202, создано новое задание attempt = 2, прежнее осталось, в карточке новое текущее задание
Scenario: Неподходящее состояние
- WHEN повтор запрошен для OCR, done, needs_check, error сервиса, ошибки маппинга либо файла с документами
- THEN 409 FILE_NOT_RETRYABLE без нового задания и аудита
Scenario: Лимит исчерпан
- WHEN подходящее задание имеет attempt = max_attempts
- THEN 409 MAX_ATTEMPTS_REACHED, состояние не меняется
Requirement: Пакет повторной обработки версии
POST /api/v1/consolidations/versions/{version_id}/files/retry SHALL выбирать видимые ERROR-файлы
консолидации по периметру версии. Другие статусы не входят в пакет и не блокируются.
Ответ — 202 с accepted[{file_id, job_id, attempt}] и skipped[{file_id, code}]. В skipped SHALL входить
только ERROR-файлы, которые нельзя повторить (FILE_NOT_RETRYABLE, MAX_ATTEMPTS_REACHED).
Файлы без контекста консолидации MUST NOT включаться по совпадению ЮЛ.
Scenario: Смешанный пакет
- WHEN у версии есть файл timeout/TIMEOUT, OCR, успешный файл и файл с исчерпанным лимитом
- THEN новый job создаётся только для первого; OCR-файл в skipped с
FILE_NOT_RETRYABLE, файл с исчерпанным лимитом — сMAX_ATTEMPTS_REACHED; успешный (PROCESSED) файл не попадает ни в accepted, ни в skipped
Scenario: Периметр и контекст
- WHEN файл загружен в другую консолидацию либо его ЮЛ не входит в выбранную версию
- THEN файл не участвует ни в accepted, ни в skipped этой версии
Scenario: Общие файлы разных версий
- WHEN две версии одной консолидации содержат одно ЮЛ и вызывают пакетный повтор
- THEN они используют общий набор файлов консолидации; уже повторяемый файл второй раз не запускается
Scenario: Пустой пакет
- WHEN подходящих файлов нет
- THEN 202 с пустым accepted; в skipped — только файлы в
ERROR, которые повторить нельзя (без них список пуст); аудита повторов нет
Requirement: Ограничения версии при повторе
Повтор в контексте версии SHALL разрешаться только для версий «в работе» (INITIATED, DOCUMENTS_PROCESSING, DATA_CORRECTION). Иначе SHALL возвращаться 409 VERSION_NOT_EDITABLE. consolidation_lock MUST NOT требоваться. Одиночный повтор файла с consolidation_id SHALL требовать наличия версии «в работе» с ЮЛ файла в периметре; без consolidation_id SHALL применяться только policy ЮЛ. Повтор MUST NOT изменять статусы версий.
Scenario: Проверенная версия
- WHEN пакет запрошен для VERIFIED
- THEN 409 VERSION_NOT_EDITABLE, ни один файл не изменён
Scenario: Консолидация уже закрыта для обработки
- WHEN одиночный повтор файла консолидации запрошен без версии «в работе» с его ЮЛ
- THEN 409 VERSION_NOT_EDITABLE; другая версия консолидации не открывает недоступный пакет версии
Scenario: Сохранение статуса
- WHEN пакет допустимой версии INITIATED принят без пользовательской блокировки
- THEN попытки созданы, INITIATED сохраняется; дальнейшие переходы происходят по существующим событиям
MODIFIED Requirements
Requirement: Жизненный цикл статуса файла
stored_file.status SHALL меняться только по заданию current_recognition_job_id: UPLOADED при загрузке и при принятом ручном повторе с новым текущим заданием;
PROCESSING при ack сервиса; ERROR при финальной ошибке задания (error, timeout, dlq) и при невозможности
маппинга; PROCESSED после успешного маппинга; SUPERSEDED при автозамене. Карточка файла SHALL показывать причину
ERROR (error_code/error_message задания или ошибку маппинга).
Scenario: Парсер вернул ошибку
- WHEN конверт
error UNSUPPORTED_FORMATдля задания файла - THEN
stored_file.status = ERROR, в карточке файлаerror_code = UNSUPPORTED_FORMAT
Scenario: Сервис не ответил
- WHEN задание переведено вахтёром в
timeout - THEN файл —
ERRORсerror_code = TIMEOUT