Andrey Epifancev 98f00c0faa docs: change retry-recognition-and-edit-osv-header, README и CLAUDE.md — DBML v5.21 (ревью #161)
Дельта data-model переименована на v5.21, пакет — только файлы в ERROR,
tasks — ссылки на docs PR #157 и задачи ревью; config.yaml — DBML v5.21.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 17:13:41 +04:00

6.6 KiB
Raw Blame History

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 с consolidation_id консолидации версии и ЮЛ из периметра версии; файлы других статусов в пакет не входят и не блокируются. Для каждого допустимого файла SHALL создаваться новая попытка. Успех — 202 с accepted[{file_id, job_id, attempt}] и skipped[{file_id, code}], где skipped — рассмотренные файлы, которые повторить нельзя (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