Andrey Epifancev fcd609c633 feat(rules): словари ОСВ (заголовки, группировки, периоды, типы данных) и загрузчик
Словари api/rules/{osv_headers,osv_groups,periods,data_types}.yaml и src/parser/rules.py
(normalize_text, Pattern, load_rules, pydantic-валидация с RuntimeError по файлу и ключу,
currency_aliases по R-6). AST-линтер координат tests/unit/parser/test_no_coordinates.py
перенесён из Task 12 (R-7, правила R-4/R-5). Тест формулировок реальных ОСВ.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 12:28:46 +04:00

3.8 KiB
Raw Blame History

rules/ — словари синонимов парсера

Словари rules/*.yaml, по которым tabular-parser ищет структуру файла по содержимому: заголовки колонок, группировки, периоды, типы данных. Словари — данные, а не код: новый синоним добавляется строкой в YAML без правки парсера. Парсер не привязан к координатам (буквы колонок, номера строк, имена листов); это проверяет AST-линтер tests/unit/parser/test_no_coordinates.py.

Путь указан относительно api/ (рабочего каталога команд сервиса): api/rules/. Загрузчик — src/parser/rules.py (load_rules()), источник содержимого — docs/context/05-domain-rules.md §1.0–§1.5.

Файл Что описывает
osv_headers.yaml маркер листа ОСВ и листов форм ББ/ОФР; группы сумм (начало / обороты / конец); «Дебет»/«Кредит»; служебные колонки (ИНН, КПП, код, количество, валюта); строка «Итого»; метки шапки (счёт, период, выводимые данные, валюта, параметры, субконто)
osv_groups.yaml название группировки из шапки -> ACCOUNT / DEPARTMENT / COUNTERPARTY / CONTRACT / OTHER (default — для всего прочего)
periods.yaml текст периода -> period_quarter и is_cumulative (§1.5); year — паттерн года
data_types.yaml «Выводимые данные» -> BU / NU / SUM; строки «Вал.» / «Кол.»; коды валют ISO 4217; синонимы валюты (руб. -> RUB)

Как писать паттерны

  • Паттерн — регулярное выражение Python. Он ищется (search) в нормализованном тексте ячейки и применяется без учёта регистра.
  • Нормализация текста (normalize_text): нижний регистр, «ё» -> «е», дефисы, тире, неразрывные пробелы и переносы строк -> один пробел, пробелы схлопываются. Пример: Оборотно-сальдовая\nведомость -> оборотно сальдовая ведомость.
  • Поэтому в паттернах нет «ё», дефисов, тире и диапазонов [а-я]: пишите оборотно\s*сальдовая, д т (для «Д-т»), \w вместо диапазона. Загрузчик отвергает такой паттерн с указанием файла и ключа.
  • Порядок записей в списках mapping, rules (периоды), header, row — приоритет: побеждает первое совпадение, от специфичных правил к общим.
  • Ошибка в словаре (нет обязательного ключа, неизвестный ключ, неверный регэксп или тип) — RuntimeError при загрузке с именем файла и ключом.

Что намеренно не в штатном словаре

Синоним «нач. остаток» / «начальный остаток» для группы opening не включён: он нужен, чтобы показать, что новый формат подключается строкой в YAML (тест сценария «Новый синоним»).