Нормализатор: разлеплять склеенные строки ИС «1500\n1700» (#16, OQ-156) #17

Merged
aep merged 1 commits from feat/16-split-merged-codes into main 2026-10-08 13:54:42 +03:00
Owner

Closes #16

Проблема

В ответах настоящей ИС по ББ РБ и Счастливочной за 1 кв. 2025 последние строки баланса склеены: код 1500\n1700, суммы 917 775\n2 371 333. Строка пропускалась как нечисловой код → в документе не было 1500 (итог раздела V) и 1700 (БАЛАНС).

Что сделано

  • rows.split_merged_row: N ≥ 2 целых кодов через перевод строки и ровно N частей в каждой непустой ячейке значений → N строк до классификации; наименование делится так же (если частей N) или остаётся целым; уверенность — исходной ячейки. Число частей не сходится → поведение прежнее (нечисловой код). Работает и для строк до шапки.
  • Предупреждение таблицы строк с несколькими кодами разлеплено: N (документ needs_check — разбивку подтверждает аналитик).
  • Решение №36 в design.md Среза 3a (отклонение от дословного переноса _classify_row), README — таблица предупреждений и раздел про отклонения.
  • Правило — 05-domain-rules.md §11.1 п. 4 и OQ-156 (RSHB/arm-ka-docs, PR рядом).

Результат на реальных ответах

1500 1700 1600 = 1700 1300+1400+1500 = 1700
РБ 31.03.2025 917 775 2 371 333 да (3 колонки) да
Счастливочная 31.03.2025 43 274 198 622 да (3 колонки) да

Эталоны aep_3/5/6/8 не изменились.

Проверка

make check-full на чистой инфраструктуре (стенд погашен): ruff/mypy чисто, unit 1042 passed, integration 11 passed, docker build ок.
Замечание: при поднятом стенде (--profile services) интеграционные тесты падают и на main — шлюз и эмулятор стенда в той же queue group и горячей папке забирают сообщения и файлы тестов.

Сливать вместе с RSHB/arm-ka-fixtures (эталоны после разлепления) — иначе golden-тесты разойдутся.

Rulings I made

  • R-1: при несходящемся числе частей строка не разлепляется (а не «разлепить сколько получится») — ложная разбивка хуже явного предупреждения. Цена ошибки: низкая.
  • R-2: разлеплённые строки делят ordinal исходной строки (уникальность нигде не требуется). Цена: низкая.

Найдено попутно (не исправлено)

  • У РБ строка «Обязательство по аренде» распознана с кодом 1520 и отброшена как повтор кода (OQ-152) → на 31.03.2025 Σ1510…1550 = 828 554 ≠ 1500 = 917 775 (разница 89 221).

🤖 Generated with Claude Code

Closes #16 ## Проблема В ответах настоящей ИС по ББ РБ и Счастливочной за 1 кв. 2025 последние строки баланса склеены: код `1500\n1700`, суммы `917 775\n2 371 333`. Строка пропускалась как нечисловой код → в документе не было 1500 (итог раздела V) и 1700 (БАЛАНС). ## Что сделано - `rows.split_merged_row`: N ≥ 2 целых кодов через перевод строки и ровно N частей в каждой непустой ячейке значений → N строк **до** классификации; наименование делится так же (если частей N) или остаётся целым; уверенность — исходной ячейки. Число частей не сходится → поведение прежнее (нечисловой код). Работает и для строк до шапки. - Предупреждение таблицы `строк с несколькими кодами разлеплено: N` (документ `needs_check` — разбивку подтверждает аналитик). - Решение №36 в `design.md` Среза 3a (отклонение от дословного переноса `_classify_row`), README — таблица предупреждений и раздел про отклонения. - Правило — `05-domain-rules.md` §11.1 п. 4 и OQ-156 (RSHB/arm-ka-docs, PR рядом). ## Результат на реальных ответах | | 1500 | 1700 | 1600 = 1700 | 1300+1400+1500 = 1700 | |---|---|---|---|---| | РБ 31.03.2025 | 917 775 | 2 371 333 | да (3 колонки) | да | | Счастливочная 31.03.2025 | 43 274 | 198 622 | да (3 колонки) | да | Эталоны `aep_3/5/6/8` не изменились. ## Проверка `make check-full` на чистой инфраструктуре (стенд погашен): ruff/mypy чисто, unit 1042 passed, integration 11 passed, `docker build` ок. Замечание: при поднятом стенде (`--profile services`) интеграционные тесты падают и на `main` — шлюз и эмулятор стенда в той же queue group и горячей папке забирают сообщения и файлы тестов. **Сливать вместе с RSHB/arm-ka-fixtures (эталоны после разлепления)** — иначе golden-тесты разойдутся. ## Rulings I made - R-1: при несходящемся числе частей строка не разлепляется (а не «разлепить сколько получится») — ложная разбивка хуже явного предупреждения. Цена ошибки: низкая. - R-2: разлеплённые строки делят `ordinal` исходной строки (уникальность нигде не требуется). Цена: низкая. ## Найдено попутно (не исправлено) - У РБ строка «Обязательство по аренде» распознана с кодом 1520 и отброшена как повтор кода (OQ-152) → на 31.03.2025 Σ1510…1550 = 828 554 ≠ 1500 = 917 775 (разница 89 221). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
aep added 1 commit 2026-10-08 11:59:55 +03:00
ИС возвращает соседние строки формы одной строкой: в ячейке кода несколько
целых кодов через перевод строки, суммы — тоже. Раньше строка пропускалась как
нечисловой код, и в ББ РБ и Счастливочной за 1 кв. 2025 не было 1500 и 1700.

- rows.split_merged_row: N ≥ 2 целых кодов и ровно N частей в каждой непустой
  ячейке значений → N строк до классификации; наименование делится так же или
  остаётся целым; уверенность — исходной ячейки. Иначе — поведение прежнее.
- Предупреждение таблицы «строк с несколькими кодами разлеплено: N».
- Решение №36 в design.md Среза 3a (отклонение от источника), README.

Эталоны нормализатора — отдельный PR в arm-ka-fixtures; правило — §11.1 п. 4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
Owner

Проверено на чистом стенде (08.10.2026; down -v, migrate, seed-dev; шлюз и эмулятор — образ этой ветки, фронт arm-web test 0897173):

  • ББ РБ 1 кв. 2025 (реальный ответ ИС): строки 1500 = 917 775 и 1700 = 2 371 333 на экране [41]; 1600 = 1700 сходится; осталось 2 нарушения в колонке 1 от повторов кодов 1220 и 1520 (OQ-152, не эта задача) — приняты с комментарием, документ подтверждён.
  • ББ Счастливочной: 1500 = 43 274, 1700 = 198 622, все проверки пройдены; дата отчёта не распознана ИС — введена 2025-03-31, подтверждён. ОФР обеих — без нарушений, подтверждены.
  • Чек-лист версии 2025 К1: ББ и ОФР «Загружен» у обоих ЮЛ; свод 1421 строка, пробелов 0.
  • aep_6 (W19–W28 гайда) — без изменений поведения.
Проверено на чистом стенде (08.10.2026; down -v, migrate, seed-dev; шлюз и эмулятор — образ этой ветки, фронт arm-web test 0897173): - ББ РБ 1 кв. 2025 (реальный ответ ИС): строки 1500 = 917 775 и 1700 = 2 371 333 на экране [41]; 1600 = 1700 сходится; осталось 2 нарушения в колонке 1 от повторов кодов 1220 и 1520 (OQ-152, не эта задача) — приняты с комментарием, документ подтверждён. - ББ Счастливочной: 1500 = 43 274, 1700 = 198 622, **все проверки пройдены**; дата отчёта не распознана ИС — введена 2025-03-31, подтверждён. ОФР обеих — без нарушений, подтверждены. - Чек-лист версии 2025 К1: ББ и ОФР «Загружен» у обоих ЮЛ; свод 1421 строка, пробелов 0. - aep_6 (W19–W28 гайда) — без изменений поведения.
aep merged commit e67aab35d8 into main 2026-10-08 13:54:42 +03:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RSHB/arm-scan-gateway#17
No description provided.