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

24 lines
2.5 KiB
YAML
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.

# Текст периода -> квартал и признак нарастающего итога (05-domain-rules.md §1.5).
# Порядок важен: первый совпавший паттерн побеждает, правила идут от специфичных к общим («9 месяцев» и
# «12 месяцев» раньше «год», числовые «\b3\s*мес» с границей слова — не ловят «13 месяцев»).
# ASSUMPTION(OQ-02): is_cumulative=false для Q2–Q4 определяется по тексту «N квартал»; ядро может переопределить по
# данным (opening Q3 == opening Q1 -> нарастающая).
rules:
# Кварталы: арабские и римские номера, «1 кв.», «1-й квартал», «I кв.»
- {pattern: '\b(1|i)\s*(й|я|ый|ой)?\s*кв', quarter: Q1, is_cumulative: true}
- {pattern: '\b(2|ii)\s*(й|я|ый|ой)?\s*кв', quarter: Q2, is_cumulative: false}
- {pattern: '\b(3|iii)\s*(й|я|ый|ой)?\s*кв', quarter: Q3, is_cumulative: false}
- {pattern: '\b(4|iv)\s*(й|я|ый|ой)?\s*кв', quarter: Q4, is_cumulative: false}
# Нарастающие периоды: месяцы, диапазон месяцев, диапазон дат «01.01 - 31.03», «с 01.01.2025 по 31.03.2025»
- {pattern: '\b3\s*мес|январ\w*\s+(по\s+)?март|\b01\.01(\.\d{2,4})?(\s*г\.?)?\s+(по\s+)?31\.03', quarter: Q1, is_cumulative: true}
- {pattern: 'полугоди|\b6\s*мес|январ\w*\s+(по\s+)?июн|\b01\.01(\.\d{2,4})?(\s*г\.?)?\s+(по\s+)?30\.06', quarter: Q2, is_cumulative: true}
- {pattern: '\b9\s*мес|январ\w*\s+(по\s+)?сентябр|\b01\.01(\.\d{2,4})?(\s*г\.?)?\s+(по\s+)?30\.09', quarter: Q3, is_cumulative: true}
- {pattern: '\b12\s*мес|январ\w*\s+(по\s+)?декабр|\b01\.01(\.\d{2,4})?(\s*г\.?)?\s+(по\s+)?31\.12|годов|\bгод\b', quarter: Q4, is_cumulative: true}
# Год: «за 2024 г.», «2024 год»; год в конце даты («31.03.2025 г.») годом периода не считается
- {pattern: '(?<![\d.])(19|20)\d{2}\s*(г\b|год)', quarter: Q4, is_cumulative: true}
# В тексте периода только год: «2024», «за 2024»
- {pattern: '^\W*(за\s+)?(19|20)\d{2}\W*$', quarter: Q4, is_cumulative: true}
# Год периода: четыре цифры 19xx/20xx, не часть длинного числа (ИНН, номер)
year: '(?<!\d)(19|20)\d{2}(?!\d)'