{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "arm-ka/quality-facts/v1", "title": "Payload фактов качества распознавания первички (AURORA-1759)", "description": "Структура jsonb-столбца payload таблиц quality_intake_fact и quality_outcome_fact (model/data-model-v5.25.dbml, context/05-domain-rules.md §14). quality_failure_fact не описан здесь — у него нет payload, все поля плоские. НЕ валидируется make check / scripts/validate_contracts.py: этот скрипт жёстко завязан на три сообщения NATS-контракта распознавания (request-/result-message-/result- примеры с дедупом и версией сообщения); payload фактов не ходит по NATS и не требует той же идемпотентности. Схему проверяет тест в arm-core, где payload формируется (см. openspec/changes/quality-metrics/design.md §2 этого репозитория).", "$defs": { "intake-payload": { "type": "object", "description": "Снимок документа на момент приёма результата (до подтверждения). Для OSV — без lines/values, только osv_warnings.", "properties": { "header": { "type": "object", "description": "header_source и распознанные поля шапки (period, inn, units, organization_name, …)", "additionalProperties": true }, "lines": { "type": "array", "description": "Отсутствует для document_type = OSV", "items": { "type": "object", "required": ["ref", "line_status"], "properties": { "ref": { "type": "string" }, "row_index": { "type": ["integer", "null"] }, "line_code": { "type": ["string", "null"] }, "line_code_text": { "type": ["string", "null"] }, "line_status": { "enum": ["ok", "unreadable", "missing", "detail"] }, "needs_review": { "type": "boolean" } } } }, "values": { "type": "array", "description": "Отсутствует для document_type = OSV", "items": { "type": "object", "required": ["line_ref", "column"], "properties": { "line_ref": { "type": "string" }, "column": { "type": "string" }, "amount": { "type": ["number", "null"] }, "string_value": { "type": ["string", "null"] }, "source_text": { "type": ["string", "null"] }, "confidence": { "type": ["number", "null"] }, "is_recognized": { "type": "boolean" }, "needs_review": { "type": "boolean" } } } }, "issues": { "type": "array", "items": { "type": "object", "required": ["code"], "properties": { "code": { "type": "string" }, "level": { "enum": ["relation", "soft", "warning", "info"] } } } }, "raw_line_codes": { "type": "array", "description": "Только PDF: четырёхзначные токены сырого ответа ИС, стоящие отдельной строкой — вход для §14.2 (добавленная строка)", "items": { "type": "string", "pattern": "^\\d{4}$" } }, "osv_warnings": { "type": "array", "description": "Только для document_type = OSV, вместо lines/values", "items": { "type": "string" } } } }, "outcome-payload": { "type": "object", "description": "Подтверждённое состояние (то же строение header/lines/values, что и intake-payload) плюс список правок", "properties": { "header": { "$ref": "#/$defs/intake-payload/properties/header" }, "lines": { "$ref": "#/$defs/intake-payload/properties/lines" }, "values": { "$ref": "#/$defs/intake-payload/properties/values" }, "fixes": { "type": "array", "items": { "type": "object", "required": ["field", "after", "source", "rule"], "properties": { "field": { "enum": ["value", "code", "added_row", "header", "osv_period_account"] }, "before_raw": { "type": ["string", "null"], "description": "сырой текст сервиса на этом поле, если был" }, "before_recognized": { "description": "как было распознано до правки" }, "after": { "description": "подтверждённое значение" }, "source": { "enum": ["service", "ours"], "description": "§14.2 — только два источника правки" }, "rule": { "type": "string", "description": "строка таблицы §14.2, которая сработала" } } } } } } }, "$comment": "Корневая схема не инстанцируется напрямую: тест в arm-core валидирует quality_intake_fact.payload против #/$defs/intake-payload и quality_outcome_fact.payload против #/$defs/outcome-payload (не oneOf — оба $defs допускают пустой объект, и oneOf отверг бы его как совпавший с обоими)." }