51 lines
5.6 KiB
Markdown
51 lines
5.6 KiB
Markdown
# Spec Delta
|
||
|
||
## MODIFIED Requirements
|
||
|
||
### Requirement: Словари форм, координаты, golden
|
||
Словари форм (заголовки и ОКУД, периоды, соотношения §7, единицы, перечни кодов) SHALL жить в установленной библиотеке `arm_statements` и в
|
||
tabular-parser MUST NOT дублироваться: файлы `api/rules/statement_*.yaml` удалены. Код `src/parser/statements/**` и
|
||
`src/parser/book.py` MUST NOT содержать литералов координат (линтер `test_no_coordinates`); `ref` ячейки собирается из
|
||
индексов функцией `grid.cell_ref`. Снимки `../fixtures/golden/expected_statement_parse/**` SHALL покрывать все файлы
|
||
`statements-xlsx/**` и обновляться только `make golden-update`; `service.statements_version` — волатильное поле снимка.
|
||
Property-тест по манифесту `tests/statements_manifest.yaml` SHALL проверять тип, ИНН, ожидаемый статус, сходимость
|
||
жёстких соотношений для полных форм и, где задано, множество кодов предупреждений `error` документа.
|
||
|
||
#### Scenario: Новый синоним без релиза кода
|
||
- **WHEN** в словарь заголовков библиотеки `arm_statements` добавлен синоним заголовка «Баланс предприятия» и библиотека
|
||
переустановлена командой `make install`
|
||
- **THEN** лист классифицирован как `BALANCE` без изменения кода tabular-parser; собственного словаря форм в сервисе нет
|
||
|
||
#### Scenario: Мёртвая запись словаря
|
||
- **WHEN** запись словаря форм не срабатывает ни на одном файле
|
||
- **THEN** это проверяет тест покрытия словарей библиотеки `arm_statements` (внутри пакета, на его данных); тест покрытия
|
||
tabular-parser словари форм не охватывает
|
||
|
||
#### Scenario: Регрессия по снимкам
|
||
- **WHEN** результат разбора любого файла `statements-xlsx/**` отличается от снимка
|
||
- **THEN** golden-тест падает с diff; обновление — только `make golden-update` и отдельный коммит в fixtures
|
||
|
||
### Requirement: Адаптер Excel шага 1
|
||
tabular-parser SHALL оставить у себя чтение книги (лимиты `PARSE_MAX_BYTES`, `PARSE_TIMEOUT_SECONDS`, формат по
|
||
сигнатуре, лимиты zip и объединённых ячеек, `UNREADABLE`), классификацию листов (ОСВ — отдельный путь; форма;
|
||
продолжение; прочее) и адаптер «блок формы на листе → `FormCandidate`» общего кода; шаги 2–8 по формам SHALL
|
||
выполняться установленной библиотекой `arm_statements`. Адаптер SHALL: выделять блоки форм на листе по заголовку или ОКУД (без
|
||
кодов между ними блоки сливаются, заголовок после кодов — новая форма); собирать шапку каждого блока в его границах
|
||
(организация, ИНН без ИНН аудитора, ОКПО, ОКОПФ, ОКФС, единицы, дата, адрес) как `Cell` с `confidence = 100`;
|
||
заполнять у каждой ячейки `text` по числовому формату (tp#42) и `value`, `ref = <лист>!<A1>` (имя листа в одинарных
|
||
кавычках по правилу Excel, если в нём есть что-то кроме букв, цифр и `_`); дописывать
|
||
листы-продолжения в сетку открытой формы до раскладки (маркер «Форма … с.2» или позиция листа; проверки типа,
|
||
диапазона кодов и, при трёх и более кодах, числа колонок — как `join_blocker`), записывая границы листов в
|
||
`segment_breaks`. Несовпадение формата с `file_type` — предупреждение файла `FILE_TYPE_MISMATCH` (`info`). Лист без
|
||
признаков ОСВ и формы, без `type_hint` и кодов — предупреждение файла `SHEET_OTHER` (`info`, `locator = sheet:<имя>`),
|
||
документа нет.
|
||
|
||
#### Scenario: Книга ББ + ОФР
|
||
- **WHEN** книга содержит лист «Баланс» (ОКУД 0710001), лист «Баланс (2)» с маркером «Форма 0710001 с.2» и лист «ОФР»
|
||
- **THEN** адаптер выдаёт два кандидата: `BALANCE` с `locator = sheet:Баланс,Баланс (2)` и одной сеткой из двух листов
|
||
(`segment_breaks` — первая строка второго листа) и `INCOME` с `locator = sheet:ОФР`
|
||
|
||
#### Scenario: Ссылки ячеек
|
||
- **WHEN** код строки стоит в ячейке C27 листа «Баланс»
|
||
- **THEN** `ref` строки — `Баланс!C27`; у листа «Бухгалтерский баланс. Лист 1» — `'Бухгалтерский баланс. Лист 1'!C27`
|