Andrey Epifancev 0e95f95c71 docs(openspec): change intercompany-matrix-presets + README (ревью #141)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 14:08:08 +04:00

6.7 KiB
Raw Blame History

Context

Реализация — PR RSHB/arm-core#141 (ветка add-preset-shahmatka). Шахматка — чистая функция от сводной ОСВ версии, периметра и выбранных счетов; в БД не хранится (DECISION-5). Корректировки (correction) — хранимые ручные решения, читаются, но в ядре пока никем не создаются.

Decisions

  1. Режим PRESET берёт правило по rule_id. Правило должно быть действительно для версии: при зафиксированном elimination_rules_version — совпадать по version_no, иначе — иметь valid_to IS NULL; иначе 404.
  2. Сторона дебета — company_1, если side_1 = D, иначе company_2; кредит — вторая сторона. Счета и исключения раскрываются по иерархии (_select_accounts), как в MANUAL. Нет счетов хотя бы одной стороны — 422 ACCOUNTS_REQUIRED; неверные side_1/measure/company_no — 422 INVALID_RULE; не передан rule_id — 422 RULE_REQUIRED.
  3. Показатель (closing/turnover) берётся из правила; ALL и MANUAL остаются на closing.
  4. Применённые корректировки правила (status = APPLIED, тот же rule_id и версия консолидации) уменьшают amount_a ячейки (A, B) на debit_adjustment корректировки (legal_entity_id = A, counterparty_id = B) и amount_b на credit_adjustment корректировки (B, A); расхождение, процент и порог пересчитываются, ID корректировок попадают в correction_ids_debit/credit.
  5. unpaired-osv строится из one_sided-ячеек шахматки пресета (osv_entry_ids_*) и возвращает строки сводной ОСВ, содержащие эти записи.
  6. GET …/elimination-rules отдаёт объект с основанием выбора версии; as_of не вводится.
  7. xlsx пресета: имя intercompany-matrix_<ГК>_<год>-<квартал>_v<n>_preset-<rule_id>.xlsx, в шапке «Режим = Пресет», коды счетов сторон (отсортированы) и строка «Показатель» (Сальдо/Оборот) для всех режимов.

Known issues / вопросы владельцу

Спека описывает фактическое поведение PR; пункты ниже не закреплены как окончательные и ждут решения автора и владельца.

  1. При пустом consolidation_version.elimination_rules_version берутся текущие открытые правила. Это расходится с DBML («фиксируется при первом расчёте, замораживается при VERIFIED») и критерием AURORA-1536; нужно решение владельца, в том числе для версий в статусе VERIFIED.
  2. «Актуальные» правила — valid_to IS NULL на сегодня, а не на отчётную дату консолидации.
  3. Если открытыми остаются несколько version_no, список правил даёт дубли rule_no.
  4. Семантика корректировки: (rule, A, B) дебетовой частью правит ячейку (A, B), кредитовой — ячейку (B, A); debit_account_id, credit_account_id и parent_correction_id не учитываются; корректировки в ядре пока никто не создаёт.
  5. unpaired-osv построена на one_sided по наличию строк — это дефект AURORA-1651, и «без пары» здесь не равно «без пары» по §5 и AURORA-1536.
  6. Пресет здесь — правило Прил. 3, а §6 описывает пресеты как наборы счетов; PRESET по ОФР на оборотах (measure = turnover) не подтверждён §5/§6.
  7. Имя файла содержит UUID правила, шапка xlsx не содержит номер правила и версию; audit не пишет номер/версию правил и ID применённых корректировок.

Decisions made without discussion

  • 2026-10-21. Change пишет ревьюер в ветке автора по решению владельца. Обоснование: автор не оформила OpenSpec. Цена ошибки: автор переписывает change.
  • 2026-10-21. Спека описывает фактическое поведение PR; спорное вынесено в Known issues. Обоснование: домен решает автор и владелец, не ревьюер. Цена ошибки: после решения владельца спека меняется дельтой.
  • 2026-10-21. Поле as_of удалено из EliminationRulesOut как мёртвое: после правок по ревью всегда None, в main его не было, потребителей нет. Цена ошибки: если фронт ждал as_of, поле нужно вернуть.
  • 2026-10-21. Интеграционный тест test_preset_uses_current_rules_when_version_unfixed приведён к фактическому поведению (version_no is None, is_version_fixed is False), а не к старому ожиданию version_no == rule.version_no; логика вычисления version_no не добавлялась. Цена ошибки: если автор решит возвращать номер версии, тест вернуть.
  • 2026-10-21. mypy: measure аннотирован Measure без cast; слишком длинная f-строка имени файла свода ОСВ (consolidated_osv.py) разбита на две без изменения результата (ruff E501). Цена ошибки: нулевая.
  • 2026-10-21. В MODIFIED-блоке требования про правила элиминации и аудит экспорта приведён полный текст; требование «XLSX шахматки» (ALL/MANUAL) не менялось, поведение PRESET описано отдельным ADDED-требованием.