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

60 lines
6.7 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.

## 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-требованием.