Преамбула «Обороты: …» над шапкой давала ОСВ, разбор листа падал и ронял книгу. Негатив s56 «Преамбула». Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
148 lines
22 KiB
Markdown
148 lines
22 KiB
Markdown
## Context
|
||
|
||
Классификация листа (`detect.classify_sheet`): ОСВ, если в первых `SHEET_MARKER_ROWS` (30) строках есть ячейка,
|
||
совпадающая с `sheet_markers`; иначе вид листа определяет пакет `arm_statements` (форма / продолжение / прочее).
|
||
`sheet_markers` сейчас один: `оборотно\s*сальдовая\s+ведомость`. Заголовок таблицы (`_find_group_row`) — первая строка,
|
||
где есть группы «обороты» и «сальдо на конец». Сторона ищется в начале текста ячейки (`^(дебет|дт|д т)\b`) — в
|
||
отдельной ячейке под группой либо в остатке ячейки группы после совпадения (`_group_cells`: «Сальдо на начало Дт»).
|
||
|
||
Файлы — банк первичных документов `awp-ca/doc-bank/` (индекс `index/index.csv`, колонки `parse_status`, `parse_error`,
|
||
`parse_bug`, `sha256`; в git не кладутся). Списки затронутых файлов с ГК, ЮЛ и sha256 — вложения `список_файлов.csv`
|
||
к AURORA-1717 и AURORA-1719. Образцы во вложениях задач:
|
||
|
||
| Задача | Файл | Что показывает |
|
||
|---|---|---|
|
||
| 1717, 1719 | «ОСВ по внб счету 009 за 9 мес 2025.xlsx» (Промлит) | «Оборотная ведомость», «Остаток на начало/конец» |
|
||
| 1717, 1719 | «ОСВ 66 67 01-06 2025.xlsx» (Виола) | «Отчет по Главной книге», SAP «Сальдо вх Дт / Сальдо исх Кт» |
|
||
| 1717 | «67 9 мес. 25.xlsx» (Айсберри) | Navision «Фин. Обороты Листок», «НачалоДт / КонецКт» |
|
||
| 1719 | «ОСВсч62_3кв2025.xls» (НМЖК) | SAP «Сальдо НачальноеДТВВ / КонечноеКТВВ» |
|
||
| 1732 | «ОСВ по внб сч 009 за 3 кв 2025.xlsx» (КТЗ) | итог «ВСЕГО» |
|
||
|
||
Эксперимент автора задач на копии словарей (20.10.2026, синонимы 1717 + 1719 без «ДТВВ» и без запасного признака): из
|
||
129 файлов 1717 — 43 «Готово», 43 «Требует проверки», 43 упираются в группы и иерархию; из 159 файлов 1719 — 53
|
||
«Готово», 58 «Требует проверки», 48 — другое (AURORA-1720, 1721, 1723). Остальные ОСВ банка статусы не ухудшили.
|
||
|
||
## Goals / Non-Goals
|
||
|
||
**Goals:**
|
||
- Листы с перечисленными названиями и листы без названия с полным заголовком таблицы ОСВ распознаются как ОСВ.
|
||
- Перечисленные написания групп и сторон находятся; заголовок таблицы этих файлов не падает с `INVALID_FORMAT`
|
||
«нет групп сумм».
|
||
- «ВСЕГО» — итоговая строка листа.
|
||
- Ни один документ банка первички и ни одна фикстура не ухудшает результат (см. «Регрессия»).
|
||
|
||
**Non-Goals:**
|
||
- Довести все затронутые файлы до «Готово»: дальше их держат иерархия (AURORA-1721, 1730), одинаковые подписи начала и
|
||
конца (AURORA-1720), обороты без подзаголовков в варианте НОВО-МАР и SAP со стороной перед группой (AURORA-1722),
|
||
ведомости ОС/ТМЦ (AURORA-1723, 1731). Эти файлы могут остаться `needs_check` или `INVALID_FORMAT` по другой причине.
|
||
- Отчёт 1С «Обороты счета» (1 файл, ГК Сейма): внутри «Оборот Дт/Кт» колонки корреспондирующих счетов, это отдельная
|
||
форма. Синоним `обороты\s+счета` не добавляется.
|
||
- Правило «расшифровка без кодов ББ не может быть Готово» (вторая половина AURORA-1718) — пакет `arm_statements`,
|
||
ждёт AURORA-1677.
|
||
|
||
**Anti-goals (провал, даже если тесты зелёные):**
|
||
- Лист формы ББ/ОФР, её продолжения или расшифровки становится ОСВ по запасному признаку или по новому названию
|
||
ведомости, хотя ведомостью не является. Ведомость, которую сегодня ложно забирает конвейер форм (10 файлов «Оборотный
|
||
баланс», AURORA-1718), становится ОСВ по названию — это цель, а не ухудшение (признак по названию проверяется раньше
|
||
форм, как сейчас).
|
||
- `if` под файл, организацию, систему-источник или имя листа вместо синонима в YAML.
|
||
|
||
## Decisions
|
||
|
||
### D1. Запасной признак листа — последним шагом (решение владельца 28.10.2026)
|
||
|
||
Порядок классификации: признак ОСВ по названию (`sheet_markers`) → форма / продолжение / прочее (пакет). Только если
|
||
пакет вернул «прочее», лист проверяется запасным признаком — раньше слабого продолжения формы (R-12): в первых `SHEET_MARKER_ROWS` строках есть строка групп, где
|
||
найдены **все три** группы (начало, обороты, конец), и у каждой группы найдены **обе** стороны — Дебет и Кредит
|
||
(в ячейках под группой или в самой ячейке группы), и между ними в строках заголовка нет других подписей (R-11).
|
||
Свёрнутое сальдо (одна колонка в группе) запасной признак не даёт.
|
||
Нашёлся — лист `OSV`, дальше обычный конвейер ОСВ; нет — `SHEET_OTHER`, как сейчас.
|
||
|
||
Почему так: расшифровки ББ с колонками «Остаток на начало / … / Остаток на конец» забирает классификатор форм раньше,
|
||
до запасного признака они не доходят; поиск заголовка выполняется только на листах «прочее», а не на каждом листе книги
|
||
с формами. Требование трёх групп и обеих сторон строже обычного заголовка ОСВ («начало» там необязательно), поэтому
|
||
ложное срабатывание требует почти полной таблицы ОСВ.
|
||
|
||
### D2. Новые записи словарей
|
||
|
||
Ориентир — рекомендации из AURORA-1717/1719/1732; окончательные паттерны подбирает исполнитель по образцам, каждая
|
||
запись — с синтетикой, где она срабатывает (R-22). Паттерны пишутся по нормализованному тексту (нижний регистр, «ё» →
|
||
«е», дефисы и переносы → пробел).
|
||
|
||
| Ключ | Написания |
|
||
|---|---|
|
||
| `sheet_markers` | «Оборотная ведомость …», «ОСВ по сч. …» (с начала ячейки), «Оборотный баланс», «Фин. Обороты Листок», «Отчет по Главной книге» |
|
||
| `groups.opening` | «Остаток на начало (периода)», «Начальное сальдо» (уже есть `\bнач(альн\w*)?\.?\s*сальдо`), «Сальдо начальное…», «Сальдо вх …», «НачалоДт / НачалоКт» |
|
||
| `groups.closing` | симметрично: «Остаток на конец», «Конечное сальдо», «Сальдо конечное…», «Сальдо исх …», «КонецДт / КонецКт» |
|
||
| `debit` / `credit` | «по дебету» / «по кредиту» (в остатке ячейки группы «Оборот по дебету»); сторона, приклеенная к названию без границы слова («…ДТВВ», «…КТВВ», «НачалоДт») |
|
||
| `total_row_exact` | «ВСЕГО» |
|
||
|
||
Если сторону без границы слова нельзя выразить записью словаря при текущем `_side` (поиск с начала остатка ячейки),
|
||
допустима правка поиска стороны в `detect.py`, общая для всех написаний, без упоминания конкретной системы.
|
||
|
||
### D3. Регрессия по банку первички
|
||
|
||
До изменений и после — прогон парсера (CLI, `ENV_FILE=.env.test`) по всем файлам банка с `route = парсер` (xls, xlsx,
|
||
xlsb) на main `a8c9605` и на ветке. Сравнение по каждому документу: вид (ОСВ / форма / прочее), статус, код ошибки.
|
||
Ухудшение — `done` → `needs_check`/ошибка, `needs_check` → ошибка, любой переход форма/расшифровка → ОСВ через запасной
|
||
признак, переход форма/расшифровка → ОСВ по названию ведомости или «прочее» → ОСВ, если лист не ведомость (каждый такой
|
||
переход по названию просматривается вручную: ожидаемы «Оборотный баланс» и другие ведомости из списков 1717/1719).
|
||
Каждое ухудшение разбирается до PR: либо исправляется, либо выносится владельцу с образцом.
|
||
|
||
Банк — `awp-ca/doc-bank/` (в worktree — симлинк `.wt/osv-dict/doc-bank`), только чтение. Базовый прогон на main
|
||
`a8c9605` снимается до первой правки кода. Скрипт прогона и сравнения и его результаты — `awp-ca/admin/osv-other-systems-regress/`
|
||
(не репозиторий; в PR — только итоговая таблица).
|
||
|
||
Приёмка: сценарии спеки на синтетике, зелёный `make check-full`, нет ухудшений D3. Число файлов банка, перешедших в
|
||
«Готово» / «Требует проверки», — отчёт, а не порог. Реальные безымянные листы, которые конвейер форм относит к форме или
|
||
продолжению (до запасного признака они не доходят), остаются как есть и перечисляются в PR как остаток. Итоговая
|
||
таблица переходов статусов (было → стало, число файлов) — в описание PR и комментарий к AURORA-1717/1719. Плюс обычные
|
||
`make check-full` (golden, property, покрытие словарей) и `tests/fixtures/test_osv_dkb.py`.
|
||
|
||
### D4. Правило в 05-domain-rules.md
|
||
|
||
§1.1: признак листа — название ведомости по словарю `sheet_markers` (примеры написаний) или, если лист не опознан как
|
||
форма ББ/ОФР или её продолжение, полный заголовок таблицы ОСВ в первых 30 строках (D1). §1.2: варианты написания групп
|
||
и сторон дополняются написаниями из D2. PR в arm-ka-docs из ветки `feat/81-osv-other-systems` worktree
|
||
`.wt/osv-dict/docs`, ссылка на tabular-parser#81.
|
||
|
||
## Итог регрессии (28.10.2026)
|
||
|
||
Банк первички, 2152 файла (`admin/osv-other-systems-regress/report.md` workspace): 60 файлов из ошибки → ОСВ «Готово»,
|
||
70 → «Требует проверки», 40 узнаны как ОСВ, но стоят на 1720–1723; ни один лист формы или прочий лист книги с формами
|
||
не стал ОСВ; ухудшения — только R-14. Файлы списков 1717/1719 (175): 60 «Готово», 60 «Требует проверки», 50 ошибка
|
||
формата, 4 ложных «Готово» безымянных ведомостей 009, которые забирает конвейер форм (D1), 1 — неполный заголовок.
|
||
|
||
Контрольный набор синтетики s48–s57: позитивы на базе падали, негативы проходили; на ветке проходят все. Мутации
|
||
запасного признака (без R-11, без лимита 30 строк, со свёрнутым сальдо, с двумя группами) и снятие якоря `^` у названий
|
||
ловит каждая свой негатив (s55, s56, s57).
|
||
|
||
## Risks / Trade-offs
|
||
|
||
- [`^осв\b` и «оборотн… ведомост» в тексте формы] → проверка ОСВ идёт первой; регрессия D3 ловит листы форм, ставшие
|
||
ОСВ; паттерн «ОСВ» — только с начала ячейки.
|
||
- [Расшифровка, не узнанная пакетом, проходит запасной признак] → D1 требует три группы и обе стороны; регрессия D3.
|
||
- [Новые синонимы групп матчат преамбулу шапки («Остаток на начало: …») как строку групп] → в такой строке нет
|
||
«оборотов», `_find_group_row` её пропускает (R-12); синтетика с преамбулой.
|
||
- [Сторона без границы слова («дт» внутри слова)] → искать её только в остатке ячейки группы после совпадения группы, не
|
||
в произвольных ячейках.
|
||
|
||
## Decisions made without discussion
|
||
|
||
| Дата | Решение | Обоснование | Цена ошибки |
|
||
|---|---|---|---|
|
||
| 2026-10-28 | R-1. Отчёт 1С «Обороты счета» вне объёма, синоним не добавляется | автор AURORA-1717 проверил: с синонимом файл даёт «Требует проверки» с договорами в контрагентах — нужна отдельная форма | 1 файл остаётся `INVALID_DOCUMENT`; отдельная задача |
|
||
| 2026-10-28 | R-2. Запасной признак ищет строку групп только в первых `SHEET_MARKER_ROWS` (30) строках | у безымянных листов таблица начинается сразу; ограничение снижает время и ложные срабатывания на длинных листах «прочее» | безымянный лист с преамбулой длиннее 30 строк не распознаётся; поднимется регрессией D3 |
|
||
| 2026-10-28 | R-3. Запасной признак не принимает свёрнутое сальдо (одна колонка в группе) | строгость против ложных ОСВ (D1) | ОСВ без названия со свёрнутым сальдо не распознаётся |
|
||
| 2026-10-28 | R-5. Новые `sheet_markers` якорятся к началу ячейки (`^…`); якорь снимается для конкретного названия, только если по спискам 1717 файлы с ним иначе не находятся | «Оборотная ведомость», «Оборотный баланс» могут встретиться в примечаниях к ББ; признак по названию проверяется раньше форм | часть ведомостей с текстом перед названием не распознаётся; видно в регрессии D3 |
|
||
| 2026-10-28 | R-6. Запасной признак проверяет ту же строку групп, что возьмёт `find_table_header` (первую с «оборотами» и «концом» в первых 30 строках), и колонки ищет тем же `_columns_of_group`; строгие условия — только к этой строке (финальное ревью, I-1: иначе преамбула «Обороты: …» над шапкой давала ОСВ, разбор падал и ронял книгу; негатив s56 «Преамбула») | запасной признак и конвейер не должны расходиться в том, что считать заголовком | безымянная ОСВ с преамбулой «Обороты: …» над шапкой не распознаётся |
|
||
| 2026-10-28 | R-7. Порядок PR: `fixtures` (golden синтетики, отдельный коммит `make golden-update`) → tabular-parser → docs | golden-тесты tabular-parser читают `../fixtures` | — |
|
||
| 2026-10-28 | R-8. Приёмка — синтетика + `make check-full` + нет ухудшений D3; число исправленных файлов банка — отчёт, не порог | эксперимент автора задач — ориентир, а не обязательство; остаток держат 1720–1723 | — |
|
||
| 2026-10-28 | R-9. Написание «Остаток по дебету/кредиту на начало/конец» (6 файлов КТЗ/ЧАЗ) включено в словарь: группа «остаток» с опережающей проверкой, сторона — из остатка ячейки | та же семья «Остаток на начало/конец» (1719), решается записью словаря | лишняя запись, удаляется |
|
||
| 2026-10-28 | R-10. В синтетике s50 у SAP-листа обороты «Оборот Дт / Оборот Кт», а не реальное «Дт оборот» | сторона перед группой — AURORA-1722, вне объёма (R-4) | файлы Виолы остаются с ошибкой до 1722 |
|
||
| 2026-10-28 | R-11. Запасной признак требует, чтобы между колонками «Дебет» и «Кредит» каждой группы в строках заголовка не было других подписей | иначе 1С «Обороты счета» (Дт/Кт оборота разделены колонками корр. счетов) проходит как ОСВ вопреки R-1; держит негатив s55 | безымянная ОСВ с колонкой между Дт и Кт не распознаётся |
|
||
| 2026-10-28 | R-12. Запасной признак проверяется раньше слабого продолжения формы (лист из 1–2 кодов сразу после формы), но после сильных признаков формы и продолжения | на базе лист Navision после формы ББ пакет присоединял к ней как слабое продолжение (синтетика s52); полная таблица ОСВ — сильнее эвристики «1–2 кода» | лист-продолжение формы с полной таблицей ОСВ отделится от формы (у продолжения формы таких групп нет) |
|
||
| 2026-10-28 | R-13. Признак «ОСВ …» сужен до `^осв\s+по\s+(\w+\s+по\s+)?сч\b` вместо `^осв\b` | первый прогон банка: строка «ОСВ за квартал по счетам …» перечня документов на листе «Входные данные_ИП» шаблона банка делала лист ОСВ, его разбор падал, и вся книга расшифровок становилась ошибкой (86 файлов); все 20 реальных названий начинаются с «ОСВ по сч.» / «ОСВ по ДЗ по сч.»; держит негатив s55 | «ОСВ» с другим продолжением по названию не узнаётся (остаётся запасной признак) |
|
||
| 2026-10-28 | R-14. Два файла «Сводная ОСВ … (забаланс)»: ложное «Готово» расшифровки на базе → ошибка иерархии ОСВ на ветке принято, а не исправлено | это цель изменения (ведомость «Оборотный баланс / Оборотная ведомость» перестаёт быть расшифровкой, 1718); дальше файл держит иерархия «002.01: Название» — AURORA-1721 | у двух книг «Ошибка» вместо фальшивого «Готово» до 1721 |
|
||
| 2026-10-28 | R-4. AURORA-1722 (SAP со стороной перед группой, НОВО-МАР) не входит | в задачах указан порядок: после 1717/1719; причина варианта НОВО-МАР не разобрана | эти файлы остаются с ошибкой до 1722 |
|