7.6 KiB
MODIFIED Requirements
Requirement: Передача файла в ИС Сканирование через горячие папки
После подтверждения сервис SHALL прочитать исходник из S3 (s3.bucket/s3.key) и записать его во входящий каталог как
<job_id>.<ext>, где <ext> — расширение original_name запроса в нижнем регистре; запрос без расширения SHALL
завершаться конвертом RECOGNITION_FAILED без записи в горячую папку. Файл SHALL записываться сразу во входящий каталог
открытием на запись с усечением, как в старом АРМ (решение владельца 09.10.2026): временных файлов, служебного каталога
и переименования нет; если <Input>/<job_id>.<ext> уже существует, он SHALL быть перезаписан содержимым объекта S3.
Затем сервис SHALL опрашивать исходящий каталог <SCAN_OUTPUT_DIR>/<job_id>/ каждые SCAN_POLL_SECONDS до
min(reply_deadline, старт + SCAN_TIMEOUT_SECONDS) (SCAN_TIMEOUT_SECONDS по умолчанию 1200). ИС кладёт в этот каталог
все распознанные документы задания — по одному *.json на документ, набор появляется целиком и больше не меняется;
пустой или отсутствующий каталог означает ожидание. Ответ SHALL считаться готовым, когда в каталоге есть хотя бы один
*.json, а набор имён и размеров *.json не менялся SCAN_SETTLE_SECONDS (по умолчанию 2); готовый набор SHALL
включать все *.json каталога по возрастанию имени, остальные файлы игнорируются.
Scenario: Файл положен во входящий каталог
- WHEN получен запрос для
aep_5.PDFсjob_id = 3f1c… - THEN во входящем каталоге появляется
3f1c….pdf, байт в байт равный объекту S3; каталогTmp/не создаётся, временных файлов нет
Scenario: Назначение уже существует
- WHEN запрос для
aep_5.pdfсjob_id = 3f1c…обрабатывается, аInput/3f1c….pdfуже лежит с другим содержимым (задание повторено ядром после потери ack в другом процессе) - THEN
Input/3f1c….pdfперезаписан и байт в байт равен объекту S3, задание продолжается опросомOutput/3f1c…/, конвертRECOGNITION_FAILEDне публикуется
Scenario: Запрос без расширения
- WHEN получен запрос с
original_name = "scan"без точки - THEN опубликован конверт
error,error.code = RECOGNITION_FAILED, сообщение о расширении; во входящем каталоге файла нет
Scenario: Ответ из одного файла
- WHEN в
Output/3f1c…/появляется один*.jsonи набор не меняетсяSCAN_SETTLE_SECONDS - THEN опрос прекращается не позднее чем через
SCAN_SETTLE_SECONDS+SCAN_POLL_SECONDSпосле первого опроса, увидевшего окончательный набор (отсчёт стабилизации — от этого опроса, а не от времени изменения файла), ответ из одного файла передаётся дальше по конвейеру
Scenario: Ответ из нескольких файлов
- WHEN в
Output/3f1c…/лежат3f1c….jsonи3f1c…_ofr.json, посторонний файлreadme.txt, и набор не меняетсяSCAN_SETTLE_SECONDS - THEN дальше по конвейеру передаются оба
*.jsonпо возрастанию имени,readme.txtигнорируется
Scenario: Набор ещё пишется
- WHEN размер файла или число файлов в
Output/3f1c…/менялось менееSCAN_SETTLE_SECONDSназад - THEN ответ не считается готовым, опрос продолжается до дедлайна
Scenario: Ошибка посреди записи
- WHEN запись
Input/3f1c….pdfпрервалась ошибкой ввода-вывода - THEN опубликован конверт
RECOGNITION_FAILED; недописанный файл удалён только приSCAN_CLEANUP=true, приfalseостаётся на месте
Requirement: Очистка горячей папки под флагом
При SCAN_CLEANUP=true после того, как готовый набор ответа прочитан и склеен в raw/{job_id}.json (независимо от
исхода нормализации), сервис SHALL удалить всё содержимое <SCAN_OUTPUT_DIR>/<job_id>/ (json-файлы ответа и любые
прочие) и сам каталог <job_id>, входящий файл <Input>/<job_id>.<ext> и его вариант <Input>/<job_id>.<ext>.done,
если они существуют. При SCAN_CLEANUP=false (по умолчанию) сервис MUST NOT удалять ничего, включая недописанный при
ошибке записи входящий файл. При TIMEOUT, FILE_READ_ERROR, RECOGNITION_FAILED записи очистка MUST NOT выполняться
(при ошибке записи и SCAN_CLEANUP=true снимается только недописанный входящий файл). Ошибка удаления SHALL быть
записана в лог одной строкой на задание и MUST NOT менять конверт, metrics.warnings и /healthcheck.
Scenario: Очистка включена
- WHEN
SCAN_CLEANUP=true, ответ на3f1c….pdfпрочитан изOutput/3f1c…/ - THEN после публикации конверта в горячей папке нет
Output/3f1c…/,Input/3f1c….pdfиInput/3f1c….pdf.done
Scenario: Очистка выключена
- WHEN
SCAN_CLEANUP=false, ответ прочитан - THEN все файлы остаются на месте, сервис ничего не удаляет и не пишет в лог о очистке (решение №27)
Scenario: Нет прав на удаление
- WHEN
SCAN_CLEANUP=true, удалениеOutput/3f1c…/3f1c….jsonзавершаетсяPermissionError - THEN конверт опубликован с тем же статусом, что и без очистки; в логе одна строка об ошибке удаления;
/healthcheck.hotfolder = ok
Scenario: Таймаут не чистит
- WHEN
SCAN_CLEANUP=true, ответ не появился до дедлайна - THEN опубликован
TIMEOUT, входящий файл и каталогOutput/<job_id>/(если есть) не тронуты