Proposal, design (D-1…D-11, решения без обсуждения №1–№11), новая capability statement-parsing, дельта tabular-recognition-service (BookParser, schema_version 1.2), tasks. Решения владельца 06.10.2026: только парсер и контракт; страницы-продолжения без склейки между файлами; единицы как есть; пятизначные подстроки как строки; контракт MINOR 1.2; без запасного пути по именам. Refs #14 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: cedd7915-2efe-41e5-988c-a9117033598b
75 lines
8.1 KiB
Markdown
75 lines
8.1 KiB
Markdown
# Proposal: Срез 2b — парсер ББ и ОФР из Excel (§12), контракт v1.2
|
||
|
||
**Срез:** 2 «Загрузка файлов + табличный парсер», подсрез 2b (`../docs/context/09-delivery-plan.md`). **Репозиторий:**
|
||
arm-tabular-parser. **Issue:** RSHB/arm-tabular-parser#14. **Сквозной change:** `../docs/openspec/changes/slice-2b-statement-parser`
|
||
(контракт v1.2, §12, OQ; RSHB/arm-ka-docs#26). Golden и синтетика — отдельный PR в arm-ka-fixtures. Копии схемы v1.2 —
|
||
bounded-PR в arm-core и arm-scan-gateway (без изменения поведения) до мержа этого change.
|
||
|
||
Решение владельца 06.10.2026 (brainstorming): объём среза — **только парсер и контракт**; маппинг `statementDocument` в
|
||
ядро остаётся в Срезе 3.
|
||
|
||
## Why
|
||
|
||
После Среза 2a сервис разбирает только ОСВ, а листы с признаками ББ/ОФР пропускает с предупреждением
|
||
`skipped: statement (slice 2b)`. Без форм из Excel нет пути «отчётность компании → консолидация»: ББ и ОФР дают строки
|
||
КФО (§8), гудвилл (1310) и логические проверки (§7). В fixtures есть 15 реальных файлов пакета ДКБ в трёх раскладках
|
||
(постраничные xls 1С, многолистовая книга ФСБУ 4/2023, выгрузка `TDSheet`) и четыре пустых шаблона 66н / ФСБУ 4/2023 —
|
||
на них парсер обязан проходить без единого правила под файл, организацию или имя листа (§1.0, §12).
|
||
|
||
## What Changes
|
||
|
||
- **Оркестратор книги** `api/src/parser/book.py` (`BookParser`): лимит размера, чтение книги, дедлайн, классификация
|
||
листов (`detect.classify_sheet`), раздача листов конвейерам ОСВ и форм, сбор документов, предупреждений, метрик и
|
||
статуса. `OsvParser` сужается до конвейера листа ОСВ (`parse_sheet`); `get_parser()` возвращает `BookParser`.
|
||
- **Конвейер форм** `api/src/parser/statements/` (`StatementParser`): заголовок формы и ОКУД, колонка кодов,
|
||
шапка документа, колонки-периоды, строки и значения, соотношения §7, склейка листов-продолжений внутри книги,
|
||
расшифровки как `DISCLOSURE`.
|
||
- **Словари** `api/rules/statement_headers.yaml`, `statement_periods.yaml`, `statement_checks.yaml` (соотношения §7 —
|
||
данные, не код) с pydantic-валидацией при старте и тестом покрытия.
|
||
- **Контракт v1.2** (копия `api/contracts/`, `CONTRACT_VERSION = "1.2"`): `statementDocument.document_type` +
|
||
`DISCLOSURE`; `statementDocument.checks`; `osvDocument.header.period_start/period_end/is_from_year_start`.
|
||
- **Тесты**: unit по модулям на синтетических сетках; property-тест на всех `../fixtures/statements-xlsx/**` по манифесту;
|
||
golden `../fixtures/golden/expected_statement_parse/`; синтетика `../fixtures/statements-xlsx/synthetic/`; линтер «нет
|
||
координат» на `statements/**` и `book.py`; покрытие словарей; интеграционный тест воркера с книгой НПЗ.
|
||
- **Документы**: README (раздел «Парсер форм»), CLAUDE.md сервиса, `rules/README.md`, спеки `statement-parsing` (новая)
|
||
и `tabular-recognition-service` (дельта).
|
||
|
||
## Capabilities
|
||
|
||
### New Capabilities
|
||
- `statement-parsing`: разбор ББ/ОФР из Excel по §12 — классификация листов и продолжений, тип формы, шапка, колонки-
|
||
периоды, колонка кодов, строки и значения, соотношения §7, склейка листов, статусы и диагностика, словари.
|
||
|
||
### Modified Capabilities
|
||
- `tabular-recognition-service`: «Парсер — заменяемый интерфейс» — реализация по умолчанию разбирает и ОСВ, и формы
|
||
(`BookParser`), результат пишется с `schema_version = "1.2"`; каталог `api/rules/` содержит словари форм.
|
||
|
||
## Impact
|
||
|
||
- Код: `api/src/parser/book.py` (новое), `api/src/parser/statements/**` (новое), `api/src/parser/osv.py` (удаление
|
||
`parse`/`_parse_book`), `api/src/parser/detect.py` (`classify_sheet`: продолжения форм, поиск признаков по области до
|
||
таблицы), `api/src/parser/__init__.py` (`get_parser`), `api/src/contract/{common,result}.py` (v1.2), `api/contracts/`
|
||
(копия), `api/rules/statement_*.yaml`, тесты, README, CLAUDE.md.
|
||
- Таблицы DBML: не затрагиваются (сервис без БД). Поля результата — только из контракта v1.2.
|
||
- Правила: §12 п. 1–8 (с решениями владельца 06.10.2026, внесёнными в §12 сквозным change'ем), §7 (формулы), §1.2 (числа).
|
||
Допущения: `ASSUMPTION(OQ-12)` — знаки 2410/2420/2430 проверяются мягко; `ASSUMPTION(OQ-36)` — строки без кода не
|
||
отдаются; `ASSUMPTION(OQ-23)` — расшифровки только классифицируются; `ASSUMPTION(OQ-37)` — код 1105 как пришёл.
|
||
- Соседи: `../docs` (контракт v1.2, §12, OQ), `../fixtures` (golden, синтетика), `arm-core` и `scan-gateway` — копия
|
||
схемы и pydantic-модели v1.2 отдельными bounded-PR, логика не меняется (ядро по-прежнему маппит только ОСВ).
|
||
- Пересечение с параллельной работой по ОСВ (issues #9, #10, #11): модули `header.py`, `classify.py`, `checks.py`,
|
||
`hierarchy.py`, `periods.yaml`, `osv_headers.yaml`, golden ОСВ в этом change не правятся; точка пересечения —
|
||
`osv.py` и `test_osv_parser.py`, разрешается при rebase на main перед PR.
|
||
|
||
## Non-goals
|
||
|
||
- Маппинг `statementDocument` в `document` / `financial_statement_*` ядра, логические проверки §7 в ядре, подтверждение
|
||
документа, чек-лист ББ/ОФР — Срез 3.
|
||
- Склейка страниц одной формы из **разных файлов** (постраничные xls 1С): страница-продолжение без шапки отдаётся как
|
||
документ с пустой шапкой и `needs_check`; признак продолжения в контракте — позже, при появлении потребителя в ядре.
|
||
- Сопоставление строк по наименованиям при отсутствии колонки кодов (§12 п. 2, словарь `statement_lines.yaml`) —
|
||
отложено до реального файла; форма без колонки кодов даёт `needs_check`.
|
||
- Нормализация единиц измерения (деление на 1000, пересчёт рублей в тысячи) — ядро и аналитик; парсер отдаёт как есть.
|
||
- Разбор содержимого расшифровок (`DISCLOSURE`), лист `К балансу`, рекомендуемые формы банка (OQ-23).
|
||
- Изменения в парсере ОСВ, кроме переноса оркестрации книги в `BookParser`; заполнение новых полей шапки ОСВ
|
||
`period_start/period_end/is_from_year_start` — в ветке issue #11 либо follow-up, см. design D-9.
|