Andrey Epifancev dd454983e6 openspec: спека Среза 3b — формы ББ/ОФР в ядре и API до сводной ОСВ (#36)
proposal, design (D-1…D-14, решения без обсуждения №1–10), дельты osv-result-mapping (маппинг форм, статус),
statement-checks (новая: §7, межформенная, акцепт), documents-api (форма, правка, акцепт, подтверждение, комментарии,
исходный файл), consolidations-api (CSV чек-листа), directories-api (documents_count), users-admin (справочник имён).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-07 08:21:57 +04:00

4.7 KiB
Raw Blame History

Spec Delta: statement-checks

Purpose

Логические проверки форм ББ/ОФР §7 в ядре: чистые функции над текущими суммами документа, без хранения результата; акцепт непройденных проверок аналитиком.

ADDED Requirements

Requirement: Соотношения §7 по колонкам

Проверки SHALL считаться чистой функцией по текущим financial_statement_value.amount документа для каждой колонки отдельно по словарю api/rules/statement_checks.yaml (копия словаря tabular-parser): соотношение проверяется, только если присутствует его левая часть; отсутствующий код и пустая сумма — 0; выполнено, если |левая − правая| ≤ tolerance (1, в единицах формы) хотя бы в одном варианте правой части — как записано или с кодами abs_terms по модулю. Нарушение жёсткого (strict) соотношения, не превышающее rounding_tolerance_percent (0,001 %) от наибольшего по модулю числа соотношения, SHALL считаться мягким («в пределах округления»). Мягкие: соотношения strict: false и «сумма пятизначных подстрок = четырёхзначный родитель». Результат — {failed: [...], soft_failed: [...]}, элемент — {column_index, relation, expected, actual}; MUST NOT храниться в БД.

Scenario: Сходящийся баланс

  • WHEN проверяется форма mezheninovskaya/2025-Q3/1_Форма1_бух_09
  • THEN failed пуст

Scenario: Нарушение жёсткого соотношения

  • WHEN у баланса 1600 = 1000, 1100 = 300, 1200 = 600 в колонке 0
  • THEN failed содержит {column_index: 0, relation: "1600 = 1100 + 1200", expected: 1000, actual: 900}

Scenario: Расходы со знаком минус

  • WHEN ОФР 2110 = 100, 2120 = −60, 2100 = 40
  • THEN 2100 = 2110 − 2120 выполнено через вариант с abs_terms

Scenario: Правка исправляет нарушение

  • WHEN аналитик правит 1200 с 600 на 700 в форме из предыдущего сценария
  • THEN проверка по текущим суммам: failed пуст

Requirement: Межформенная проверка

Для документа BALANCE или INCOME SHALL считаться мягкая проверка 1370(колонка отчётной даты ББ) − 1370(колонка 31 декабря прошлого года ББ) = 2400(колонка отчётного периода ОФР) с допуском tolerance, если найдена форма-пара: документ другого типа формы того же ЮЛ, period_year и period_quarter, файла не SUPERSEDED (подтверждённый, затем самый поздний по created_at), и все три колонки. Нарушение SHALL попадать в cross_form и MUST NOT блокировать подтверждение.

Scenario: Пара найдена

  • WHEN у ЮЛ ББ за 2025 Q3 (1370 = 500 на 30.09.2025, 300 на 31.12.2024) и ОФР за 2025 Q3 (2400 = 150)
  • THEN cross_form — нарушение expected 200, actual 150; подтверждение ББ разрешено

Scenario: Пары нет

  • WHEN у ЮЛ есть только ББ за период
  • THEN cross_form — null

Requirement: Акцепт непройденных проверок

Акцепт SHALL записывать financial_statement_meta.checks_accepted_by, checks_accepted_at, checks_accepted_comment; документ с акцептом SHALL считаться прошедшим жёсткие проверки для статуса и подтверждения. Любая правка значений или шапки формы SHALL сбрасывать акцепт (три поля — NULL).

Scenario: Акцепт и правка

  • WHEN аналитик акцептовал нарушение 1600 и затем поправил любое значение
  • THEN поля акцепта пусты, при непройденной проверке документ NEEDS_CHECK