51 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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`