{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "arm-ka/recognition-result-message/v1", "title": "Сообщение результата распознавания (tabular-parser / scan-gateway → arm-core), контракт v1.0", "description": "Тело сообщения на subject recognition.result. Заголовок Nats-Msg-Id (не поле тела) на этом subject имеет две формы: ack:: — для status = processing; result:: — для done, needs_check и error. Форма запроса : описана в схеме recognition-request. status = processing — ack «взял в работу», публикуется до чтения файла из S3. group_schema в конверт не входит: источник — файл результата (recognition-result).", "$comment": "Версионирование: schema_version = MAJOR.MINOR. MINOR (1.1) — необязательные поля и новые значения enum; MAJOR (2.0) — удаление/переименование полей, смена типов или семантики. Потребитель принимает тот же MAJOR и любой MINOR. Новый MINOR раскатывается сначала на потребителей (ядро и сервисы обновляют копии схем раньше, чем производитель начнёт слать 1.1), потому что закрытые enum отвергают незнакомые значения.", "type": "object", "required": ["schema_version", "job_id", "file_id", "status", "service"], "properties": { "schema_version": { "type": "string", "pattern": "^1\\.\\d+$", "description": "MAJOR.MINOR; производитель контракта v1.0 пишет \"1.0\"" }, "job_id": { "type": "string", "format": "uuid", "description": "recognition_job.id" }, "file_id": { "type": "string", "format": "uuid", "description": "stored_file.id" }, "status": { "enum": ["processing", "done", "needs_check", "error"] }, "service": { "type": "object", "required": ["name", "version"], "properties": { "name": { "enum": ["tabular-parser", "scan-gateway"] }, "version": { "type": "string" } } }, "result_s3": { "type": "object", "description": "файл результата (recognition-result): results/{file_id}/{job_id}/result.json", "required": ["bucket", "key"], "properties": { "bucket": { "type": "string", "minLength": 1 }, "key": { "type": "string", "minLength": 1 } } }, "result_schema_version": { "type": "string", "pattern": "^\\d+\\.\\d+$", "description": "schema_version файла результата, MAJOR.MINOR" }, "error": { "type": "object", "required": ["code", "message"], "properties": { "code": { "enum": ["UNSUPPORTED_FORMAT", "UNREADABLE", "TIMEOUT", "SCHEMA_MISMATCH", "NOT_IMPLEMENTED", "FILE_READ_ERROR", "INVALID_FORMAT", "INVALID_DOCUMENT", "RECOGNITION_FAILED", "UNKNOWN_ERROR"] }, "message": { "type": "string" } } }, "raw_s3_key": { "type": ["string", "null"], "description": "scan-gateway: raw/{job_id}.json — сырой ответ ИС Сканирование; в БД не регистрируется" }, "metrics": { "type": "object", "properties": { "duration_ms": { "type": "integer" }, "pages": { "type": "integer" }, "rows": { "type": "integer" }, "fields_total": { "type": "integer" }, "fields_low_confidence": { "type": "integer" }, "fields_unrecognized": { "type": "integer" }, "warnings": { "type": "array", "items": { "type": "string" } } } } }, "allOf": [ { "if": { "properties": { "status": { "enum": ["done", "needs_check"] } }, "required": ["status"] }, "then": { "required": ["result_s3", "result_schema_version"] } }, { "if": { "properties": { "status": { "const": "error" } }, "required": ["status"] }, "then": { "required": ["error"] } } ] }