docs(#202): контракт payload фактов качества первички
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
13eec70aba
commit
2af056df22
99
contracts/quality-facts.schema.json
Normal file
99
contracts/quality-facts.schema.json
Normal file
@ -0,0 +1,99 @@
|
||||
{
|
||||
"$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 отверг бы его как совпавший с обоими)."
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user