# Контракты FileWorker ## NATS: ARMKA → FileWorker Subject: `files.tabular_uploaded`. Формат: JSON в UTF-8. ```json { "task_id": "c609e0d2-f5c4-4a78-b6dc-686a280a2c21", "file_id": "5e92bc4f-d919-487c-aed4-c293de5c8c96", "source_s3_key": "uploads/report.pdf", "expires_at": "2026-10-06T15:00:00Z" } ``` Все поля обязательны. `task_id` — UUID задачи (`RecognitionJob.id`), `file_id` — UUID исходного файла. `source_s3_key` — ключ объекта внутри настроенного бакета MinIO, с расширением, без URL и начального `/`. `expires_at` — срок задачи в ISO 8601 с часовым поясом. Все расширения используют этот subject; `document_type` не передаётся. ## NATS: FileWorker → ARMKA Subject: `files.tabular_parsed`. Формат: JSON в UTF-8. ```json { "task_id": "c609e0d2-f5c4-4a78-b6dc-686a280a2c21", "file_id": "5e92bc4f-d919-487c-aed4-c293de5c8c96", "status": "ready", "result_s3_key": "FileWorker/results/c609e0d2-f5c4-4a78-b6dc-686a280a2c21.json", "error_code": null, "finished_at": "2026-10-06T14:30:00Z" } ``` `task_id` и `file_id` совпадают с командой. Они, `status` и `finished_at` обязательны. `finished_at` — ISO 8601 с часовым поясом. | status | result_s3_key | error_code | |---|---|---| | `ready` | Ключ результата в MinIO | `null` или отсутствует | | `timeout` | `null` или отсутствует | `deadline_exceeded` | | `error` | `null` или отсутствует | `source_not_found`, `invalid_source_json` или `storage_unavailable` | `storage_unavailable` допустим по схеме, но сейчас ошибки хранилища повторяются внутри FileWorker и не публикуются с этим кодом. В обоих сообщениях дополнительные поля запрещены, ключи MinIO имеют длину 1–1024 символа. Core NATS не сохраняет сообщения для отсутствующих подписчиков; `flush()` не подтверждает обработку сообщения ARMKA. ## Файлы Все SMB-пути ниже относительны к `SMB_PATH`. | Направление | Путь и формат | |---|---| | FileWorker → распознаватель | `Input/.<расширение>` — исходный файл | | Распознаватель → FileWorker | `Output//*.json` — JSON-результаты | | FileWorker → MinIO | `/.json`, по умолчанию `FileWorker/results/.json` | Распознаватель игнорирует `.tmp`. JSON-результаты одной задачи появляются полным батчем и больше не изменяются. Пустая или отсутствующая папка означает ожидание. В итоговом JSON каждый исходный JSON становится элементом `files`, в порядке имён без учёта регистра: ```json { "task_id": "c609e0d2-f5c4-4a78-b6dc-686a280a2c21", "job_id": "c609e0d2-f5c4-4a78-b6dc-686a280a2c21", "file_id": "5e92bc4f-d919-487c-aed4-c293de5c8c96", "files": [{"example": "содержимое JSON распознавателя"}] } ``` ## HTTP Префикс `ROOT_PATH` по умолчанию: `/aurora/apps/fastapi-dkb-armka-pdf-worker`. | Метод и путь | Ответ | |---|---| | `GET /healthcheck` | `200 {"status":"ok"}`; `503`, если NATS или обработчик недоступен | | `GET /tasks/active` | `200 {"tasks":[...]}`; `503`, если экземпляр FileService недоступен | Элемент `tasks`: `task_id`, `file_id`, `source_s3_key`, `status`. Статусы: `received`, `checking_result`, `checking_smb`, `reading_source`, `sending_to_smb`, `discovering_result`, `waiting_for_result`, `merging_result`, `reading_result`, `uploading_result`, `cleaning_smb`, `publishing_result`, `retrying_storage`, `retrying_publish`. При сбое добавляется `last_error`: `stage`, `type`, `message`, `location`, `occurred_at`. Последняя ошибка сохраняется между попытками. Список относится к текущему процессу, очищается при перезапуске; завершённые задачи из него удаляются.