- спеки statement-normalization, quality-checks, arm-core, recognition-contract — дельты под библиотеку - удалены sync-statements, statements-check, test-sync-statements; новая statements-orders-check в make check - снимок для контура: без шага 0a, цель install вырезается (иначе проверка «нет uv» падает) - 03-architecture, 05-domain-rules, 00-workspace-layout, dev/checks.md, contour-transfer-guide; баннеры убраны Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
70 lines
6.9 KiB
Markdown
70 lines
6.9 KiB
Markdown
## MODIFIED Requirements
|
||
|
||
### Requirement: Файл результата
|
||
Файл результата SHALL соответствовать `docs/contracts/recognition-result.schema.json` v2.0: один файл (`stored_file`)
|
||
→ один `job_id` → массив `documents` из `osvDocument` и/или `statementDocument`; денежные значения — строки
|
||
`^-?\d+(\.\d{1,2})?$`; `confidence` — 0–100. Пустой массив `documents` допустим только при `status = error`.
|
||
Предупреждение уровня файла пишется там, где документа нет (потерянный json, таблица ИС, исключение разбора таблицы,
|
||
лист «прочее»).
|
||
`service.statements_version` — версия установленной библиотеки `arm_statements` (дистрибутив
|
||
`pylib-ai-arm-statements`), которой посчитан результат (обязателен при наличии `statementDocument`); у результатов,
|
||
посчитанных до перехода на библиотеку, — хэш коммита копии общего кода. `metrics.warnings[]` — предупреждения уровня файла (структура `warning` с `locator`).
|
||
|
||
Каждый документ (и `osvDocument`, и `statementDocument`) SHALL иметь `status` (`done` | `needs_check`) и `warnings[]` —
|
||
структуры `{code, severity, message, line_refs?, column_index?, field?}` (`line_refs` — только `ref` строк из `lines[]`);
|
||
у `osvDocument` все предупреждения — `info`, `status = done`, когда контрольные суммы §1.4 листа сошлись, иначе
|
||
`needs_check`. Остальное в `osvDocument` — как в v1.2: у строки `rows[]` необязательное поле `extra` — объект «заголовок
|
||
колонки → строка или null» для колонок внутри таблицы, не сопоставленных с шестью суммами и ИНН (§1.2 «не терять»); у
|
||
шапки — `period_start`, `period_end`, `is_from_year_start`.
|
||
|
||
`statementDocument` SHALL иметь `form_variant` (`full` | `simplified` | `null`); `header` — поля `organization_name`,
|
||
`inn`, `report_date`, `units`, `okud`, `okpo`, `okopf`, `okfs`, `okei`, `address` и для каждого `<поле>_text` и
|
||
`<поле>_confidence`, плюс `needs_review_fields[]`; `columns[]` — `column_index` (номер столбца в сетке кандидата: у OCR
|
||
— `column_index` ИС, у Excel — номер столбца листа с 0), `label`, `label_confidence`,
|
||
`period_date`, `period_kind` (`absolute` | `relative:current` | `relative:prev_year_end` |
|
||
`relative:prev_prev_year_end` | `relative:prev_period` | `none`); `lines[]` — `row_index`, `ref` (у Excel `<лист>!<A1>`,
|
||
имя листа в кавычках по правилу Excel), `line_status` (`ok` |
|
||
`unreadable` | `missing` | `detail`), `line_code` (строка 4–5 цифр или `null`; `null` ⇔ статус не `ok`),
|
||
`line_code_text`, `line_code_confidence`, `line_name` (строка или `null`), `line_name_confidence`, `parent_ref` (у
|
||
`detail`), `needs_review`, `values[]` — `column_index`, `amount`, `string_value`, `text`, `confidence`,
|
||
`is_recognized`, `needs_review`. `checks` SHALL присутствовать у `BALANCE` / `INCOME` со строками и отсутствовать у
|
||
документа без строк; `relations_failed` и `soft_relations_failed` — `{column_index, relation, codes[], expected,
|
||
actual}`; `duplicate_line_codes` удалён. `document_type` — `BALANCE` | `INCOME` | `DISCLOSURE` (`OTHER` в v2.0 не
|
||
порождается: лист «прочее» — предупреждение файла `SHEET_OTHER`, документа нет; значение остаётся только в схеме 1.x и в
|
||
`document_type` ядра для документов прежних результатов); `form_variant` обязателен (`null` у `DISCLOSURE`); у документа
|
||
без строк `columns` и `lines` — пустые массивы. `ref` уникален в документе.
|
||
|
||
#### Scenario: Результат валидируется примерами
|
||
- **WHEN** CI сервиса запускает тесты контракта
|
||
- **THEN** все файлы `docs/contracts/examples/result-*.json` проходят схему файла результата v2.0, а все
|
||
`request-*.json` / `result-message-*.json` — схемы сообщений
|
||
|
||
#### Scenario: Лишняя колонка сохранена
|
||
- **WHEN** в ОСВ между ИНН и суммами есть колонка «КПП»
|
||
- **THEN** у строк контрагентов `extra = {"КПП": "<значение>"}`, файл проходит схему v2.0
|
||
|
||
#### Scenario: Форма из Excel с проверками
|
||
- **WHEN** tabular-parser разобрал книгу с балансом на двух листах, ОФР со строкой без кода под 2110 и пояснениями
|
||
(`examples/result-statement-excel.json`)
|
||
- **THEN** файл проходит схему v2.0: `BALANCE` с `locator` из двух листов, `status`, `checks` и мягким нарушением;
|
||
`INCOME` со строкой `detail` (`line_code = null`, `parent_ref`); `DISCLOSURE` с пустыми `columns`/`lines` и без `checks`
|
||
|
||
#### Scenario: Форма из OCR с сомнительными значениями
|
||
- **WHEN** scan-gateway разобрал ББ, где одна сумма собрана из грязного текста и покрыта соотношением, а одна строка
|
||
`unreadable` (`examples/result-statement-minimal.json`)
|
||
- **THEN** файл проходит схему v2.0; у покрытого значения `is_recognized = false`, `needs_review = false`, `text` —
|
||
сырой; у строки `unreadable` `line_code = null`, `line_code_text` — сырой текст; документ `needs_check`
|
||
|
||
#### Scenario: Границы периода ОСВ
|
||
- **WHEN** в шапке ОСВ период «Октябрь 2024 г. – Сентябрь 2025 г.»
|
||
- **THEN** `period_start = "2024-10-01"`, `period_end = "2025-09-30"`, `is_from_year_start = false`; документ ОСВ с
|
||
`status` и `warnings`, файл проходит схему v2.0
|
||
|
||
#### Scenario: Документ OTHER в v2.0
|
||
- **WHEN** в результате v2.0 `statementDocument` с `document_type = OTHER` или без `form_variant`
|
||
- **THEN** файл не проходит схему v2.0
|
||
|
||
#### Scenario: Строка без кода с кодом в поле
|
||
- **WHEN** у строки `line_status = unreadable` передан непустой `line_code`
|
||
- **THEN** файл не проходит схему v2.0
|