arm-tabular-parser/api/contracts/recognition-result.schema.json
Andrey Epifancev f8a584af15 chore: копии схем контракта v1.0 и примеров в api/contracts
Скопировано из ../docs/contracts байт в байт (cp, diff -r чистый).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 02:38:17 +04:00

198 lines
9.9 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "arm-ka/recognition-result/v1",
"title": "Результат распознавания файла (tabular-parser / scan-gateway), контракт v1.0",
"description": "Один файл (stored_file) → один job → N документов. Сервисы не знают БД: только структура файла. Нормализация счетов, резолв контрагентов, проверки — в arm-core.",
"$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", "service", "status", "documents"],
"properties": {
"schema_version": { "type": "string", "pattern": "^1\\.\\d+$", "description": "MAJOR.MINOR; производитель контракта v1.0 пишет \"1.0\"" },
"job_id": { "type": "string", "format": "uuid" },
"file_id": { "type": "string", "format": "uuid" },
"service": {
"type": "object",
"required": ["name", "version"],
"properties": {
"name": { "enum": ["tabular-parser", "scan-gateway"] },
"version": { "type": "string" }
}
},
"status": { "enum": ["done", "needs_check", "error"] },
"error": {
"type": ["object", "null"],
"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" }
}
},
"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" } }
}
},
"raw_s3_key": { "type": ["string", "null"], "description": "scan-gateway: raw/{job_id}.json — сырой ответ ИС Сканирование; в БД не регистрируется" },
"documents": {
"type": "array",
"items": { "oneOf": [ { "$ref": "#/$defs/osvDocument" }, { "$ref": "#/$defs/statementDocument" } ] }
}
},
"if": {
"properties": { "status": { "enum": ["done", "needs_check"] } },
"required": ["status"]
},
"then": {
"properties": { "documents": { "minItems": 1 } }
},
"$defs": {
"money": { "type": ["string", "null"], "pattern": "^-?\\d+(\\.\\d{1,2})?$", "description": "Decimal как строка, чтобы не терять копейки в JSON" },
"osvDocument": {
"type": "object",
"required": ["document_type", "locator", "header", "group_schema", "rows"],
"properties": {
"document_type": { "const": "OSV" },
"locator": { "type": "string", "examples": ["sheet:Лист_1"] },
"header": {
"type": "object",
"required": ["organization_name", "account_code_raw", "period_text"],
"properties": {
"organization_name": { "type": "string", "description": "как в r1 файла" },
"organization_inn": { "type": ["string", "null"] },
"account_code_raw": { "type": "string", "examples": ["60", "58.03"] },
"period_text": { "type": "string", "examples": ["1 квартал 2025 г.", "2024 г."] },
"period_year": { "type": ["integer", "null"] },
"period_quarter": { "enum": ["Q1", "Q2", "Q3", "Q4", null] },
"is_cumulative": { "type": ["boolean", "null"], "description": "по тексту; ядро может переопределить по данным (OQ-02)" },
"data_type": { "enum": ["BU", "NU", "SUM", "CURRENCY", "QUANTITY", null] },
"currency": { "type": ["string", "null"], "examples": ["RUB", "руб."] },
"header_variant": { "enum": [1, 2] }
}
},
"group_schema": {
"type": "array",
"description": "порядок группировок из шапки, после первого ACCOUNT",
"items": {
"type": "object",
"required": ["type"],
"properties": {
"type": { "enum": ["ACCOUNT", "DEPARTMENT", "COUNTERPARTY", "CONTRACT", "OTHER"] },
"name": { "type": "string", "description": "исходный текст из шапки" },
"has_inn": { "type": "boolean" }
}
}
},
"columns": {
"type": "object",
"description": "диагностика: какие колонки листа были приняты за шесть сумм и ИНН",
"additionalProperties": { "type": "string" }
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": ["row_number", "level", "row_value", "group_type"],
"properties": {
"row_number": { "type": "integer" },
"level": { "type": "integer" },
"parent_row_number": { "type": ["integer", "null"] },
"row_value": { "type": "string" },
"group_type": { "enum": ["ACCOUNT", "DEPARTMENT", "COUNTERPARTY", "CONTRACT", "OTHER", "TOTAL"] },
"group_name": { "type": ["string", "null"] },
"account_code_raw": { "type": ["string", "null"], "description": "код текущей ветки, как в файле (60.1)" },
"counterparty_name": { "type": ["string", "null"] },
"counterparty_inn": { "type": ["string", "null"] },
"data_type": { "enum": ["BU", "NU", "SUM", "CURRENCY", "QUANTITY", null] },
"opening_debit": { "$ref": "#/$defs/money" },
"opening_credit": { "$ref": "#/$defs/money" },
"turnover_debit": { "$ref": "#/$defs/money" },
"turnover_credit": { "$ref": "#/$defs/money" },
"closing_debit": { "$ref": "#/$defs/money" },
"closing_credit": { "$ref": "#/$defs/money" }
}
}
},
"checks": {
"type": "object",
"properties": {
"total_row_matches_root": { "type": "boolean" },
"balance_identity_violations": { "type": "array", "items": { "type": "integer" }, "description": "row_number строк, где opening−turnover≠closing" },
"parent_sum_violations": { "type": "array", "items": { "type": "integer" } }
}
}
}
},
"statementDocument": {
"type": "object",
"required": ["document_type", "locator", "header", "columns", "lines"],
"properties": {
"document_type": { "enum": ["BALANCE", "INCOME", "OTHER"] },
"locator": { "type": "string", "examples": ["pages:1-2"] },
"header": {
"type": "object",
"properties": {
"form_name": { "type": "string" },
"organization_name": { "type": ["string", "null"] },
"organization_name_confidence": { "type": ["number", "null"], "minimum": 0, "maximum": 100 },
"inn": { "type": ["string", "null"] },
"inn_confidence": { "type": ["number", "null"], "minimum": 0, "maximum": 100 },
"report_date_text": { "type": ["string", "null"] },
"report_date": { "type": ["string", "null"], "format": "date" },
"units": { "type": ["string", "null"], "examples": ["тыс. руб."] },
"okud": { "type": ["string", "null"] },
"okpo": { "type": ["string", "null"] },
"okopf": { "type": ["string", "null"] },
"okfs": { "type": ["string", "null"] },
"address": { "type": ["string", "null"] }
}
},
"columns": {
"type": "array",
"items": {
"type": "object",
"required": ["column_index", "label"],
"properties": {
"column_index": { "type": "integer" },
"label": { "type": "string", "examples": ["На 30 сентября 2025 г."] },
"period_date": { "type": ["string", "null"], "format": "date" }
}
}
},
"lines": {
"type": "array",
"items": {
"type": "object",
"required": ["line_code", "line_name", "values"],
"properties": {
"line_code": { "type": "string" },
"line_code_confidence": { "type": ["number", "null"], "minimum": 0, "maximum": 100 },
"line_name": { "type": "string" },
"line_name_confidence": { "type": ["number", "null"], "minimum": 0, "maximum": 100 },
"values": {
"type": "array",
"items": {
"type": "object",
"required": ["column_index"],
"properties": {
"column_index": { "type": "integer" },
"amount": { "$ref": "#/$defs/money" },
"string_value": { "type": ["string", "null"] },
"confidence": { "type": ["number", "null"], "minimum": 0, "maximum": 100 },
"is_recognized": { "type": "boolean" }
}
}
}
}
}
}
}
}
}
}