Архив change quality-metrics (AURORA-1759, #203) #212

Merged
aep merged 1 commits from chore/archive-quality-metrics into main 2026-11-07 07:52:13 +03:00
4 changed files with 62 additions and 0 deletions

View File

@ -0,0 +1,62 @@
# quality-metrics-model Specification
## Purpose
Модель данных и контракт фактов качества распознавания первички (AURORA-1759): какие факты пишутся, в каком
формате, как они переживают удаление/перераспознавание документа и чем отличаются от рабочих таблиц. Алгоритм
подсчёта и атрибуции — `context/05-domain-rules.md` §14 (не дублируется здесь).
## Requirements
### Requirement: Факты качества — append-only и без FK на рабочие таблицы
`quality_intake_fact`, `quality_outcome_fact`, `quality_failure_fact` SHALL не иметь внешних ключей на `document`,
`stored_file`, `recognition_job`, `legal_entity`, `company_group` — только простые `uuid` и денормализованные имена
ЮЛ/ГК. Факты SHALL жить в отдельной схеме PostgreSQL (имя — настройка, по умолчанию `dkb_metrics`).
#### Scenario: Документ удалён после записи факта
- **WHEN** документ, по которому есть `quality_intake_fact`, физически удалён (`primary_files.delete`)
- **THEN** строка факта остаётся читаемой, её `document_id` не разрешается в существующий `document`, и запрос к
факту не падает на отсутствующем FK
### Requirement: `quality_intake_fact` — один факт на документ, кроме ОСВ без построчного снимка
Таблица SHALL иметь ровно один факт на `document_id` (`unique`). Для `document_type = OSV` `payload` SHALL не
содержать `lines`/`values` — только счётчики строк и предупреждения `OSV_*`; для `BALANCE`/`INCOME` `payload` SHALL
содержать построчный снимок (`lines`, `values`).
#### Scenario: Приём результата ОСВ
- **WHEN** ядро мапит результат распознавания ОСВ в документ `OSV`
- **THEN** `quality_intake_fact.payload` не содержит ключей `lines`/`values`, но содержит `osv_warnings`
#### Scenario: Приём результата ББ
- **WHEN** ядро мапит результат распознавания в документ `BALANCE`
- **THEN** `quality_intake_fact.payload` содержит `lines` и `values` построчно
### Requirement: `quality_outcome_fact` — не unique на документ, метрики берут последний факт
Таблица SHALL допускать несколько строк с одним `document_id` (повторное подтверждение ОСВ после правки,
исход `*_AFTER_CONFIRM` поверх прежнего). Любой читатель метрик SHALL использовать факт с максимальным `outcome_at`
для данного `document_id`.
#### Scenario: Документ удалён после подтверждения
- **WHEN** подтверждённый документ впоследствии удалён или вытеснен автозаменой
- **THEN** пишется новый факт с `outcome ∈ {DELETED_AFTER_CONFIRM, SUPERSEDED_AFTER_CONFIRM}`, прежний факт
(`CONFIRMED`/`AUTO_CONFIRMED`) не удаляется и не перезаписывается
### Requirement: Сырой ответ ИС Сканирование регистрируется и не экспирится с файлом
`s3_object` SHALL поддерживать роль бакета `raw`; `recognition_job.raw_s3_object_id` SHALL ссылаться на
зарегистрированный объект для image pipeline. Удаление `stored_file` SHALL НЕ устанавливать `expires_at` ни объекту
с ролью `raw`, ни объекту `uploads`, на который ссылается `quality_intake_fact` (`upload_s3_key`) — оба нужны
эталонному прогону (OQ-179). Объекты `results` и прочие `uploads` (без факта) — без изменений, `expires_at = now()`
при удалении файла, как и раньше.
#### Scenario: Удаление файла с зарегистрированным сырым ответом
- **WHEN** PDF-файл с заполненным `recognition_job.raw_s3_object_id` и существующим `quality_intake_fact` удаляется
- **THEN** `s3_object.expires_at` остаётся `NULL` у объекта роли `raw` и у объекта `uploads`, на который ссылается
факт; у объекта `results` того же файла `expires_at` проставляется `now()`, как для любого удаления
того же файла
### Requirement: Контракт payload не входит в `make check` этого репозитория
`contracts/metrics/quality-facts.schema.json` SHALL существовать как валидная JSON Schema (Draft 2020-12), но SHALL NOT
быть подключена к `scripts/validate_contracts.py` — payload не является сообщением NATS-контракта распознавания.
#### Scenario: `make check` в arm-ka-docs
- **WHEN** выполняется `make check` в этом репозитории
- **THEN** `quality-facts.schema.json` не упоминается в выводе `validate-contracts`, и это не считается ошибкой