- design.md: Р-20 (законные повторы кода в перечне, синонимы в словаре имён), Р-21 (мягкое соотношение, сошедшееся точно, подтверждает неуверенное значение), Р-22 (S-1…S-25 приняты с оговорками; отмечены утверждённые владельцем); решения при доработке S-26…S-52 с ценой ошибки - statement-normalization: отдельное требование sync-statements (пути, VERSION, коды 0 / 10 / 20 / 2), словарь единиц и ОКЕИ, ref Excel с кавычками, нумерация с двойниками и пропуском, номер колонки, содержимое строки, столбец кодов у DISCLOSURE, упрощённый 2400 мягкий, Р-20 / Р-21 со сценариями, обе редакции перечня, интерфейс функции статуса, TABLE_PARSE_ERROR / SHEET_OTHER уровня файла - arm-core: признак строки правки row_index IS NULL, header_source, формы без checks (1.x и миграция) — §7 ядром в document_issue, codes / column_index, RESULT_STATUS_INCONSISTENT, синонимы и «итого по разделу», PATCH organization_name / confirmed: false / подтверждение даты, LINE_CODE_TAKEN, акцепт и подтверждения, LINES_UNRESOLVED с текстом, «того же периода», откат миграции - recognition-contract: MODIFIED «Копия контракта … идентична» — сверка по MAJOR копии, *.v1.schema.json на окне; 1.x — MAPPING_WARNING / LEGACY_WARNING; okei, column_index, пустые массивы DISCLOSURE, статус ОСВ одной формулировкой - quality-checks (новая дельта): make check охватывает копию arm_statements, make check-full — statements-check - tabular-recognition-service: манифест statements_manifest.yaml — failed_relations страниц 2 баланса (K-25) - scan-gateway, arm-web: TABLE_PARSE_ERROR файла; подсказки шапки, снятие подтверждений, LINE_CODE_TAKEN - proposal: шаг 0 выкладки, перечни кодов, ожидания на реальных сканах, Impact Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
47 lines
4.9 KiB
Markdown
47 lines
4.9 KiB
Markdown
## ADDED Requirements
|
||
|
||
### Requirement: Адаптер json ИС шага 1
|
||
scan-gateway SHALL оставить у себя обмен с ИС Сканирование (горячие папки, опрос, срок, склейку набора json в
|
||
`raw/{job_id}.json` до нормализации, очистку папки) и адаптер «таблица `table_structure[i]` json → `FormCandidate`»;
|
||
шаги 2–8 SHALL выполняться копией пакета `arm_statements`. Адаптер SHALL: создавать кандидата на каждую таблицу каждого
|
||
успешного json; копировать шапку json (`organization`, `inn`, `units`, `date`) в шапку каждой своей таблицы как `Cell`
|
||
(`text = form_name`, `confidence` ИС); передавать `label.form_name` таблицы как заголовок в `evidence` (тип — общим
|
||
правилом шага 1 по словарю заголовков, `statement_labels.yaml` уходит в словарь пакета); строить плотную сетку по
|
||
`row_index` и `column_index` ИС (пустые позиции — `null`), `Cell.ref = row:<row_index>`; `locator =
|
||
file:<имя json>;table:<i>`. `value` у OCR-ячеек всегда `null`.
|
||
|
||
#### Scenario: Один json — ББ и ОФР
|
||
- **WHEN** json `aep_3.json` содержит две таблицы — «Бухгалтерский баланс» и «Отчет о финансовых результатах» — под
|
||
общей шапкой
|
||
- **THEN** два кандидата с `locator` `file:aep_3.json;table:0` и `…;table:1`, у каждого копия шапки json
|
||
|
||
### Requirement: Ошибки набора json
|
||
Ошибочный json набора (`parse_error`, непустой `error.code`, корень не объект) при хотя бы одном успешном соседе SHALL
|
||
давать предупреждение файла `JSON_FAILED` (`error`, `locator = file:<имя json>`, в `message` — код и сообщение ИС);
|
||
все json ошибочны — конверт `error` с кодом первого. Исключение при разборе таблицы — предупреждение **файла**
|
||
`TABLE_PARSE_ERROR` (`error`, `locator = file:<имя json>;table:<i>`; документа у таблицы нет), остальные таблицы
|
||
разбираются; ни одной таблицы не разобрано — `error RECOGNITION_FAILED`.
|
||
|
||
#### Scenario: Таблица упала при разборе
|
||
- **WHEN** разбор `table:1` json `aep_3.json` бросил исключение, `table:0` разобрана
|
||
- **THEN** документ `BALANCE` из `table:0`; в `metrics.warnings` — `TABLE_PARSE_ERROR` уровня `error` с `locator =
|
||
"file:aep_3.json;table:1"`; конверт `needs_check`; ядро не автоподтверждает документы файла
|
||
|
||
#### Scenario: Потерянный ОФР (решение № 28 среза 3a)
|
||
- **WHEN** `<job_id>.json` успешен (ББ), а `<job_id>_ofr.json` вернул `INVALID_DOCUMENT`
|
||
- **THEN** документ ББ получает свой статус; в `metrics.warnings` — `JSON_FAILED` уровня `error`; конверт
|
||
`needs_check`; ядро не автоподтверждает документы файла
|
||
|
||
### Requirement: Что уходит из шлюза
|
||
scan-gateway SHALL удалить `api/rules/statement_lines.yaml` и подстановку наименований по справочнику, срезание
|
||
уверенности кода до 99 по справочнику, выбор редакции для имён (`_choose_edition`), пропуск строк с нечисловым и пустым
|
||
кодом со счётчиками, правило «оставлена первая строка» при повторе кода, синтез шапки, правило «ячейки под колонкой
|
||
нет → `confidence = 0`, не распознано», привязку `is_recognized` к `confidence` и правило «любое предупреждение →
|
||
`needs_check`». Модули `normalizer/ocr/text|dates|amounts` переезжают в общие разборы пакета, `layout|rows|header|
|
||
document` — в шаги 2–6 пакета; `ocr_lookalikes.yaml` — в словарь пакета.
|
||
|
||
#### Scenario: Строки без кода в aep_3
|
||
- **WHEN** в `aep_3.json` строки «БАЛАНС» и «Выручка» имеют пустой код, а в колонке значения мусор `211(1 |`
|
||
- **THEN** строки попадают в результат со статусами (`detail` под строкой с кодом, `missing` в начале таблицы) и сырым
|
||
текстом; счётчиков «строк без кода с суммами пропущено» нет
|