2026-11-06 20:27:38 +04:00

18 KiB
Raw Permalink Blame History

КФО: §8, DBML v5.26, контракт API — план

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: к утру 09.11.2026 дать Цыганкову (AURORA-1546) и Степанову (AURORA-1547) правила §8 «КФО», модель v5.26 и контракт API КФО, по которым расчёт и экран строятся параллельно.

Architecture: только документы репозитория arm-ka-docs. §8 — алгоритм; DBML — что хранится; контракт — что отдаёт и принимает API; OpenSpec-delta — требования в форме SHALL/сценариев. Числа сквозного примера §8 и examples контракта — одни и те же, считаются одним скриптом в scratchpad, чтобы не разойтись.

Tech Stack: Markdown, DBML, OpenAPI 3.1 (YAML), OpenSpec 1.13.1, make check.

Spec: openspec/changes/kfo-calculation-contract/design.md, proposal.md.

Все пути — от корня worktree /Users/andrey.epifancev/projects/awp-ca/.wt/kfo-contract/docs; команды — из него.

Global Constraints

  • Результат КФО — тыс. руб., строки с двумя знаками; ОСВ и агрегаты — рубли; float нет.
  • cleaned_amount = client_amount − vgo_amount; bank_amount = sum_amount − vgo_amount + goodwill_adjust — на всех строках.
  • Строки расходов, приводимые к −|x|: 2120, 2210, 2220, 2330, 2350.
  • Новый режим правила: min_or_full; правило 2 seed v1: article_2_line: "1310/1350/1370".
  • Новые поля: kfo_result_line_company.client_amount, .vgo_amount; kfo_result.warnings, corrections_count_bb, corrections_count_ofr, corrections_amount_bb, corrections_amount_ofr; audit_action.KFO_EDIT.
  • Коды предупреждений: FORM_MISSING, FORM_AMBIGUOUS, FORM_UNITS_UNKNOWN, LINE_OUTSIDE_BLANK, UNALLOCATED_ROWS, INCOME_RULES_MISSING, GOODWILL_NOT_APPLIED, GOODWILL_ROW_REASSIGNED.
  • Эндпоинты: GET /api/v1/consolidations/versions/{version_id}/kfo (KFO_VIEW), PUT …/kfo/annotations (CONSOLIDATION_EDIT); ошибка UNKNOWN_LINE; units = "thousand_rub".
  • Новые открытые вопросы — с OQ-180 (177 и 179 заняты открытыми PR #195 и #203).
  • Версия модели — v5.26; v5.25 — PR #203 (если слит до нас — строим поверх него, см. design §3).
  • docs/source/** не трогать. Язык — русский; маркеры решений — R-n с номером design-таблицы.

Review Focus

  1. Агрегат с корректировкой, у которого и автосумма > 0 — исключение ровно одно (корректировка), не сумма двух.
  2. Пара гудвилла с G ≤ 0 или выключенным goodwill_enabled — обычный агрегат правила 2, строка GOODWILL = 0.
  3. Расходная строка 2120 положительной в форме одной компании и отрицательной в другой — после приведения Σ по 2120 и итог 2100 сходятся.
  4. Каскад правила 2 при нехватке остатка 1310 и 1350 — остаток целиком на 1370, Σ исключений ДО = исключению ГО 1170.
  5. Версия без форм у части компаний — КФО считается, компания с нулями, FORM_MISSING в warnings.

Каждый пункт — числом в сквозном примере §8 (Task 1) и в одном из examples контракта (Task 3).


Task 1: §8 «КФО», §8 «Корректировка», открытые вопросы

Files:

  • Modify: context/05-domain-rules.md — §8: блок «КФО» заменить; блоки «Корректировка», «Гудвилл» («КФО» в конце), «Пороги» — привести; §5 п. 1 — строка о режиме min_or_full.
  • Modify: context/07-open-questions.md — OQ-180…: открытые вопросы КФО.
  • Create (scratchpad, не в репо): /private/tmp/claude-501/-Users-andrey-epifancev-projects-awp-ca/38dca83c-0de5-4c8e-b11b-50b6f660f3f7/scratchpad/kfo_example.py

Interfaces:

  • Produces: числа сквозного примера (компании «Альфа», «Бета», «Гамма»; таблица исключений, строки 1170, 1230, 1310, 1350, 1370, 1520, 1100, 1300, 1600, 1700, GOODWILL, 2110, 2120, 2100; пороги) — Task 3 копирует их в examples.

  • Step 1: Скрипт сквозного примера. kfo_example.py на Decimal: три компании, агрегаты — правило 6 («Альфа» → «Бета» в допуске 2 %; «Бета» → «Альфа» 20 % с корректировкой, у которой автосумма была бы 0, и ещё один агрегат 6 в допуске 3 % с корректировкой, где итоги сторон 100/90 — проверка «меньшего»); правило 2 «Альфа» → «Бета» с гудвиллом (ФВ, УК, d, P, G > 0); правило 2 «Альфа» → «Гамма» без пары на стороне 2 (min_or_full → amount_1) с нехваткой 1310/1350 — каскад на 1370; ОФР-агрегат 2110 «Альфа» / 2120 «Бета» (у «Беты» 2120 положительное в форме); «Гамма» без ОФР — FORM_MISSING. Скрипт печатает таблицы строк по компаниям и итоги, пороги ББ/ОФР. Assert внутри скрипта: bank(1600) == bank(1700); Σ исключений ДО по правилу 2 = исключению ГО 1170; Σ vgo строки 2100 = 0; у агрегата с корректировкой в vgo нет автосуммы.

  • Step 2: Прогнать скрипт. Run: python3 -I <scratchpad>/kfo_example.py — Expected: таблицы печатаются, ни одного AssertionError.

  • Step 3: Переписать блок «КФО» §8 по design §4.1 п. 1–12 (единицы, строки и редакция бланка, «по данным клиента» и знак расходов, агрегаты, таблица режимов и каскад, корректировка вместо автосуммы, vgo и округление, строка и итоги, гудвилл, расхождения, пороги, реквизиты, пересчёт и заморозка, предупреждения и их хранение), со ссылками на источники (DOC-274230, DOC-259025, DOC-272613, DOC-274636) и пометками «на старте — вариант N, решает заказчик (OQ-nnn)». Сквозной пример — числами из Step 2. Отдельным абзацем — прогон на РБ 01.10.2024 (66н) и ожидаемое расхождение с эталоном по OQ-155.

  • Step 4: Привести соседние блоки §8 и §5. «Корректировка»: агрегат min_or_full — eliminated_amount, exceeds_threshold = false, статусы AUTO / ONE_SIDED; одна функция автосуммы для таблицы корректировок и КФО; «в КФО по выбранным статьям уходит меньшая сумма» — раскрыть по design п. 5. «Гудвилл», абзац «КФО» — ссылка на новый блок, ветка по паре независимо от агрегата, GOODWILL в 1100/1600. «Пороги» — заменить ссылкой на новый блок (дубли формул убрать). §5 п. 1 — mode = min_or_full в псевдокоде.

  • Step 5: OQ-180… в 07-open-questions.md. По одному вопросу на развилку design, которую решает заказчик: строки вне бланка; состав колонок; значение без формы; итоговая строка; округление; место строки гудвилла; совокупный объём расхождений; ЧА — 1300 или расчёт; нулевая база порога; действие при превышении; «подход» по Методике; согласование клиентом; пересчёт автоматически или по кнопке; правило 1 автоматически (follow-up seed). В каждом — источник, «допущение принято: вариант …», ссылка на §8.

  • Step 6: Проверка. Run: grep -n "eliminated_auto (Σ сумм элиминации троек" context/05-domain-rules.md — Expected: пусто (старая формула удалена). Run: grep -c "OQ-18[0-9]" context/07-open-questions.md — Expected: ≥ 10.

  • Step 7: Commit

git add context/05-domain-rules.md context/07-open-questions.md
git commit -m "КФО: §8 под DOC-274230/259025/272613, открытые вопросы OQ-180… (#206)"

Task 2: DBML v5.26 и ссылки на версию

Files:

  • Create: model/data-model-v5.26.dbml (копия v5.24 или v5.25 — см. Global Constraints), model/entities-v5.26.md.
  • Modify: Makefile:9, openspec/config.yaml:4,9, context/00-workspace-layout.md, context/03-architecture.md, context/04-data-model-guide.md, context/08-source-docs-index.md, context/KICKOFF-PROMPT.md, repo-templates/arm-core.CLAUDE.md, analyst/eliminations-vgo.md — ссылки v5.24 → v5.26, где речь о текущей версии.
  • Modify (если npx есть): model/diagrams/part08_corrections_kfo.{svg,png} через make diagrams.

Interfaces:

  • Consumes: формулировки полей из Task 1 (§8).

  • Produces: имена колонок и enum — ровно как в Global Constraints; Task 3 на них ссылается.

  • Step 1: Скопировать модель и записать changelog v5.26 в шапку: 1) kfo_result_line_company + client_amount, vgo_amount; 2) kfo_result + warnings jsonb, четыре поля сводки корректировок; 3) audit_action.KFO_EDIT; 4) elimination_mode — значение min_or_full; 5) пояснения kfo_result_line по §8 (без изменения структуры); 6) миграция — одна в arm-core, AURORA-1546, все новые колонки nullable, откат удаляет колонки, KFO_EDIT при наличии событий не откатывается (как FILE_REPROCESS в v5.21).

  • Step 2: Правки таблиц и enum по design §4.2 — note каждого поля ссылается на §8 п. N.

  • Step 3: entities-v5.26.md — копия с правками разделов kfo_result, kfo_result_line, kfo_result_line_company, audit_event, elimination_rule; шапка — v5.26.

  • Step 4: Ссылки на текущую версию в файлах из списка; в 04-data-model-guide.md — абзац «v5.26».

  • Step 5: Проверка. Run: grep -rn "v5\.24" Makefile openspec/config.yaml context/00-workspace-layout.md context/04-data-model-guide.md — Expected: только исторические упоминания («v5.24: таблица vgo_assignment»), не «текущая». Run: grep -n "client_amount\|KFO_EDIT\|min_or_full\|corrections_count_bb" model/data-model-v5.26.dbml — Expected: все четыре найдены. Если есть npx: make diagrams — Expected: без ошибок, diff part08_*.

  • Step 6: Commit

git add model/ Makefile openspec/config.yaml context/ repo-templates/ analyst/
git commit -m "DBML v5.26: разрез КФО по компании, предупреждения и аудит КФО, режим min_or_full (#206)"

Task 3: Контракт API КФО и правка контракта корректировок

Files:

  • Create: dev/api-contract-kfo.md, dev/api-contract-kfo.openapi.yaml.
  • Modify: dev/api-contract-corrections.md — агрегат min_or_full; dev/frontend-api-guide.md — строка-ссылка на контракт КФО в оглавлении контрактов.

Interfaces:

  • Consumes: числа Task 1 Step 2; имена полей Task 2.

  • Produces: схемы KfoResultOut, KfoLineOut, KfoLineCompanyOut, KfoSummaryOut, KfoRequisitesOut, KfoWarningOut, KfoAnnotationsIn, KfoCommentIn — их берёт 1547 как фейк и 1546 как схему ответа.

  • Step 1: api-contract-kfo.md — структура как у api-contract-goodwill.md: 1 «Общее» (права KFO_VIEW / CONSOLIDATION_EDIT, тыс. руб. и units, порядок проверок правок), 2 «Понятия» (кратко со ссылками на §8 п. N, без повторения формул), 3 «Эндпоинты» (таблица design §4.3, GET и PUT подробно: пересчёт при чтении, заморозка, null очищает, лимиты 2000/4000, UNKNOWN_LINE, аудит KFO_EDIT), 4 «Схемы» (поля с типами и смыслом), 5 «Состояния экрана DOC-274647 → поля ответа», 6 «Примеры» — три ответа (обычный; превышение порога ББ с гудвиллом; замороженный), сокращённые до строк сквозного примера, 7 «Открытые вопросы» — ссылки на OQ-180….

  • Step 2: api-contract-kfo.openapi.yaml — OpenAPI 3.1, два пути, схемы из Interfaces, examples из Step 1 (полные JSON), коды ошибок как в design §4.3; деньги — type: string, pattern: '^-?\d{1,16}\.\d{2}$', nullable через type: [string, "null"].

  • Step 3: Валидация OpenAPI. Run: uv run --with openapi-spec-validator python -I -c "from openapi_spec_validator import validate; from openapi_spec_validator.readers import read_from_filename; validate(read_from_filename('dev/api-contract-kfo.openapi.yaml')[0]); print('ok')" — Expected: ok. Плюс: каждый example проходит свою схему — тот же запуск с jsonschema по components.schemas.KfoResultOut (скрипт в scratchpad) — Expected: ok для трёх примеров.

  • Step 4: Контракт корректировок. В api-contract-corrections.md §2/§3.1: для правила с elimination_mode = min_or_full — eliminated_amount по §8, exceeds_threshold = false, статус AUTO / ONE_SIDED; сноска «изменение кода — AURORA-1546». Проверить, что в api-contract-corrections.openapi.yaml описание поля status / eliminated_amount не противоречит (поправить описание, не схему).

  • Step 5: Commit

git add dev/
git commit -m "КФО: контракт API (dev/api-contract-kfo.*), агрегат min_or_full в контракте корректировок (#206)"

Task 4: OpenSpec-delta, проверка, PR, вложения в Jira

Files:

  • Create: openspec/changes/kfo-calculation-contract/specs/arm-core/spec.md, openspec/changes/kfo-calculation-contract/tasks.md.

  • Step 1: Spec delta — ## ADDED Requirements в capability arm-core: «Расчёт КФО версии» (сценарии: агрегат с корректировкой; гудвилл G > 0 и G ≤ 0; каскад правила 2; форма отсутствует; приведение знака расходов), «Чтение результата КФО» (пересчёт при чтении, заморозка), «Ручные поля КФО» (сохранение, null очищает, UNKNOWN_LINE, аудит KFO_EDIT), «Автосумма агрегата min_or_full» (таблица корректировок и КФО совпадают). tasks.md — четыре задачи этого плана с отметками.

  • Step 2: Проверка репозитория. Run: make validate-openspec CHANGE=kfo-calculation-contract — Expected: valid. Run: make check — Expected: все цели зелёные.

  • Step 3: Финальное ревью ветки (сабагент opus, только чтение): §8 ↔ DBML ↔ контракт — одни имена и числа; Review Focus 1–5 покрыты; ни одной развилки заказчика без пометки. Находки C-n/I-n/M-n — исправить или deferred в design.md.

  • Step 4: Push и PR — git push -u origin feat/206-kfo-contract; tea pulls create --login home --repo RSHB/arm-ka-docs --head feat/206-kfo-contract --base main с описанием: что и зачем, Closes #206, порядок с #203, «Rulings» (design §6), таблица находок. Merge — только по команде владельца.

  • Step 5: Вложения в Jira — пакет batch_create: AURORA-1546 — context/05-domain-rules.md, model/data-model-v5.26.dbml; AURORA-1547 — dev/api-contract-kfo.md, dev/api-contract-kfo.openapi.yaml; в обе — комментарий голосом владельца со ссылкой на PR (что смотреть: §8 «КФО» / контракт, открытые вопросы OQ-180…). Expected: все команды пакета done.