9.0 KiB
Context
Решения владельца 06.11.2026 (выбраны рекомендованные варианты): 1734 — резать по смене формы у себя; 1735 — отсеивать редкую колонку с неразобранной подписью. Разбор на JSON из задач (прогон нормализатора scan-gateway на пакете 0.1.3):
- АК-ЮЛ: один документ
BALANCE, 54 кода (ББ + ОФР),SEGMENT_COLUMNS_MISMATCHу сегмента строки 19, десять жёстких нарушений ББ. Строка 41 — шапка с «Коды» (столбец кодов сдвинут в столбец 2), сегмент открывается, но остаётся в ББ. - Калтан, ОФР: колонки 4 / 5 («31») / 6,
COLUMN_WITHOUT_DATEпо столбцу 5; в столбце 5 разбирается одно число — «$301 .» (тире «—», «——-» числами не считаются).
Decisions
- Разрез — отдельная функция до раскладки.
normalize_candidateвозвращает один документ, хосты вызывают его на каждый кандидат с изоляцией ошибок. МенятьCandidateResultна список ломает API у трёх потребителей; разрез на кандидаты сохраняет шаги 2–8 нетронутыми — каждая часть проходит их как обычный кандидат (свои колонки, периоды, §7). Сегменты для разреза ищутся тем же кодом шага 2 (_split_and_analyse), что и для раскладки. - Условие разреза: своя шапка + первые
min_codes(3) кодов сегмента — одной формы, отличной от формы текущей части. Шапка нужна, чтобы не резать по случайным строкам; порог — чтобы пара строк другой формы (OCR-мусор, «пояснения» в хвосте) не создавала документ. Тип части — по первому сегменту части с определённым типом. - Часть
k ≥ 1:type_hint = null, пустыеevidenceиwarnings— метка таблицы ИС относится к первой форме, а предупреждения адаптера (единицы, шапка) уже есть у первой части; повторять их в каждой части — дубли. - Редкий столбец: «между» — есть колонка периода левее и правее; «редкий» — число не более чем в одной строке с
кодом при ≥ 3 у каждой колонки периода сегмента. Правило применяется в
segment_columns(у каждого сегмента со своей шапкой), адреса идут в общееNUMBERS_OUTSIDE_TABLEформы.
Decisions made without discussion
| Дата | Решение | Обоснование | Цена ошибки |
|---|---|---|---|
| 2026-11-06 | locator части — <locator>;form:<k> (k с 1); первая часть — прежний locator |
Locator нигде не разбирается (ядро и UI показывают как строку); формат читаемый, у первой части ничего не меняется — golden и уже сохранённые документы не съезжают | Низкая: строка в карточке документа; поменять формат — одна строка кода |
| 2026-11-06 | Порог разреза — существующий min_codes словаря диапазонов (3), не новый ключ |
Тот же смысл «достаточно кодов, чтобы считать это формой» уже есть в словаре | Низкая: порог — данные |
| 2026-11-06 | Разрез — общий для OCR и Excel | Правила шага 2 общие (как Р-44); у Excel формы обычно на разных листах — разрез почти не срабатывает, но лист «ББ + ОФР» с повторной шапкой тоже станет двумя документами | Средняя: golden tabular-parser может измениться — проверяется при подъёме пина, при сюрпризе — флаг источника |
| 2026-11-06 | Текст NUMBERS_OUTSIDE_TABLE: «числа вне колонок формы не учитываются», если есть адрес редкого столбца, иначе прежний |
Прежний текст «правее таблицы» неверен для столбца посередине; прежние случаи и их golden не меняются | Нулевая: текст предупреждения |
| 2026-11-06 | «Редкий»: ≤ 1 число в столбце и ≥ 3 у каждой колонки периода | Калтан: 1 против 10+; столбец с двумя числами уже может быть данными — оставляем аналитику | Низкая: порог — константа пакета |
| 2026-11-06 | Реальные JSON АК-ЮЛ и Калтана в fixtures не кладём; тесты пакета — на синтетических кандидатах (tests/builders.py), прогон реальных файлов — вручную через нормализатор scan-gateway |
Файлы заказчика с контура; синтетика воспроизводит обе раскладки строка в строку | Низкая |
| 2026-11-07 | Тип сегмента для разреза — по первым min_codes кодам (все одной формы), а не по большинству всех кодов сегмента (исполнение, Task 2) |
Строки ОФР без своей шапки прилипают к сегменту пассива ББ с повторной шапкой; по большинству такой сегмент — «ОФР», и разрез по шапке ББ унёс бы пассив в ОФР | Низкая: сегмент, который открывается 1–2 кодами своей формы и дальше идёт чужой, не режется — как до изменения |
| 2026-11-07 | Для разреза — помощник segments.split_segments (первая строка, своя шапка, коды сегмента) вместо прямого импорта приватных функций модуля |
split.py не зависит от приватных имён |
Нулевая |
Risks / Trade-offs
-
Правило редкого столбца срабатывает и на ББ АК-ЮЛ (прогон 07.11): в сегменте пассива столбец 5 с обрывком «На 2» и одним числом 46922 (итог 1700 за 31.12.2024, OCR сдвинул его из столбца 6) уходит в
NUMBERS_OUTSIDE_TABLE(row:40). До изменения этот сегмент сопоставлялся по порядку (SEGMENT_COLUMNS_MISMATCH, значения столбца 5 уезжали в колонку 6, настоящие значения столбца 6 терялись); теперь столбец 6 сопоставлен по дате, потеряно одно число, адрес виден аналитику, жёсткая проверка1600 = 1700ловит пустой 1700. -
АК-ЮЛ после разреза: ОФР — отдельный документ, но подписи его колонок 5 («За I п / 20:») и 6 («юлугодие / 25 года») ИС тоже разорвала, и ни одна не разбирается как период — столбец 5 не «между периодами», правило редкого столбца не срабатывает: обе колонки с
COLUMN_WITHOUT_DATE, документneeds_check, аналитик ставит дату. Это честный результат на испорченной шапке; ББ после разреза теряет 2xxx-строки и жёсткие нарушения, вызванные ими. -
Саракташагротехремонт — JSON в задаче нет (только PDF); ожидаем ту же раскладку, проверим после выкладки.
-
Хостам нужен один вызов
split_by_form; без него поведение прежнее — подъём пина без правки хоста ничего не ломает.