From e70f589112b3c3f11978caff079a913d7c217ec1 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Fri, 23 Oct 2026 18:34:21 +0400 Subject: [PATCH] =?UTF-8?q?DBML=20v5.23=20(elimination=5Frules=5Fversion?= =?UTF-8?q?=20NOT=20NULL),=20=C2=A75=20=D0=B1=D0=B5=D0=B7=20=D0=BA=D0=B0?= =?UTF-8?q?=D1=81=D0=BA=D0=B0=D0=B4=D0=B0,=20=D0=BF=D0=B0=D1=80=D1=8B=20?= =?UTF-8?q?=D0=92=D0=93=D0=9E=20=D0=BF=D0=BE=20=D0=B2=D0=B5=D1=80=D1=81?= =?UTF-8?q?=D0=B8=D0=B8=20(#164,=20AURORA-1536)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Решения владельца 23.10.2026 по ревью arm-core #175: - consolidation_version.elimination_rules_version — not null, существующим версиям номер проставляет миграция по дате создания; - §5: каскад по остатку отменён (21.10), правила считаются отдельно до разнесения строк AURORA-1751; суммы сторон со знаком, при min <= 0 процент не считается; отрицательные строки в упаковку не идут (NEGATIVE_AMOUNT); группы сортируются по проценту расхождения; выдача — список троек версии и детализация тройки; - OQ-173, OQ-174, OQ-175; страница аналитика; гайд фронта §5.7.2; ссылки на модель и диаграммы — v5.23. Co-Authored-By: Claude Opus 5.5 --- Makefile | 2 +- analyst/eliminations-vgo.md | 49 +- context/00-workspace-layout.md | 2 +- context/03-architecture.md | 6 +- context/04-data-model-guide.md | 6 +- context/05-domain-rules.md | 75 +- context/07-open-questions.md | 6 +- context/08-source-docs-index.md | 4 +- context/KICKOFF-PROMPT.md | 6 +- dev/frontend-api-guide.md | 30 + model/data-model-v5.23.dbml | 1546 +++++++++++++++++++++++ model/diagrams/part07_consolidation.png | Bin 529351 -> 529795 bytes model/diagrams/part07_consolidation.svg | 4 +- model/diagrams/part09_audit_ex.svg | 2 +- model/entities-v5.23.md | 246 ++++ openspec/config.yaml | 4 +- repo-templates/arm-core.CLAUDE.md | 2 +- 17 files changed, 1910 insertions(+), 80 deletions(-) create mode 100644 model/data-model-v5.23.dbml create mode 100644 model/entities-v5.23.md diff --git a/Makefile b/Makefile index 924fd6c..d872437 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ PY := $(if $(wildcard $(VENV)/bin/python),$(CURDIR)/$(VENV)/bin/python,python3) # Пусто — проверяются все change'и и спеки; `make validate-openspec CHANGE=` — один change CHANGE ?= # Текущая версия модели данных — по ней рисуются диаграммы (make diagrams) -DBML ?= model/data-model-v5.22.dbml +DBML ?= model/data-model-v5.23.dbml .PHONY: venv validate-contracts validate-openspec test-snapshot test-sync-statements sync-statements statements-check check diagrams diff --git a/analyst/eliminations-vgo.md b/analyst/eliminations-vgo.md index b94c34e..0776c87 100644 --- a/analyst/eliminations-vgo.md +++ b/analyst/eliminations-vgo.md @@ -1,7 +1,7 @@ # Элиминация ВГО: правила, расчёт, корректировки Документ для аналитика, 19.10.2026 (RSHB/arm-ka-docs#132; сопоставление — по решениям OQ-07 и OQ-173, #136). Основа — модель данных -[`model/data-model-v5.19.dbml`](../model/data-model-v5.19.dbml) и правила предметной области +[`model/data-model-v5.23.dbml`](../model/data-model-v5.23.dbml) и правила предметной области [`context/05-domain-rules.md`](../context/05-domain-rules.md) §3–§6, §8. Источник истины — они: при расхождении прав DBML и `05-domain-rules.md`, а этот документ поправь следом. Где написано наше прочтение ТЗ, а не прямая цитата, это помечено; такие места собраны в раздел 6 вопросами. @@ -90,8 +90,9 @@ DBML и `05-domain-rules.md`, а этот документ поправь сле ### 2.3. Версии правил Правила меняются выпуском новой версии (`version_no`), старая не правится. Версия, по которой посчитана версия -консолидации, фиксируется в `consolidation_version.elimination_rules_version` при первом расчёте и замораживается при -`VERIFIED` — так расчёт верифицированной версии объясним и воспроизводим, даже если правила потом поменялись. +консолидации, фиксируется в `consolidation_version.elimination_rules_version` при создании версии (версия правил, +действующая на дату создания, OQ-174; с DBML v5.23 поле обязательно) и дальше не меняется — так расчёт объясним и +воспроизводим, даже если правила потом поменялись. ### 2.4. Стартовый набор — Прил. 3 (ББ, `measure = closing`) @@ -135,38 +136,36 @@ DBML и `05-domain-rules.md`, а этот документ поправь сле компаний — и (A, B), и (B, A), поэтому зеркальные правила № 9–16 Прил. 3 отдельно не заводятся (№ 14 для (A, B) — это № 6 для (B, A)). У тройки два уровня (решения владельца 19.10.2026, OQ-07 и OQ-173): -**Сумма элиминации** — агрегат, идёт в КФО. Считается **каскадом по остатку**: правила пары (A, B) идут по порядку -`rule_no`, каждое берёт min из того, что осталось после предыдущих правил: +**Сумма элиминации** — агрегат, идёт в КФО. Каждое правило считается **отдельно** (каскад по остатку отменён решением +владельца 21.10.2026 по созвону с заказчиком 19.10.2026): ``` -для правил по возрастанию rule_no: - ΣA = Σ остатка строк A с контрагентом B по счетам стороны 1 (с исключениями) - ΣB = Σ остатка строк B с контрагентом A по счетам стороны 2 - deviation_amount = |ΣA − ΣB|; deviation_percent = deviation_amount / min(ΣA, ΣB) × 100 - элиминация = min(ΣA, ΣB) при расхождении ≤ 5 % (раздел 3.3); остатки сторон уменьшаются на неё +ΣA = Σ строк A с контрагентом B по счетам стороны 1 (с исключениями), со знаком +ΣB = Σ строк B с контрагентом A по счетам стороны 2, со знаком +deviation_amount = |ΣA − ΣB|; deviation_percent = deviation_amount / min(ΣA, ΣB) × 100 +элиминация = min(ΣA, ΣB) при расхождении ≤ 5 % (раздел 3.3) ``` -Зачем каскад: счета правил пересекаются (дебиторка у № 5–8 общая; 67.03 входит и в № 3, и в маску 67 у № 7; 66.03 — в -№ 4 и в № 8). По буквальным формулам Прил. 3 одна дебиторка элиминировалась бы несколько раз. Порядок `rule_no` в Прил. 3 -уже идёт от частного к общему (№ 3/4 раньше № 7/8, № 5 раньше № 6, № 6 → 7 → 8), а сам принцип «списывать по очереди до -обнуления» Прил. 3 задаёт в правиле № 1. +Суммы — **со знаком**, как в шахматке (решение владельца 23.10.2026): отрицательное сальдо строки — встречная позиция +(аванс, переплата), у A по B строки 150 и −50 дают ΣA = 100. -Пример: у A дебиторка на B 100; у B кредиторка на A 70 и долгосрочный заём (67) на A 50. Буквально: № 6 = 70, -№ 7 = 50, итого 120 — больше самой дебиторки. Каскадом: № 6 = 70, остаток A = 30; № 7 = min(30, 50) = 30; итого 100; -20 по 67 у B — расхождение, разбирается корректировкой. +Счета правил пересекаются (дебиторка у № 5–8 общая; 67.03 входит и в № 3, и в маску 67 у № 7; 66.03 — в № 4 и в № 8), +поэтому строка такого счёта пока учитывается в **каждом** подходящем правиле, и сумма по паре компаний может превысить +сумму стороны. Двойной учёт снимается разнесением строк по правилам и ручным переносом между правилами (AURORA-1751). **Упаковка строк** — какие строки ОСВ с какими сопоставлены (детализация и строки без пары). Правило охватывает несколько счетов, поэтому строки сопоставляются группами **1:1, 1:N, N:1**; N:M нет, N ≤ 5. Выбирается **минимальная упаковка** — группа с меньшим числом строк: если сумму закрывают и «1 Дт ↔ 2 Кт», и «1 Дт ↔ 3 Кт», берётся 1:2. ``` -правила пары — по возрастанию rule_no; строка, сопоставленная в раннем правиле, в следующих не участвует +каждое правило — отдельно; строки с суммой > 0 по счетам правила +строки с отрицательной суммой → «без пары», разбирает аналитик; с нулевой → «без пары» для k = 2 … 6 (число строк группы: 1:1, затем 1:2 и 2:1, … до 1:5 и 5:1): кандидаты размера k из ещё не сопоставленных строк, закрывающие сумму: - сначала точные, затем с расхождением ≤ 5 % к меньшей — по возрастанию расхождения + сначала точные, затем с расхождением ≤ 5 % к меньшей — по возрастанию процента расхождения группа без соперников → пара, её строки выбывают - две и более группы с тем же k и тем же расхождением, делящие строку → на ручное (между правилами ничьей нет) -строки, не сопоставленные ни одним правилом → «без пары» + две и более группы с тем же k и тем же процентом, делящие строку → на ручное +строки, не вошедшие ни в одну группу → «без пары» ``` Способ упаковки сумму элиминации не меняет: в КФО идёт агрегат тройки. @@ -184,8 +183,8 @@ DBML и `05-domain-rules.md`, а этот документ поправь сле | нет второй стороны (ΣB = 0) | элиминируется 0, строки — «без пары» (вопрос В-4) | | правило с `mode = manual` (№ 1, № 2) | автоматически не элиминируется, только корректировкой / гудвиллом | -Суммы сторон — остатки после предыдущих правил пары (каскад, раздел 3.2), поэтому двойной элиминации по общим счетам -нет. +Каждое правило считается отдельно, поэтому строка общего счёта пока входит в суммы нескольких правил (раздел 3.2) — +двойной учёт снимается разнесением строк (AURORA-1751). Алгоритм — по ТЗ (решение владельца 08.10.2026, OQ-155): пары, `min`, порог 5 %. Эталонный Excel «Консолидация_Группа РБ» элиминирует у каждой компании полную сумму её строк на группу — это сознательное расхождение с эталоном. @@ -300,7 +299,7 @@ vgo_amount = eliminated_auto + eliminated_manual **Сумма элиминации (правило № 6):** ΣA = 110 429 113,15, ΣB = 106 311 116,46, расхождение 3,87 % ≤ 5 % → элиминируется `min` = 106 311 116,46: статья 1230 у Счастливочной, 1520 у РБ. Это при условии, что у РБ нет 66.04 / 67.04 -на Счастливочную: иначе по каскаду 76.06 и 76.АВ сначала уйдут в правило № 5, и ΣA правила № 6 уменьшится. +на Счастливочную: иначе 76.06 и 76.АВ войдут и в правило № 5 — двойной учёт до разнесения строк (AURORA-1751). **76.АВ** (НДС по авансам) сейчас входит в дебиторку по правилу «76 кроме 76.07.5/76.07.9». Эталон его исключает — вопрос OQ-164 (В-9). @@ -325,4 +324,4 @@ vgo_amount = eliminated_auto + eliminated_manual | В-9 | 76.АВ / 76.ВА (НДС по авансам) — исключать из ДЗ / КЗ? Есть ли ещё такие субсчета 76? | OQ-164 открыт, вопрос в AURORA-1373 | | В-10 | Округление при элиминации: рубли → тыс. руб. на выходе, ROUND_HALF_UP? | допущение OQ-26 | | В-11 | Правило № 1: если у компании А нет ОСВ по 03 — результат в строку «ППА»? | открыто в §4 | -| В-12 | ~~Счета правил пересекаются — как избежать двойной элиминации?~~ | **решено 19.10.2026 (OQ-173):** каскад по остатку в порядке `rule_no` (раздел 3.2) | +| В-12 | ~~Счета правил пересекаются — как избежать двойной элиминации?~~ | **решено 21.10.2026:** каскад по остатку отменён, правила считаются отдельно, двойной учёт снимает разнесение строк по правилам (AURORA-1751, раздел 3.2) | diff --git a/context/00-workspace-layout.md b/context/00-workspace-layout.md index 290510b..f7a6894 100644 --- a/context/00-workspace-layout.md +++ b/context/00-workspace-layout.md @@ -76,7 +76,7 @@ git remote add origin && git push -u origin main | Слой | Где | Статус | Правило для агента | |---|---|---|---| -| Модель данных | `docs/model/data-model-v5.22.dbml` | стабильный, версионируется | единственный источник имён и структур | +| Модель данных | `docs/model/data-model-v5.23.dbml` | стабильный, версионируется | единственный источник имён и структур | | Правила домена | `docs/context/05-domain-rules.md` | курируемый — пишет человек/агент по итогам ревью | **единственный вход алгоритмов в код**; из ТЗ напрямую не кодируем | | Открытые вопросы | `docs/context/07-open-questions.md` | живой реестр | каждое допущение в коде — `ASSUMPTION(OQ-nn)` | | Экспорт ТЗ | `docs/source/tz/` | снимок на дату из `docs/source/tz/_export.md` | читать для контекста; расхождение с §05 → вопрос, не код | diff --git a/context/03-architecture.md b/context/03-architecture.md index da98595..1d8a8bf 100644 --- a/context/03-architecture.md +++ b/context/03-architecture.md @@ -1,4 +1,4 @@ -# 03. Архитектура (целевая, по решениям DECISION-1…5 и ARCH-* в DBML v5.22) +# 03. Архитектура (целевая, по решениям DECISION-1…5 и ARCH-* в DBML v5.23) ## Компоненты (= репозитории, см. `00-workspace-layout.md`) @@ -251,7 +251,7 @@ api/src/ # машины статусов, policy — pydantic-модели на входе и выходе services/ # use-cases: оркестрация domain + repositories + outbox + audit_event repositories/ # SQLAlchemy-запросы, в т. ч. запросы-вычисления (сводная ОСВ, шахматка) - models/ # ORM 1:1 с DBML v5.22; имена таблиц/колонок/enum — как в DBML + models/ # ORM 1:1 с DBML v5.23; имена таблиц/колонок/enum — как в DBML schemas/ # pydantic DTO API /api/v1 core/ # config, clients (S3; NATS outbox-publisher и result-consumer), auth (JWT РАИСА / dev-эмитент), # logger, exception_handlers @@ -341,7 +341,7 @@ FastAPI» платформы РАИСА/aurora): дерево импортиро `version_table_schema` и `include_name` Alembic). Следуем шаблону, не `public`. - Alembic берёт URL из настроек, не из `alembic.ini`; ревизии — `api/alembic/versions/`, имя файла стандартное `_.py`. Автогенерация — только черновик: итоговую ревизию сверяет с DBML `api/scripts/check_dbml_vs_orm.py`. -- PK везде `uuid` через `UUIDPrimaryMixin`; имена таблиц, колонок и enum'ов — ровно как в DBML v5.22. +- PK везде `uuid` через `UUIDPrimaryMixin`; имена таблиц, колонок и enum'ов — ровно как в DBML v5.23. ### Инфраструктурные клиенты diff --git a/context/04-data-model-guide.md b/context/04-data-model-guide.md index 518f362..deab41d 100644 --- a/context/04-data-model-guide.md +++ b/context/04-data-model-guide.md @@ -1,6 +1,6 @@ -# 04. Как читать модель данных v5.22 +# 04. Как читать модель данных v5.23 -Файлы: `docs/model/data-model-v5.22.dbml` (источник истины), `docs/model/entities-v5.22.md` (смысл таблиц; предыдущие +Файлы: `docs/model/data-model-v5.23.dbml` (источник истины), `docs/model/entities-v5.23.md` (смысл таблиц; предыдущие версии `data-model-v5.13…v5.20.dbml` и `entities-v5.13…v5.20.md` остаются как история), `docs/model/diagrams/part01…09.{svg,png}` (диаграммы v5.21 по частям из таблицы ниже; перерисовываются из DBML командой `make diagrams` в корне репозитория docs — скрипт `scripts/gen_model_diagrams.py`, нужен npx; при новой версии DBML @@ -20,6 +20,8 @@ | 08 Корректировки и КФО | `correction`, `goodwill`, `kfo_result`, `kfo_result_line`, `kfo_result_line_company`, `client_kfo_line` | ручные решения и результат | | 09 Комментарии, аудит, ЕХ | `comment`, `audit_event`, `ex_snapshot`, `ex_snapshot_member`, `ex_snapshot_item` | полиморфные комментарии, append-only журнал, замороженные срезы | +**v5.23:** `consolidation_version.elimination_rules_version` — `not null`: версия правил элиминации, действующая на дату создания версии консолидации, фиксируется при создании; существующим версиям проставляется миграцией (AURORA-1536). + **v5.22:** из описания `comment.object_type` убраны `chess_cell` и `kfo_result_line`, сохранены `document | consolidation_version | …`; структура БД не меняется, миграция не требуется (AURORA-1446). **v5.21:** повторная обработка файла пишется в журнал своим событием `audit_action.FILE_REPROCESS` (раздел diff --git a/context/05-domain-rules.md b/context/05-domain-rules.md index 10a641e..4ca605c 100644 --- a/context/05-domain-rules.md +++ b/context/05-domain-rules.md @@ -496,9 +496,10 @@ closing_* = closing_* строки Qn Хранятся как данные: `elimination_rule` (+ `elimination_rule_account`), версионируются; версия фиксируется в `consolidation_version.elimination_rules_version`. Для версии консолидации берётся версия правил, **действующая на дату -составления консолидации** (создания версии), а не на её отчётный период; фиксируется при создании версии или первом -расчёте, не в GET-запросе (OQ-174, решение владельца 21.10.2026; реализация — AURORA-1536). Пока поле пусто, расчёты -берут открытые правила (`valid_to IS NULL`). Seed-набор для ББ (`statement_type = balance`, `measure = closing`): +составления консолидации** (создания версии), а не на её отчётный период; фиксируется при создании версии и дальше не +меняется (OQ-174, решение владельца 21.10.2026). С DBML v5.23 поле обязательно (решение владельца 23.10.2026, AURORA-1536): +версия консолидации без действующих правил не создаётся, у версий, созданных раньше, номер проставлен миграцией по дате +создания. Seed-набор для ББ (`statement_type = balance`, `measure = closing`): | № | Статья А (Дт) | Счета А (closing_debit) | Статья Б (Кт) | Счета Б (closing_credit) | mode | Примечание | |---|---|---|---|---|---|---| @@ -530,10 +531,11 @@ closing_* = closing_* строки Qn --- -## §5. Автоматическое сопоставление ВГО (DOC-223044; OQ-07, OQ-173 — решения владельца 19.10.2026) +## §5. Автоматическое сопоставление ВГО (DOC-223044; OQ-07, OQ-173 — решения владельца 19.10, 21.10 и 23.10.2026) Границы: только `closing_debit` / `closing_credit`; только компании периметра версии; правила и счета сторон — из §4 -(версия правил — `consolidation_version.elimination_rules_version`); строки `group_type = COUNTERPARTY`, +(версия правил — `consolidation_version.elimination_rules_version`), только правила ББ (`statement_type = balance`, +`measure = closing`; правило с другим показателем — ошибка `INVALID_RULE`); строки `group_type = COUNTERPARTY`, `data_type ∈ (BU, SUM)`. Единица расчёта — **тройка** (правило r, компания A, компания B). Правила считаются для каждой упорядоченной пары компаний — и (A, B), и (B, A); поэтому зеркальные правила № 9–16 Прил. 3 в seed не нужны (№ 14 для (A, B) — это № 6 для (B, A)). @@ -541,53 +543,56 @@ closing_* = closing_* строки Qn Два уровня: **сумма элиминации** по тройке — агрегат, идёт в КФО; **упаковка** — какие строки ОСВ с какими сопоставлены (детализация, строки без пары). Способ упаковки сумму элиминации не меняет (решение владельца 19.10.2026). -**1. Сумма элиминации по тройке — каскадом по остатку** (AURORA-1536; OQ-173). Счета правил пересекаются (дебет -№ 5–8 общий; кредит 67.03 — № 3 и маска 67 у № 7, 66.03 — № 4 и маска 66 у № 8), и по буквальным формулам Прил. 3 одна -и та же сумма элиминировалась бы несколькими правилами. Поэтому правила пары (A, B) считаются **по порядку `rule_no`**, и -каждое берёт min из **остатка** сторон после предыдущих — тот же принцип, что Прил. 3 задаёт в правиле № 1 («сначала из -1450 до обнуления, остаток — из 1150, затем из 1550»). Порядок `rule_no` в Прил. 3 уже идёт от частного к общему: -№ 3/4 (58.03 ↔ 67.03 / 66.03) раньше № 7/8 (↔ 67 / 66), № 5 (76 ↔ проценты 66.04/67.04) раньше № 6 (↔ кредиторка), -№ 6 → № 7 → № 8 (дебиторка гасится кредиторкой, потом долгосрочными, потом краткосрочными займами). Отдельное поле -порядка не нужно. +**1. Сумма элиминации по тройке — каждое правило отдельно.** Каскад по остатку в порядке `rule_no` **отменён** (решение +владельца 21.10.2026 по созвону с заказчиком 19.10.2026, OQ-173): счета правил пересекаются (дебет № 5–8 общий; кредит +67.03 — № 3 и маска 67 у № 7, 66.03 — № 4 и маска 66 у № 8), и строка такого счёта пока входит в Σ **каждого** подходящего +правила. Двойной учёт снимает разнесение строк по правилам и ручной перенос между правилами (AURORA-1751); до него +сумма элиминации по паре компаний может превышать сумму стороны — это известное ограничение, не дефект. ``` -остаток(строка) = сумма строки (сторона side_1 у A по B, противоположная у B по A) -для r по возрастанию rule_no: - ΣA = Σ остатка строк A с counterparty_id = B по счетам стороны 1 правила r (с исключениями is_excluded) - ΣB = Σ остатка строк B с counterparty_id = A по счетам стороны 2 правила r - deviation_amount = |ΣA − ΣB|; deviation_percent = deviation_amount / min(ΣA, ΣB) * 100 - mode = min: расхождение ≤ 5 % → элиминация_r = min(ΣA, ΣB); > 5 % → подсветка, элиминация_r = 0, ждёт корректировки - mode = manual: элиминация_r = 0 — только корректировка / гудвилл (§8) - остаток строк правила r на каждой стороне уменьшается на элиминация_r (по строкам — в порядке упаковки п. 2, - затем нераспределённые; на сумму КФО порядок внутри стороны не влияет) +ΣA = Σ строк A с counterparty_id = B по счетам стороны 1 правила r (с исключениями is_excluded), сумма стороны side_1 +ΣB = Σ строк B с counterparty_id = A по счетам стороны 2 правила r, противоположная сторона +deviation_amount = |ΣA − ΣB|; deviation_percent = deviation_amount / min(ΣA, ΣB) * 100 +mode = min: расхождение ≤ 5 % → элиминация_r = min(ΣA, ΣB); > 5 % → подсветка, элиминация_r = 0, ждёт корректировки +mode = manual: элиминация_r = 0 — только корректировка / гудвилл (§8) ``` -Пример: у A дебиторка на B 100; у B кредиторка на A 70 и долгосрочный заём (67) на A 50. Буквально по Прил. 3: -№ 6 = 70, № 7 = 50, итого 120 — больше самой дебиторки. Каскадом: № 6 = min(100, 70) = 70, остаток A = 30; -№ 7 = min(30, 50) = 30; итого 100; 20 по 67 у B — расхождение пары, разбирается корректировкой. +**Знак** (решение владельца 23.10.2026): суммы сторон — **со знаком**, как в шахматке §6 (одно правило и одна пара дают +одинаковые ΣA и ΣB на обоих экранах). Отрицательное сальдо строки (§1: возможно) — встречная позиция, например аванс или +переплата: у A по B строки 150 и −50 дают ΣA = 100, а не 200. Если `min(ΣA, ΣB) ≤ 0` (одна сторона пуста или ушла в +минус), процент не считается (`null`), элиминация 0, тройка подсвечивается при любом расхождении — разбирает аналитик +(в шахматке тот же случай — OQ-175). **2. Упаковка строк в тройке** — группами **1:1, 1:N, N:1** (правило охватывает несколько счетов, поэтому одной строке на одной стороне могут соответствовать несколько строк на другой). N:M нет. Выбирается **минимальная упаковка** — -группа с меньшим числом строк: если сумму закрывают и «1 Дт ↔ 2 Кт», и «1 Дт ↔ 3 Кт», берётся 1:2. +группа с меньшим числом строк: если сумму закрывают и «1 Дт ↔ 2 Кт», и «1 Дт ↔ 3 Кт», берётся 1:2. Каждое правило +упаковывается независимо (каскада нет): строка может войти в пары разных правил, пока её не разнесли (AURORA-1751). ``` -правила пары (A, B) — по возрастанию rule_no; строка, сопоставленная в раннем правиле, в следующих не участвует -вход правила r: ещё не сопоставленные строки a стороны 1 (A → B) и b стороны 2 (B → A) по счетам правила r +вход правила r: строки a стороны 1 (A → B) и b стороны 2 (B → A) по счетам правила r с суммой > 0 + строки с суммой < 0 в упаковку не идут → «без пары», причина NEGATIVE_AMOUNT (разбирает аналитик) + строки с суммой 0 → «без пары», причина ZERO_AMOUNT для k = 2 … 6 (число строк группы: 1:1, затем 1:2 и 2:1, … до 1:5 и 5:1; N ≤ 5): кандидаты размера k из ещё не сопоставленных строк, «закрывающие» сумму: - точные (Σ одной стороны == Σ другой), затем с расхождением ≤ 5 % к меньшей — по возрастанию расхождения + точные (Σ одной стороны == Σ другой), затем с расхождением ≤ 5 % к меньшей — по возрастанию ПРОЦЕНТА расхождения + (решение владельца 23.10.2026) группа без соперников → пара, её строки выбывают - две и более группы с тем же k и тем же расхождением, делящие строку → не сопоставляем, на ручное - (между разными правилами ничьей нет — её решает порядок rule_no) -строки, не сопоставленные ни одним правилом → «без пары» -результат пары: rule, A, B, osv_entry.id обеих сторон, Σ A, Σ B, deviation_amount, deviation_percent + две и более группы с тем же k и тем же процентом расхождения, делящие строку → не сопоставляем, на ручное (AMBIGUOUS) +строки, не вошедшие ни в одну группу → «без пары» (NO_MATCH) +результат группы: rule, A, B, osv_entry.id обеих сторон, Σ A, Σ B, deviation_amount, deviation_percent ``` Результат **не хранится** (DECISION-5) — возвращается как структура для шахматки, корректировок и КФО. Ручное решение по паре — `correction` с естественным ключом (`rule_id`, `legal_entity_id`, `counterparty_id`). +**3. Выдача.** Два запроса (контракт — `dev/frontend-api-guide.md`): **список пар версии** — все тройки «правило ББ × +упорядоченная пара компаний периметра», где хотя бы одна сторона не ноль, с ΣA, ΣB, расхождением, процентом, суммой +элиминации, статусом (сопоставлено автоматически / с расхождением > 5 % / без встречной стороны / ручное правило) и +`osv_entry.id` строк обеих сторон; сводная ОСВ строится один раз на запрос. **Детализация тройки** — упаковка п. 2: +точные группы, группы с расхождением ≤ 5 %, строки без пары с причиной. + **Алгоритм — по ТЗ** (решение владельца 08.10.2026, OQ-155): пары, `min`, порог 5 %, а не полная элиминация каждой стороны, как в эталонном Excel. Пример на фикстурах (Q3 2024, правило № 6): у Счастливочной на «Русский бисквит» 62.01 «БП Производство» 106 311 116,46, 62.01 «БП Аренда» 1 401 330, 76.06 350 000, 76.АВ 2 366 666,69; у РБ — одна строка 60.01 106 311 116,46. Упаковка: точная пара 1:1 (106 311 116,46), остальные три строки Счастливочной — без пары. -Сумма элиминации: ΣA = 110 429 113,15, ΣB = 106 311 116,46, расхождение 3,87 % ≤ 5 % → min = 106 311 116,46 (если у РБ нет -66.04/67.04 на Счастливочную; иначе 76.06 и 76.АВ сначала уйдут в правило № 5 и ΣA правила № 6 уменьшится). +Сумма элиминации: ΣA = 110 429 113,15, ΣB = 106 311 116,46, расхождение 3,87 % ≤ 5 % → min = 106 311 116,46. Строки 76.06 +и 76.АВ входят и в правило № 5, если у РБ есть 66.04/67.04 на Счастливочную, — двойной учёт до AURORA-1751. --- diff --git a/context/07-open-questions.md b/context/07-open-questions.md index 65911a8..a51cd4c 100644 --- a/context/07-open-questions.md +++ b/context/07-open-questions.md @@ -178,7 +178,7 @@ | OQ-170 | Состав `counterparty_accounts` (контрагенты расчётных счетов без названия вида, §1.3): исключены 71 «Расчёты с подотчётными лицами» и 73 «Расчёты с персоналом» (физлица, OQ-158), список — 58, 60, 62, 66, 67, 75, 76, 80. Верно ли исключение; нужны ли 68, 69, 70, 77 и др. | tabular-parser #59, change `osv-flat-form` (R-9, решение сессии при одобрении запуска 19.10.2026) | §1.3, сопоставление контрагентов (OQ-158) | открыт; допущение принято: 71/73 исключены (аналитика без названия вида на них остаётся `OTHER`, в сопоставление не попадает) | | OQ-171 | Вид субконто «Организации» в строке между названием ведомости и периодом (файл-письмо «ОСВ сч. 60 за 2 кв. 2026», план счетов ООО Хреновская Нива): что это за вид в 1С — организации-контрагенты (справочник «Организации» или «Контрагенты» под другим названием) или собственные организации учёта; на каких счетах встречается | tabular-parser #59, change `osv-flat-form` (R-10, решение сессии при одобрении запуска 19.10.2026) | §1.1 (синоним в `osv_groups.yaml`), сопоставление контрагентов | открыт; допущение принято: синоним `COUNTERPARTY` — только множественное число «Организации» (`^организации\b`, R-17); единственное «Организация» (собственная организация учёта в шапке) остаётся `OTHER`; другой смысл «Организации» на иных счетах даст `COUNTERPARTY` вместо `OTHER`, виден по предупреждениям | | OQ-172 | Безымянная аналитика первого уровня на счёте **63** (резервы по сомнительным долгам) в плоской форме без названия вида: на файлах контура таких строк нет; 51 строка — в fixtures, golden `osv-dkb/nm/2025-Q3/НМ_ОСВ_63_Контрагенты_…json` (имя файла «63_Контрагенты» — довод за включение 63); счёт 63 не входит в `counterparty_accounts` (§1.3), строки остаются `OTHER` без имени. Нужен ли 63 в списке (аналитика резерва — контрагенты-должники) | tabular-parser #59, приёмка Task 6 (19.10.2026) | §1.3, сопоставление контрагентов | открыт; допущение принято: 63 в список не входит, строки `OTHER` | -| OQ-173 | Пересечение правил в сумме элиминации: счета сторон правил §4 пересекаются — дебет № 5–8 (76 у № 5; 60/62/76 у № 6–8), кредит: 67.03 (№ 3 и маска 67 у № 7), 66.03 (№ 4 и маска 66 у № 8), 66.04/67.04 (№ 5 и № 7/8). Строка такого счёта входит в Σ стороны каждого правила, и сумма min(ΣA, ΣB) по правилам может превысить Σ самой стороны — двойная элиминация. Считать ΣA правила только по строкам, которые упаковка (§5 п. 2) отнесла к этому правилу? Или распределять сторону по правилам в фиксированном порядке? | решение по OQ-07 (docs #136, 19.10.2026), описание AURORA-1536 | §5 п. 1, AURORA-1536, КФО (§8 `eliminated_auto`) | **закрыт решением владельца 19.10.2026 (docs #136):** каскад по остатку — правила пары (A, B) считаются по порядку `rule_no` (в Прил. 3 он уже от частного к общему: № 3/4 раньше № 7/8, № 5 раньше № 6, № 6 → 7 → 8), каждое берёт min из остатка сторон после предыдущих, как в правиле № 1 Прил. 3 («сначала из 1450 до обнуления…»); упаковка — в том же порядке, строка сопоставляется одним правилом; ничьей между правилами нет. Поле порядка не нужно. Алгоритм — `05-domain-rules.md` §5 | -| OQ-174 | Какая версия правил элиминации (§4) применяется к версии консолидации, если `consolidation_version.elimination_rules_version` не задан: открытые на сегодня, действующие на отчётную дату консолидации или на дату её составления; когда фиксировать номер версии | ревью arm-core PR #141 (21.10.2026) | §4, §5, AURORA-1536 | **закрыт решением владельца 21.10.2026 (docs #145):** версия правил, действующая на дату составления консолидации (создания версии), а не на отчётный период; фиксируется в `elimination_rules_version` при создании версии или первом расчёте, не в GET-запросе; реализация — AURORA-1536; до неё расчёты берут открытые правила (`valid_to IS NULL`, сейчас одна версия v1) | -| OQ-175 | Процент расхождения шахматки при отрицательной меньшей стороне: `variance_pct = variance / min(amount_a, amount_b) * 100` при отрицательном сальдо (возможно по §1) уходит в минус — пара (100, −5) даёт −2100 %, порог > 5 % не срабатывает, пара не подсвечивается. Считать от `\|min\|`, от меньшей по модулю стороны или подсвечивать пары с разными знаками всегда? | ревью arm-core #165 (AURORA-1651), 22.10.2026 | §6, шахматка, xlsx | открыт; до решения — как в коде (min со знаком) | +| OQ-173 | Пересечение правил в сумме элиминации: счета сторон правил §4 пересекаются — дебет № 5–8 (76 у № 5; 60/62/76 у № 6–8), кредит: 67.03 (№ 3 и маска 67 у № 7), 66.03 (№ 4 и маска 66 у № 8), 66.04/67.04 (№ 5 и № 7/8). Строка такого счёта входит в Σ стороны каждого правила, и сумма min(ΣA, ΣB) по правилам может превысить Σ самой стороны — двойная элиминация. Считать ΣA правила только по строкам, которые упаковка (§5 п. 2) отнесла к этому правилу? Или распределять сторону по правилам в фиксированном порядке? | решение по OQ-07 (docs #136, 19.10.2026), описание AURORA-1536 | §5 п. 1, AURORA-1536, КФО (§8 `eliminated_auto`) | **закрыт решением владельца 19.10.2026 (docs #136):** каскад по остатку — правила пары (A, B) считаются по порядку `rule_no` (в Прил. 3 он уже от частного к общему: № 3/4 раньше № 7/8, № 5 раньше № 6, № 6 → 7 → 8), каждое берёт min из остатка сторон после предыдущих, как в правиле № 1 Прил. 3 («сначала из 1450 до обнуления…»); упаковка — в том же порядке, строка сопоставляется одним правилом; ничьей между правилами нет. Поле порядка не нужно. **Пересмотрено 21.10.2026** (решение владельца по созвону с заказчиком 19.10.2026): каскад отменён, каждое правило считается и упаковывается отдельно, строка общего счёта пока входит в несколько правил; двойной учёт снимает разнесение строк по правилам и ручной перенос (AURORA-1751). Алгоритм — `05-domain-rules.md` §5 | +| OQ-174 | Какая версия правил элиминации (§4) применяется к версии консолидации, если `consolidation_version.elimination_rules_version` не задан: открытые на сегодня, действующие на отчётную дату консолидации или на дату её составления; когда фиксировать номер версии | ревью arm-core PR #141 (21.10.2026) | §4, §5, AURORA-1536 | **закрыт решением владельца 21.10.2026 (docs #145):** версия правил, действующая на дату составления консолидации (создания версии), а не на отчётный период; фиксируется в `elimination_rules_version` при создании версии, не в GET-запросе; реализация — AURORA-1536. С DBML v5.23 (решение владельца 23.10.2026, docs #164) поле обязательно: у версий, созданных раньше, номер проставлен миграцией по дате создания | +| OQ-175 | Процент расхождения шахматки при отрицательной меньшей стороне: `variance_pct = variance / min(amount_a, amount_b) * 100` при отрицательном сальдо (возможно по §1) уходит в минус — пара (100, −5) даёт −2100 %, порог > 5 % не срабатывает, пара не подсвечивается. Считать от `\|min\|`, от меньшей по модулю стороны или подсвечивать пары с разными знаками всегда? | ревью arm-core #165 (AURORA-1651), 22.10.2026 | §6, шахматка, xlsx | открыт; до решения — как в коде (min со знаком); у пар ВГО §5 суммы сторон тоже со знаком (решение владельца 23.10.2026), но при `min ≤ 0` процент не считается и тройка подсвечивается | | OQ-176 | Счёт `000` «Вспомогательный» (технический счёт 1С для ввода остатков, `kind = AP`, `is_off_balance = false`) входит в шахматку «все счета». Исключать его вместе с забалансовыми? | ревью arm-core #165 (AURORA-1651), 22.10.2026 | §6, режим «все счета» | открыт; до решения — входит (решение владельца 22.10.2026: не трогать) | diff --git a/context/08-source-docs-index.md b/context/08-source-docs-index.md index 29ab3e6..c23553a 100644 --- a/context/08-source-docs-index.md +++ b/context/08-source-docs-index.md @@ -48,8 +48,8 @@ | Файл | Что | |---|---| -| `data-model-v5.22.dbml` | источник истины; changelog v5.1…v5.22 в шапке; блоки «ИСТОЧНИК» над каждой таблицей (v5.13…v5.21 остаются рядом как история) | -| `entities-v5.22.md` | описание сущностей по частям 01–09, таблицы «Что изменилось» по версиям, сценарий «как читать модель», открытые вопросы (v5.13…v5.21 остаются как история) | +| `data-model-v5.23.dbml` | источник истины; changelog v5.1…v5.23 в шапке; блоки «ИСТОЧНИК» над каждой таблицей (v5.13…v5.22 остаются рядом как история) | +| `entities-v5.23.md` | описание сущностей по частям 01–09, таблицы «Что изменилось» по версиям, сценарий «как читать модель», открытые вопросы (v5.13…v5.22 остаются как история) | | `diagrams/part01…09.{svg,png}` | диаграммы v5.21 по частям; перерисовываются `make diagrams` (`scripts/gen_model_diagrams.py`) | | `source/tz/data-model-part1_4.dbml` (лежит не в `model/`, а в экспорте ТЗ) | v4 часть 1 — историческое | diff --git a/context/KICKOFF-PROMPT.md b/context/KICKOFF-PROMPT.md index c1662df..23f5b0c 100644 --- a/context/KICKOFF-PROMPT.md +++ b/context/KICKOFF-PROMPT.md @@ -9,8 +9,8 @@ 1. `CLAUDE.md` (workspace) и `docs/context/00-workspace-layout.md` — как устроена рабочая область, статус аналитики, макет. 2. `docs/context/01-project-overview.md`, `02-glossary.md` — предметная область. -3. `docs/context/03-architecture.md`, `04-data-model-guide.md`, затем **весь** `docs/model/data-model-v5.22.dbml` и - `docs/model/entities-v5.22.md`. +3. `docs/context/03-architecture.md`, `04-data-model-guide.md`, затем **весь** `docs/model/data-model-v5.23.dbml` и + `docs/model/entities-v5.23.md`. 4. `docs/context/05-domain-rules.md` — алгоритмы (особенно §1.0 и §12 — парсеры ищут структуру по содержимому); `06-test-data.md`; `07-open-questions.md`; `10-user-journey.md`; `09-delivery-plan.md`. 5. `arm-core/`, `tabular-parser/`, `scan-gateway/` — три репозитория, развёрнутые из нулевого коммита шаблона команды, @@ -37,7 +37,7 @@ NATS, MinIO, эмулятор ИС Сканирование), контракт ` `07-open-questions.md`; если нужен ответ для среза — делай допущение по правилам из этого файла. Ограничения на всё время работы: -- имена таблиц, колонок и enum'ов — ровно как в DBML v5.22; поля, которых нет в DBML, не изобретать; +- имена таблиц, колонок и enum'ов — ровно как в DBML v5.23; поля, которых нет в DBML, не изобретать; - алгоритмы — только из `05-domain-rules.md`; из страниц ТЗ напрямую не кодировать; - парсеры: никаких координат ячеек, букв колонок, имён листов и номеров строк в коде — структура по содержимому, синонимы в `rules/*.yaml`; фикстуры — регрессия, не спецификация; diff --git a/dev/frontend-api-guide.md b/dev/frontend-api-guide.md index ec809ee..2ac4b2d 100644 --- a/dev/frontend-api-guide.md +++ b/dev/frontend-api-guide.md @@ -620,6 +620,36 @@ variance_percent?, exceeds_threshold, one_sided, skipped_osv_entry_count, osv_en счета» — без забалансовых 001–012. `skipped_osv_entry_count` — строки ОСВ пары без сопоставленного счёта, в суммы они не вошли. Выгрузки пишут в журнал `EXPORT`. +### 5.7.2 Пары ВГО и сумма элиминации (Срез 5, правила — `05-domain-rules.md` §5; arm-core #175, AURORA-1536) + +Префикс — `/consolidations/versions/{version_id}`. Права — `CONSOLIDATION_VIEW` и policy версии (чужая — 404); блокировка не +нужна. Считается на лету по сводной ОСВ версии и правилам ББ зафиксированной версии правил (`elimination_rules_version`, +с DBML v5.23 есть у каждой версии), ничего не хранится. Каждое правило считается отдельно: строка общего счёта может войти в +несколько правил (двойной учёт снимает AURORA-1751). + +| Метод и путь | Запрос | Ответ | Ошибки | +|---|---|---|---| +| `GET …/elimination-totals` | — | `EliminationTotalsOut` — все тройки версии: правила ББ × упорядоченные пары компаний периметра, у которых есть строки хотя бы на одной стороне | 404 | +| `GET …/elimination-pairs?rule_id=&company_a_id=&company_b_id=` | три параметра обязательны | `EliminationPairsOut` — итог тройки и упаковка строк | 404 (версия; правило не из версии правил); 422 `INVALID_COMPANY_PAIR` (A = B или не из периметра), `INVALID_RULE` (не ББ, показатель не `closing`), `ACCOUNTS_REQUIRED` | + +`EliminationTotalsOut` — `{version_no, items[] {rule_id, rule_no, elimination_mode, company_a_id, company_b_id, amount_a, +amount_b, deviation_amount, deviation_percent?, eliminated_amount, exceeds_threshold, status, osv_entry_ids_a[], +osv_entry_ids_b[]}}`, порядок — `rule_no`, затем порядок компаний периметра. `status`: `AUTO` — элиминируется +`eliminated_amount = min(ΣA, ΣB)` (расхождение ≤ 5 %); `DISCREPANCY` — обе стороны есть, расхождение > 5 % или меньшая сторона +≤ 0, элиминация 0; `ONE_SIDED` — одна из сумм нулевая; `MANUAL` — правило `elimination_mode = manual` (№ 1, № 2), элиминация 0. +`osv_entry_ids_*` — строки ОСВ, вошедшие в ΣA и ΣB (по ним — переход в сводную ОСВ). + +`EliminationPairsOut` — `{version_no, rule_id, rule_no, company_a_id, company_b_id, amount_a, amount_b, deviation_amount, +deviation_percent?, eliminated_amount, exceeds_threshold, matched[], with_discrepancy[], unpaired[]}`. Группы упаковки +(`matched` — точные, `with_discrepancy` — расхождение ≤ 5 %, по возрастанию процента) — `{rule_id, company_a_id, company_b_id, +amount_a, amount_b, deviation_amount, deviation_percent, osv_entry_ids_a[], osv_entry_ids_b[]}`; `unpaired[]` — `{row {entry_ids[], +legal_entity_id, counterparty_id, account_id, account_code, closing_debit?, closing_credit?}, reason}`, `reason`: `NO_MATCH` — +не нашлось группы, `AMBIGUOUS` — две равные группы делят строку (на ручное), `ZERO_AMOUNT`, `NEGATIVE_AMOUNT` — отрицательная +сумма строки, в упаковку не идёт. + +Суммы — строки в рублях с двумя знаками, со знаком (как в шахматке); `deviation_amount = |ΣA − ΣB|`, `deviation_percent` — +к меньшей стороне, `null`, если она ≤ 0. Упаковка сумму элиминации не меняет: в КФО идёт `eliminated_amount` тройки. + ### 5.8 Схемы ответов (кратко) Поля с `?` могут быть `null`, но ключ присутствует всегда. Полные схемы — `/openapi.json` и контракты по областям. diff --git a/model/data-model-v5.23.dbml b/model/data-model-v5.23.dbml new file mode 100644 index 0000000..919e28c --- /dev/null +++ b/model/data-model-v5.23.dbml @@ -0,0 +1,1546 @@ +// ДКБ · Модель данных v5.23: справочники, файлы/распознавание, консолидация, КФО, аудит, ЕХФД +// Формат: DBML (dbdiagram.io). Вставить на https://dbdiagram.io/d +// >>> Источник истины по модели данных. Аналитика в Confluence ссылается сюда. +// Над каждой таблицей — блок «ИСТОЧНИК»: пункт ТЗ АРМ КА BIQ-34 / ТЗ ЕХФД (помечено «ЕХ ТЗ») / Методика; +// страница аналитики (md); экран макета dkb_24.09.26; версия модели, в которой таблица появилась (v4 = исходная DBML аналитики). +// +// v5.23 (решения владельца 23.10.2026; RSHB/arm-ka-docs#164, AURORA-1536, ревью arm-core #175; одна миграция arm-core): +// 1. consolidation_version.elimination_rules_version: not null. Версия правил элиминации (elimination_rule.version_no), +// действующая на дату создания версии консолидации (OQ-174), фиксируется при создании и дальше не меняется; по ней +// считаются шахматка-пресет и пары ВГО (context/05-domain-rules.md §4, §5). Пустое значение больше не допускается: +// «пока поле пусто — последние открытые правила» убрано, версия без правил не создаётся. +// Миграция: существующим версиям — номер версии правил, действовавшей на дату created_at (по Москве), при её отсутствии — +// последней открытой; затем NOT NULL. Откат снимает только NOT NULL, значения остаются. +// +// v5.22 (22.10.2026; AURORA-1446): +// 1. comment.object_type: убраны устаревшие chess_cell и kfo_result_line. +// Сохранено описание привязки: document | consolidation_version | …. +// Комментарий к правке пары ВГО — correction.comment; к строкам КФО — kfo_result_line.comment +// и client_kfo_line.comment (отдельные поля, не лента комментариев). +// Уточнены описание и источники comment. Структура БД не меняется, миграция не требуется. +// +// v5.21 (решение владельца 22.10.2026; RSHB/arm-ka-docs#149, AURORA-1442; одна миграция arm-core): +// 1. audit_action: значение FILE_REPROCESS — повторная обработка файла пользователем (раздел PRIMARY_DOCUMENTS; +// context/05-domain-rules.md §9.5 п. 6, п. 13). Файл не загружается заново — создаётся новое recognition_job +// (attempt + 1) и становится current_recognition_job_id, поэтому FILE_UPLOAD (приём нового файла) и FILE_REPLACE +// (автозамена другим файлом) не подходят. Событие — на файл: object_type = stored_file, before_value — прежнее +// задание, after_value — новое; пакет версии пишет по событию на каждый отправленный файл. +// Миграция только добавляет значение enum. Откат при наличии событий FILE_REPROCESS останавливается с ошибкой и ничего +// не меняет (журнал append-only). +// +// v5.20 (решения владельца 21.10.2026; RSHB/arm-ka-docs#147, OQ-161 вариант 2, AURORA-1442; одна миграция arm-core): +// 1. document: is_modified (boolean, not null, default false), original_values (jsonb), modified_by (FK → app_user), +// modified_at — уточнение периода и счёта документа ОСВ аналитиком (context/05-domain-rules.md §9.5 п. 12). +// Правка — на месте в period_year / period_quarter / is_cumulative / osv_account_code; при первой правке прежние +// значения этих четырёх полей копируются в original_values и дальше не меняются (первичка не мутируется, как +// osv_entry.original_values). Копия document не создаётся: file_ordinal — номер документа в результате +// распознавания, не номер редакции. Строки osv_entry при смене счёта не меняются. +// Миграция только добавляет колонки (is_modified = false, остальные NULL). Откат на данных с is_modified = true +// останавливается с ошибкой и ничего не меняет (потерялись бы исходные значения). +// +// v5.19 (решения владельца 17.10.2026, Р-1…Р-19; RSHB/arm-ka-docs#116, openspec/changes/archive/2026-10-19-unified-statement-normalization; +// контракт результата v2.0; одна миграция arm-core): +// 1. financial_statement_line: снята уникальность (meta_id, line_code) — повтор кода законен, хранятся все строки (Р-4); +// line_code остаётся nullable и пуст у строк unreadable / missing / detail (Р-8, отменяет OQ-36 / OQ-141). +// Новые колонки: row_index (порядок строки в документе; у шаблонных и созданных правкой — NULL), source_ref +// (положение в источнике, частичный уникальный индекс (meta_id, source_ref) WHERE source_ref IS NOT NULL), +// line_status (enum statement_line_status), line_code_text (сырой текст ячейки кода), parent_row_index (родитель +// detail), needs_review (как пришло от сервиса, пересчитывается ядром после правок), is_confirmed (код подтверждён +// аналитиком). +// 2. financial_statement_value: source_text (values[].text — сырой текст источника), needs_review (как пришло, +// пересчитывается после правок; пересматривает п. 4 v5.13 «считается, не хранится»), is_confirmed + confirmed_by / +// confirmed_at (подтверждено аналитиком без изменения значения). +// 3. financial_statement_column: period_kind (absolute | relative:<вид> | none), label_confidence. +// 4. financial_statement_meta: form_variant (enum statement_form_variant), needs_review_fields (поля шапки с +// needs_review, jsonb-массив имён). +// 5. Новая таблица document_issue (+ enum'ы document_issue_kind, issue_severity, issue_source): предупреждения и нарушения +// §7 документа как пришли от сервиса или посчитаны ядром; очищается при перезагрузке файла; при пересчёте после +// правки записи relation / soft заменяются целиком, warning источника service сохраняются, кроме снимаемых правкой. +// 6. recognition_job.statements_version — коммит копии общего кода arm_statements, которым посчитан результат. +// 7. document: уникальность (stored_file_id, document_type, osv_account_code) — только для типов кроме BALANCE / INCOME +// (частичный индекс; ОСВ по счёту, DISCLOSURE, OTHER — «один на тип на файл», §9.5 п. 2); вторая форма того же типа +// в файле хранится (Р-10, Р-15); новая колонка file_ordinal — индекс документа в documents[] результата (у всех +// документов при любом MAJOR контракта; несозданный документ номер не занимает), уникален в файле. +// 8. related_group.crm_id (varchar, nullable, unique) — ID ГСК/ГСЗ в ЕЦП CRM (AURORA-1619, arm-core#112, OQ-33). +// 9. Признак «строка создана правкой аналитика» — financial_statement_line.row_index IS NULL (заменяет прежний +// признак line_code_original_value IS NULL: у строк unreadable / missing / detail источника кода тоже нет). +// line_code_original_value — код строки из результата как пришёл (NULL у статусов кроме ok и у строк, созданных +// правкой); правками не меняется. +// 10. financial_statement_meta: header_source (jsonb — сырой текст и уверенность всех полей шапки результата, +// {"<поле>": {"text", "confidence"}}), organization_name_original_value и organization_name_modified (наименование +// правится PATCH шапки, как ИНН). +// 11. document_issue: codes (jsonb — коды цели и членов нарушения §7), column_index (столбец предупреждения вне колонок +// формы — COLUMN_SKIPPED и др.). +// Перед выкладкой база очищается от форм ББ/ОФР (решение владельца 18.10.2026, Р-24; скрипт ядра +// scripts/purge_statements.py): миграция только добавляет колонки, таблицу, enum'ы, индексы и значения по умолчанию, +// §7 по существующим формам не считает. Заполнение (миграция проходит и на непустой базе): row_index строк — NULL у +// строк с line_code_original_value IS NULL (созданных правкой), у остальных — по возрастанию line_code внутри формы с 0; +// line_status = ok, needs_review строк = false, needs_review значений = НЕ values_ok (values_ok — правлено или +// is_recognized не false и confidence 100 / NULL), source_text = string_value, is_confirmed = false, period_kind = +// absolute при period_date, иначе none, form_variant = NULL (набор §7 — полный), header_source — из *_original_value +// и inn_confidence, organization_name_original_value = organization_name, file_ordinal — по (created_at, id) внутри +// файла с 0 (у всех документов), related_group.crm_id = NULL; document_issue — пуст: корректность нарушений у форм, +// оставшихся в неочищенной базе, не гарантируется до первой правки. +// Откат гарантирован на пустой БД и на данных, которые v5.18 представляет без потери первичных данных и ручного ввода; +// downgrade останавливается с ошибкой и ничего не меняет при повторе кода в форме, строке без кода, двух формах одного +// типа в файле, непустом related_group.crm_id, organization_name_modified = true; производные и сигнальные колонки +// v5.19 и document_issue удаляет с записью числа удалённых значений в журнал миграции. +// +// v5.18 (решения владельца 09.10.2026; RSHB/arm-ka-docs#90, openspec/changes/console-files): +// 1. stored_file.consolidation_id (uuid, nullable, FK → consolidation): консолидация (ГК + год + квартал), в контексте +// которой загружен файл, — основа «рабочего стола консоли» (полный состав стола — context/05-domain-rules.md §9.5 п. 11), общего для всех версий периода. NULL — загрузка без контекста +// (страница ЮЛ, монозаёмщики, API). Пишется один раз при загрузке (POST /consolidations/{id}/legal-entities/{le}/files); +// при автозамене новый файл без контекста наследует consolidation_id заменённого. Индекс (legal_entity_id, consolidation_id). +// Что использует конкретная версия, по-прежнему определяет consolidation_document; заморозка после VERIFIED — привязки и ex_snapshot. +// Миграция 0006 arm-core: backfill по consolidation_document (при нескольких периодах — самый ранний). +// 2. Note recognition_job.reply_deadline: срок ответа OCR — 20 мин (OQ-159, решение владельца 09.10.2026), структура не меняется. +// +// v5.17 (решение владельца 07.10.2026, пересмотр OQ-31; RSHB/arm-ka-docs#53): +// 1. legal_entity.kpp и legal_entity_history.kpp (varchar, nullable): КПП юридического лица. Формат — 9 символов: +// 4 цифры, 2 символа (цифра или латинская A–Z), 3 цифры; иначе INVALID_KPP. У ИП КПП запрещён (INVALID_KPP; +// импорт — строка пропускается). Для ЮЛ необязателен: существующие записи и импорт без колонки КПП остаются валидными. +// Уникальность — только legal_entity.inn (КПП — атрибут, сопоставление контрагентов ОСВ по ИНН не меняется). +// Изменение КПП — обычная правка со снимком в legal_entity_history. Отменяет п. 2 v5.14 («КПП не вводится»). +// +// v5.16 (Срез 4, решения владельца 06.10.2026): +// 1. Новый enum counterparty_match_kind и колонка osv_entry.counterparty_match_kind (nullable): способ, которым строке ОСВ +// сопоставлен контрагент. NULL ⇔ counterparty_id NULL; INN / NAME / ALIAS — шаг автоматического резолва при маппинге +// (ИНН; точное имя; нормализованное имя или алиас); MANUAL — ручное сопоставление аналитиком; PROPAGATED — +// автоприменение по имени в версии (DOC-221278 п. 12–13). Миграция 0004 заполняет колонку по уже смапленным строкам. +// 2. Без изменений структуры, уточнение семантики consolidation_document: строка создаётся при подтверждении документа +// (по документам ЮЛ — членов периметра версии «в работе»), при подходящем подтверждённом документе — при добавлении ЮЛ +// в периметр; удаляется при отвязке документа (замена файла, удаление, исключение ЮЛ из периметра). Для одной +// (ЮЛ, document_type, osv_account_code, период, признак нарастающего) привязан один документ — самый поздний confirmed_at. +// 3. Без изменений структуры, уточнение семантики consolidation_lock: блокировка без истечения по времени — активна, пока её не +// снял владелец, администратор или перехват другим пользователем с CONSOLIDATION_EDIT по причине (OQ-119). +// +// v5.15 (Срез 2c, решения владельца 05.10.2026): +// 1. osv_data_type: добавлено NU — строки налогового учёта из ОСВ «БУ, НУ» хранятся в osv_entry как есть (OQ-45); +// контракт результата допускал NU с v1.0. +// 2. app_user.email хранится в нижнем регистре: нормализация при записи (seed, администрирование), поиск по +// lower(email) остаётся; уникальность — существующий UNIQUE по email (OQ-59). Структура не меняется. +// 3. Без изменений структуры, уточнение семантики: stored_file.status — PROCESSING ставится inbox'ом по ack сервиса, +// PROCESSED/ERROR — циклом маппинга результата (OQ-67); маппинг выполняется отдельно от inbox (OQ-69); +// recognition_job.group_schema заполняет маппер; «Итого» в osv_entry не хранится (OQ-01). +// 4. Индексы для удаления файла и обхода дерева строк: osv_entry (parent_entry_id), osv_entry (recognition_job_id), +// stored_file (current_recognition_job_id) — проверки FK при DELETE документа/файла и очистке перед повторным +// маппингом шли seq scan'ом (OQ-117). Замер: DELETE документа 1000 строк 8,6 с → 16 мс на 200 тыс. строк. +// +// v5.14 (Срез 1, решения владельца 04.10.2026): +// 1. ЮЛ может состоять ОДНОВРЕМЕННО в одной ГСК и одной ГСЗ (но только в одной группе каждого вида) — отменяет +// ANL-030/v5.8. В related_group_member возвращена денормализованная колонка kind (= related_group.kind, +// равенство проверяет ядро при записи); частичный уникальный индекс стал (legal_entity_id, kind) WHERE is_current. +// 2. КПП у ЮЛ не вводится (OQ-31: поле есть только в макете; решение владельца — не нужен). [Отменено в v5.17 — КПП введён.] +// 3. Без изменений структуры, уточнение семантики: company_group.crm_id = «iD ГК» выгрузки ЕЦП CRM +// (docs/source/biq/ecp-export-lagal-entity.xlsx), base_regional_office — «Базовый РФ ГК в CRM»; флаги «входит в ГСК/ГСЗ» +// выгрузки → членство в одной неявной ГСК/ГСЗ на ГК (правила импорта — 05-domain-rules.md §13). +// 4. audit_action: добавлены LEGAL_ENTITY_CHANGE (создание/изменение/закрытие/перевод ЮЛ, алиасы) и USER_CHANGE +// (создание/деактивация пользователя администратором) — ТЗ 8.2 «журнал изменений справочников» их требует, +// в v5.13 были только GROUP_CHANGE / MEMBERSHIP_CHANGE / USER_ROLE_CHANGE. +// +// v5.13 (ревью 30.09–01.10, замечания 1–7; п.2 parent_entry_id — отложен): +// 1. Права как данные: permission + role_permission (матрица доступов ТЗ сноска 29 — в БД, не в коде); +// права только через роли, прямых назначений пользователю нет. Отменяет решение v5.4. +// 3. osv_group_schema убрана — схема группировок шапки = recognition_job.group_schema jsonb; +// тип строки — osv_entry.group_type. +// 4. financial_statement_value.needs_review убран — производное от confidence/is_recognized, считается запросом. +// 5. recognition_job: оставлен только result_s3_object_id; сырой ответ ИС Сканирование в БД не регистрируется +// (scan-gateway пишет его в S3 по конвенции raw/{job_id}.json для разбора инцидентов). +// 6. stored_file.fields_modified убран — COUNT(is_modified) по данным документа. +// 6-бис. Разделение «файл / документ»: stored_file = физический файл (один на загрузку), document = логическая +// единица (ББ, ОФР, ОСВ по счёту, расшифровка) — один файл содержит N документов (PDF с ББ+ОФР, xlsx с +// несколькими ОСВ листами). Чек-лист, проверки периода/контрагента, подтверждение, FK разобранных данных, +// consolidation_document и ex_snapshot_item — на document. Замена (superseded_by) остаётся на файле целиком. +// 7. file_type: убран P7. +// +// Изменения относительно v4 (кратко): +// FIX — исправлены дефекты v4 (PK у meta, типы, копипаст-note про «контрагента», row_type, parent_entry_id) +// ADD — audit_event, status_history, company_group_assignment, elimination_rule, statement_check_result, +// consolidated_osv_line, chess_cell, vgo_pair_match (агрегат по ТЗ 6.4), ofr_vgo_match, kfo_result_*, +// client_kfo_line, comment, export_log/preset, ex_snapshot*, correction_version +// CHG — role → 7 ролей ТЗ + сегмент (ЗО); consolidation_version — сценарий/подход/гудвилл/решение УОБ; +// stored_file — счёт ОСВ, версии/замена; osv_entry — признак контрагента + override; legal_entity — монозаёмщик +// +// Ключи: у ВСЕХ сущностей суррогатный PK (uuid). Натуральные ключи — UNIQUE-колонки. +// (Для высокообъёмных таблиц — osv_entry, audit_event — uuid можно заменить на bigint identity.) +// ЮЛ и ГК — SCD Type 4 (живая таблица + *_history). Членство в ГСК/ГСЗ — SCD Type 2 (is_current). +// Первичка не мутируется: правки распознанных значений = поле + *_original_value + is_modified + audit_event. +// Производные объекты версии (сводная ОСВ, шахматка, КФО) — snapshot на consolidation_version: +// пересчитываются пока версия «в работе», замораживаются при VERIFIED (ТЗ 6.10, 7.2). +// +// DECISION-1 (ТЗ 6.4 vs v4): первичная модель сопоставления ВГО — АГРЕГАТ по паре компаний × правилу пары счетов +// (vgo_pair_match), как в ТЗ/Прил. 3. Строковое 1:1 сопоставление (vgo_match) сохранено как детализация агрегата. +// DECISION-2 (ЕХФД): ЕХ — те же таблицы + ex_snapshot как «замороженный указатель» на состав верифицированной версии. +// Отдельная физическая БД для ЕХ не предполагается; архив в data lake — выгрузка снапшота. +// DECISION-3: ГО — обычная запись regional_office с is_head_office=true (вместо NULL). +// DECISION-5 (производные консолидации): сводная ОСВ, пары ВГО и шахматка НЕ хранятся, пока версия в работе — +// считаются запросом из osv_entry (актуальные прогоны) × consolidation_member × elimination_rule. +// Признак контрагента ГСК/ГК/Внешний — функция от osv_entry.counterparty_id и периметра версии; ручное действие +// аналитика = сопоставление контрагента с ЮЛ (counterparty_id + алиас), комментарий — в audit_event. +// v5.16: способ сопоставления контрагента (osv_entry.counterparty_match_kind) ХРАНИТСЯ; пробелы квартальной склейки и сам свод — нет. +// При VERIFIED производные замораживаются один раз: структурированный снапшот — jsonb в ex_snapshot_item.payload +// (просмотр в ЛК ЕХ), подготовленный xlsx для выгрузки — s3_object. Отдельная NoSQL-база не вводится. +// Корректировки и гудвилл ссылаются на пару ВГО по естественному ключу (правило, компания 1, компания 2). +// DECISION-4 (распознавание): два отдельных stateless-сервиса без доступа к БД — +// tabular-parser (XLS/XLSX/XLSB) и scan-gateway (адаптер ИС Сканирование для PDF/PNG/JPG). +// Запрос: NATS recognition.{tabular|image}.request + файл в S3 uploads/. Результат: JSON в S3 results/ + +// NATS recognition.result. Единственный писатель в БД — arm-core; корреляция по recognition_job.id; +// идемпотентность по msg_id; outbox при создании recognition_job; DLQ. +// v5.13: результат одного файла содержит N документов; ядро создаёт document при маппинге результата. +// +// v5.1 (по макету dkb_24.09.26): consolidation_lock (взятие в работу), participant_disclosure (расшифровки участника), +// legal_entity_history.event_type, statement_meta реквизиты (ОКПО/ОКОПФ/ОКФС/адрес), kfo_result_line: vgo/share, +// client_kfo_line: ВГО клиента/банка + причина, audit_event: section/result/user_agent, статусы REJECTED/ARCHIVED, +// document_check (проверка периода/контрагента файла), company_group.crm_id nullable (ANL-037). +// v5.2 (DECISION-4): recognition_job: subject/msg_id/deadline/external_task_id/result_schema_version/error_code, статусы timeout/dlq. +// v5.12 (ревью part09): ЕХ самодостаточен — срез не ссылается FK на консолидацию и её результаты (их удаляют по сроку, +// срез хранится «вечно»): ex_snapshot.source_version_id/no без FK; ex_snapshot_item = stored_file_id (исходники храним) +// ИЛИ payload jsonb (сводная ОСВ, ВГО, шахматка, КФО, гудвилл, корректировки); убраны object_type/object_id, +// prepared_s3_object_id (готовые файлы не храним), ex_snapshot.source_system, audit_event.s3_object_id; +// добавлен ex_snapshot.superseded_by_snapshot_id (архивный → актуальный). +// v5.11: consolidation_version.elimination_rules_version — какая версия правил Прил. 3/4 применялась (объяснимость и +// воспроизводимость расчёта замороженной версии). +// v5.10 (DECISION-5, ревью part08): убраны consolidated_osv_line, consolidated_osv_source, vgo_pair_match, chess_sheet, chess_cell, +// osv_entry.counterparty_type (выводится); correction ссылается на пару по (rule_id, company_1_id, company_2_id); +// ex_snapshot_item получил payload jsonb. +// v5.9 (ревью part06/07): statement_check_result убрана — проверки считаются на лету, акцепт КА — на документе +// (financial_statement_meta.checks_accepted_*); reviewed_by/at перенесены в meta (документ ревьюится целиком); +// financial_statement_line: убраны ordinal/row_kind/section (порядок и группирующие строки — шаблон формы на фронте); +// consolidation: company_group_id NOT NULL, related_group_id nullable — ГСК фиксируется при VERIFIED (ANL-029); +// consolidation_version: убран package_uuid (документы в ИС Сканирование по одному, ключ = recognition_job.id), добавлен updated_by. +// v5.8 (ревью part01): убраны company_group_assignment (видимость ТЗ 8.1 выводится из company_group.base_regional_office_id, +// legal_entity.regional_office_id, app_user.regional_office_id; история перезакрепления — company_group_history), +// legal_entity.is_mono_borrower (монозаёмщик = company_group_id IS NULL), related_group_member.kind и индекс related_group(id, kind) +// (после ANL-030 partial-unique по legal_entity_id без условия на kind). +// v5.7: метрики качества распознавания — recognition_job.fields_total/low_confidence/unrecognized (что пришло от сервиса). +// (stored_file.fields_modified/fields_reviewed и financial_statement_value.needs_review — убраны в v5.9/v5.13 как производные.) +// v5.6 (ревизия 28.09, решения по каждой убранной таблице): +// account_code_alias — нормализация кодов в коде; редкие субсчета клиентов добавляются в chart_of_account +// vat_rate — константы; средневзвешенная ставка хранится в vgo_pair_match +// crm_import_batch — импорт справочников только на старте (миграция); след в audit_event(DIRECTORY_IMPORT) + файл в s3_object +// osv_entry_edit — audit_event(RECOGNIZED_DATA_EDIT) + osv_entry.original_values/modified_by/modified_at +// document_check — колонки period_check/counterparty_check (с v5.13 — на document); сверка с периодом версии вычисляется +// export_preset — выбор колонок в момент экспорта, без сохранения наборов +// export_log — audit_event(EXPORT, after_value={report_code, format, columns, rows}); файлы выгрузок не хранятся (S3 lifecycle exports/ = 7 дней) +// v5.5: убрана correction_version — история корректировок (сноска 22) ведётся audit_event(before/after), version_no в correction. +// v5.4: возвращён s3_object (реестр объектов S3 — lifecycle/ретеншн ТЗ 8.4, sha256, единая точка ключей); permission/role_permission — матрица в коде (ОТМЕНЕНО в v5.13). +// v5.3 РЕВИЗИЯ по правилу «в базе только то, что есть в ТЗ или на экране макета». Удалено 14 таблиц: +// - account_code_alias: нормализация кодов (60.1=60.01) — алгоритм в коде (ARCH-004), не справочник +// - vat_rate: ставки 0/10/20/22 — константы; средневзвешенная ставка хранится в vgo_pair_match.vat_weighted_rate +// - disclosure_item: расшифровки участника: в UI скрыты, в ТЗ только тип документа «Расшифровка» → вне scope до решения ANL-040 +// - participant_disclosure: см. disclosure_item +// - crm_import_batch: журнал импортов не в ТЗ/UI; факт импорта и ошибки — audit_event(GROUP_CHANGE/IMPORT) +// - permission / role_permission: ВОЗВРАЩЕНЫ в v5.13 (замечание 1) +// - integration_message: РЕШЕНИЕ — обмен с NATS завязан только на recognition_job (status queued→published = outbox; result_msg_id UNIQUE = inbox/дедуп); отдельная таблица появится, только если возникнет второй тип сообщений +// - osv_entry_edit: история правок сумм ОСВ — audit_event(RECOGNIZED_DATA_EDIT, before/after) +// - document_check: результат проверки периода/контрагента — две колонки (с v5.13 — в document) +// - vgo_match: строковое сопоставление 1:1 — только в аналитике, нет ни в ТЗ (агрегат по Прил. 3), ни в UI; детализация агрегата — consolidated_osv_source +// - export_preset: сохранённые пресеты колонок не в ТЗ/UI (выбор столбцов — при экспорте, без сохранения) +// - export_log: история выгрузок (ТЗ 8.2, ЕХ 6.6) — audit_event(EXPORT) с составом в after_value + +// ============ ENUMS ============ +Enum entity_type { + "ЮЛ" + "ИП" +} + +Enum related_group_kind { + gsk + gsz +} + +Enum account_kind { + A [note: 'актив'] + P [note: 'пассив'] + AP [note: 'активно-пассивный'] +} + +Enum account_row_type { + account [note: 'синтетический счёт, напр. 60'] + subaccount [note: 'субсчёт, напр. 60.01'] + analytic [note: 'подсубсчёт, напр. 60.01.1 / 76.07.1'] +} + +Enum business_segment { + DKB [note: 'крупный бизнес'] + DMSB [note: 'малый и средний'] + DM [note: 'микробизнес'] +} + +Enum document_type { + BALANCE [note: 'Бухгалтерский баланс (0710001)'] + INCOME [note: 'ОФР (0710002)'] + OSV [note: 'ОСВ по счёту — osv_account_code обязателен'] + DISCLOSURE [note: 'Расшифровка'] + OTHER [note: 'Прочий документ'] +} + +Enum file_type { + XLS + XLSX + XLSB + PDF + PNG + JPG +} + +Enum recognition_pipeline { + tabular [note: 'XLS/XLSX/XLSB — tabular-parser'] + image [note: 'PDF/PNG/JPG — ИС Сканирование через scan-gateway'] +} + +Enum period_quarter { + Q1 + Q2 + Q3 + Q4 +} + +// v5.13: статус ФАЙЛА — только техническая обработка. Проверка и подтверждение аналитиком — на document. +Enum file_status { + UPLOADED [note: 'Загружен: поступил, в очереди'] + PROCESSING [note: 'Обработка: распознавание/парсинг'] + PROCESSED [note: 'Результат получен, документы созданы'] + ERROR [note: 'Ошибка: нечитаемый файл, требуется повторная загрузка'] + SUPERSEDED [note: 'Заменён новой версией файла (ТЗ 8.2) — вместе со всеми документами в нём'] +} + +// v5.13: статус ДОКУМЕНТА (ANL-003: «Требуется проверка» при confidence < 100% или непройденных проверках; +// «Подтвержден» — финальный после проверки аналитиком) +Enum document_status { + RECOGNIZED [note: 'данные получены, ручная проверка не требуется по порогу'] + NEEDS_CHECK [note: 'Требуется ручная проверка: confidence < 100% / контрольные суммы / период или контрагент не совпали'] + CONFIRMED [note: 'Подтвержден аналитиком: данные зафиксированы, доступны консолидации'] + ERROR [note: 'документ не разобран (напр. не найдена шапка ОСВ)'] +} + +Enum s3_bucket_role { + uploads + results + exports + archive +} + +Enum recognition_status { + queued [note: 'создано, запрос в outbox'] + published [note: 'запрос опубликован в NATS'] + processing [note: 'сервис подтвердил взятие в работу (опц. heartbeat)'] + done + needs_check [note: 'результат получен, но confidence < 100% / контрольные суммы не сошлись'] + error + timeout [note: 'reply_deadline истёк без результата'] + dlq [note: 'сообщение ушло в DLQ после max_deliver'] +} + +Enum statement_type { + balance + income +} + +// v5.19: статус строки формы ББ/ОФР (05-domain-rules.md §11.4) +Enum statement_line_status { + ok [note: 'код разобран'] + unreadable [note: 'в ячейке кода есть цифры, но код не разобран (сырой текст — line_code_text)'] + missing [note: 'строка без кода с содержимым, выше в документе нет строки с кодом'] + detail [note: 'расшифровка без кода под строкой с кодом (Р-8): в §7, агрегаты, КФО и ЕХ не входит'] +} + +// v5.19: вариант формы — по структуре кодов (§11.7) +Enum statement_form_variant { + full + simplified [note: 'упрощённая форма (приказ 66н, прил. 5): ББ без 1100/1200, ОФР без 2100/2200/2300'] +} + +// v5.19: вид записи document_issue +Enum document_issue_kind { + warning [note: 'предупреждение (05-domain-rules.md §11.9, таблица уровней)'] + relation [note: 'жёсткое соотношение §7, не сошедшееся вне допуска и округления'] + soft [note: 'мягкое соотношение или жёсткое в пределах округления (OQ-138)'] +} + +Enum issue_severity { + error [note: 'документ needs_check'] + info [note: 'на статус не влияет'] +} + +Enum issue_source { + service [note: 'пришло в результате распознавания'] + core [note: 'посчитано ядром (проверки по словарю имён и перечню кодов; пересчёт §7 после правки)'] +} + +Enum osv_group_type { + ACCOUNT + DEPARTMENT + COUNTERPARTY + CONTRACT + OTHER +} + +Enum counterparty_match_kind { + INN [note: 'автоматический резолв при маппинге: ИНН строки совпал с legal_entity.inn'] + NAME [note: 'автоматический резолв: точное совпадение имени строки с legal_entity.name'] + ALIAS [note: 'автоматический резолв: нормализованное имя ЮЛ или алиас (legal_entity_alias)'] + MANUAL [note: 'ручное сопоставление аналитиком'] + PROPAGATED [note: 'автоприменение ручного сопоставления к строкам с тем же именем в версии (DOC-221278 п. 12–13)'] +} + +Enum osv_data_type { + BU + NU [note: 'v5.15: налоговый учёт из ОСВ «БУ, НУ» (OQ-45)'] + CURRENCY + QUANTITY + SUM +} + +Enum consolidation_scenario { + CREATE [note: '«Создание КФО» при отсутствии клиентской консолидации'] + CONFIRM [note: '«Подтверждение КФО клиента»'] +} + +Enum consolidation_approach { + BASIC [note: 'базовый: ББ, ОФР, ОСВ 01,58,60,62,66,67,76,90'] + EXTENDED [note: 'опция к базовому: + ОСВ 02,03,08,44,26,91,51,52,59,80,83,86,97,001,008,009,011'] +} + +// Статусы КФО по ТЗ 6.10 + «Корректировка» при расхождении ≥5% (ТЗ 6.4) +Enum consolidation_status { + INITIATED + DOCUMENTS_PROCESSING + DATA_CORRECTION [note: 'корректировка распознанных данных'] + CONSOLIDATION_RF + ADJUSTMENT [note: '«Корректировка» ВГО (расхождение ≥ 5%); подстатус этапа консолидации'] + VERIFICATION_RF + CONSOLIDATION_GO + VERIFICATION_GO [note: 'РКА ГО, если КФО инициировано КА ГО (ТЗ 6.10 маршрут)'] + VERIFIED + CANCELLED + // v5.1 по макету — ANL-035: подтвердить с заказчиком + REJECTED [note: 'Отклонено: возвращено на доработку (макет). Альтернатива — событие в status_history без отдельного статуса'] + ARCHIVED [note: 'Архив: скрыто из основного списка (макет); применимо к VERIFIED/CANCELLED'] +} + +Enum correction_status { + DRAFT + APPLIED + REVOKED +} + +Enum document_check_result { + MATCH + MISMATCH + UNKNOWN +} + +Enum le_history_event { + CREATE + UPDATE + MOVE_TO_GROUP [note: '«Переход в другую ГК»'] + CLOSE [note: '«Закрытие» / вывод из состава ГК'] + REMOVE_FROM_GROUP +} + +Enum ex_snapshot_status { + ACTUAL + ARCHIVE +} + +// v5.13: объекты и действия матрицы прав (ТЗ Прил. 2 «Роль: перечень полномочий», сноска 29) +Enum permission_object { + DIRECTORY [note: 'справочники ГК/ГСК/ГСЗ/ЮЛ'] + DOCUMENT [note: 'первичные документы и распознанные данные'] + CONSOLIDATION [note: 'консолидация, версии, корректировки, гудвилл'] + KFO [note: 'результат КФО: утверждение, верификация'] + EX [note: 'Единое хранилище'] + EXPORT + USERS [note: 'пользователи и роли'] + AUDIT [note: 'журнал действий'] +} + +Enum permission_action { + VIEW + EDIT + APPROVE [note: 'утверждение в РФ'] + VERIFY [note: 'верификация в ГО'] + DELETE + EXPORT + ADMIN +} + +Enum audit_section { + DIRECTORIES + CONSOLIDATION + PRIMARY_DOCUMENTS + RECOGNITION + KFO + EXPORT + ACCESS + SESSION + USERS +} + +Enum audit_action { + LOGIN + LOGIN_FAILED + LOGOUT + CONSOLIDATION_CREATE + CONSOLIDATION_STATUS_CHANGE + CONSOLIDATION_APPROVE + CONSOLIDATION_VERIFY + GROUP_CHANGE + LEGAL_ENTITY_CHANGE [note: 'v5.14: ЮЛ создано/изменено/закрыто/переведено, алиасы'] + MEMBERSHIP_CHANGE + ASSIGNMENT_CHANGE + FILE_UPLOAD + FILE_DELETE + FILE_REPLACE + FILE_REPROCESS [note: 'v5.21: повторная обработка файла — новое recognition_job (attempt + 1), не новая загрузка'] + DOCUMENT_CONFIRM + CONSOLIDATION_LOCK + CONSOLIDATION_LOCK_TAKEOVER + DISCLOSURE_EDIT + RECOGNIZED_DATA_EDIT + OSV_COUNTERPARTY_MAP + OSV_TYPE_OVERRIDE + CORRECTION_CREATE + CORRECTION_EDIT + CORRECTION_REVOKE + GOODWILL_EDIT + EXPORT + DIRECTORY_IMPORT + USER_ROLE_CHANGE + USER_CHANGE [note: 'v5.14: пользователь создан/изменён/деактивирован администратором'] + ROLE_PERMISSION_CHANGE +} + +// ============ СПРАВОЧНИКИ ============ + +// ИСТОЧНИК: +// ТЗ: ТЗ 8.1 (пользователь ГО / пользователь РФ; закрепление ГК за РФ); Прил. 2 «Пользователь: привязка к РФ/ГО» +// Аналитика: md «Модель данных» (regional_office) +// Макет: справочник ГК: колонка «Основной РФ»; пользователи: «Ростовский РФ» и т.п. +// В модели: v4 +// Зачем: справочник филиалов; DECISION-3 — ГО явной записью +Table regional_office { + id uuid [pk] + name varchar [not null, unique] + is_head_office boolean [not null, default: false, note: 'DECISION-3: ГО — явная запись'] + is_active boolean [not null, default: true] + Note: 'Филиал: ГО и региональные филиалы (РФ)' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.1 (справочник ГК, импорт из ЕЦП CRM, создание вручную Куратором); Прил. 2 «ГК: id, наименование, id ЕЦП CRM» +// Аналитика: md «Модель данных» (company_group, SCD4) +// Макет: «Группы компаний»: Создать ГК, CRM ID «генерируется автоматически», Архив +// В модели: v4 + v5.1 (code, crm_id nullable — ANL-037) +Table company_group { + id uuid [pk] + code varchar [not null, unique, note: 'v5.1 ANL-037: внутренний код ГК, генерируется системой'] + crm_id varchar [unique, note: 'ключ из ЕЦП CRM; NULL для ГК, созданной вручную Куратором до сверки с CRM'] + name varchar [not null] + base_regional_office_id uuid [ref: > regional_office.id, note: 'закрепление ГК за филиалом (ТЗ 6.1/8.1); перезакрепление Куратором = UPDATE + снимок в history'] + is_archived boolean [not null, default: false, note: 'v5.1 макет: «Архив» ГК'] + valid_from timestamptz [not null] + updated_by uuid [ref: > app_user.id] + created_at timestamptz + updated_at timestamptz + Note: 'ГК — ТЕКУЩЕЕ состояние (SCD4). История — company_group_history' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.10 «фиксация изменений ГК/ГСК в истории изменений»; 8.2 «изменение состава ГСК, ГК» +// Аналитика: md «Модель данных» (company_group_history) +// Макет: «История изменений» в карточке ГК +// В модели: v4 +// Зачем: прошлые снимки ГК (SCD4) +Table company_group_history { + id uuid [pk] + company_group_id uuid [not null, ref: > company_group.id] + crm_id varchar + name varchar + base_regional_office_id uuid + valid_from timestamptz + valid_to timestamptz + changed_by uuid [ref: > app_user.id] + Indexes { (company_group_id, valid_from) [unique] } +} + + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.1 (ЮЛ/ИП, только одна ГСК/ГСЗ); Прил. 2 «ЮЛ: id, наименование, ИНН, id CRM, ГК, признак»; ЕХ ТЗ 6.1 «Монозаёмщик» +// Аналитика: md «Модель данных» (legal_entity, SCD4) +// Макет: «Юридические лица», «ЮЛ вне ГК» / «Монозаемщики» +// В модели: v4 + v5 (crm_id, is_mono_borrower, ГК nullable); v5.17 — kpp +Table legal_entity { + id uuid [pk] + inn varchar [not null, unique] + crm_id varchar [unique, note: 'ADD: id ЮЛ в ЕЦП CRM (Прил. 2 ТЗ)'] + entity_type entity_type + name varchar [not null] + company_group_id uuid [ref: > company_group.id, note: 'nullable: NULL = монозаёмщик (ЕХ 6.1), признак выводится'] + regional_office_id uuid [ref: > regional_office.id] + close_date date [note: 'NULL = активна'] + valid_from timestamptz [not null] + updated_by uuid [ref: > app_user.id] + created_at timestamptz + updated_at timestamptz + kpp varchar [note: 'v5.17 (добавлена последней колонкой, как её добавляет миграция 0005): КПП, nullable; 9 символов (4 цифры, 2 цифры/латинские A–Z, 3 цифры); у ИП запрещён — проверяет ядро (INVALID_KPP). Источник: макет [50][51-02][61][79], решение владельца 07.10.2026 (OQ-31)'] + Note: 'Организация (ЮЛ/ИП) — ТЕКУЩЕЕ состояние (SCD4). История — legal_entity_history' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 8.2 (журнал изменений справочников); 6.10 (история изменений состава) +// Аналитика: md «Модель данных» (legal_entity_history) +// Макет: Архив ГК: события «Переход в другую ГК», «Закрытие», дата перевода +// В модели: v4 + v5.1 (event_type, effective_date — ANL-046); v5.17 — kpp +Table legal_entity_history { + id uuid [pk] + legal_entity_id uuid [not null, ref: > legal_entity.id] + inn varchar + crm_id varchar + entity_type entity_type + name varchar + company_group_id uuid + regional_office_id uuid + close_date date + event_type le_history_event [note: 'v5.1 макет: «Переход в другую ГК» / «Закрытие» — для архива ГК'] + effective_date date [note: 'дата перевода/закрытия (не раньше текущей — ANL-046)'] + valid_from timestamptz + valid_to timestamptz + changed_by uuid [ref: > app_user.id] + kpp varchar [note: 'v5.17 (последней колонкой, миграция 0005): снимок КПП на момент события'] + Indexes { (legal_entity_id, valid_from) [unique] } +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.5 «ведение справочника соответствий наименований контрагентов», «использование ранее подтверждённых сопоставлений» +// Аналитика: md «Сводная ОСВ» (алгоритм ручного сопоставления, legal_entity_alias); FNR01 п.9 +// Макет: карточка ЮЛ: «Альтернативные наименования», «Связь с компанией из ОСВ (алиас)» +// В модели: v4 +Table legal_entity_alias { + id uuid [pk] + legal_entity_id uuid [not null, ref: > legal_entity.id] + alias varchar [not null, note: 'как в ОСВ'] + normalized_alias varchar [not null, note: 'lower/trim/без пунктуации/без ОПФ'] + created_by uuid [ref: > app_user.id] + created_at timestamptz + Indexes { + (legal_entity_id, normalized_alias) [unique] + normalized_alias [note: 'ANL-028: конфликт «один алиас у разных ЮЛ» решается при ручном сопоставлении'] + } + Note: 'Словарь соответствий наименований контрагентов (ТЗ 6.5)' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.1 (ГСК/ГСЗ в составе ГК; иерархия не поддерживается; в одной ГК несколько ГСК — сноска 11); Прил. 2 «ГСК/ГСЗ» +// Аналитика: md «Модель данных» (related_group, kind) +// Макет: вкладки «ГСК», «ГСЗ», коды GSK-001/GSZ-001 +// В модели: v4; v5.19 — crm_id +Table related_group { + id uuid [pk] + code varchar [not null, unique] + company_group_id uuid [not null, ref: > company_group.id] + kind related_group_kind [not null] + name varchar [not null] + created_date date + crm_id varchar [unique, note: 'v5.19: ID ГСК/ГСЗ в ЕЦП CRM (формы 51-03, 51-04, 77-02; arm-core#112, OQ-33); вводится вручную, импорт ЕЦП не заполняет (OQ-91); NULL — не задан'] + Note: 'ГСК/ГСЗ — current-state. Иерархия групп не поддерживается (ТЗ 6.1)' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.1 «КА может редактировать состав ГСК»; «одно ЮЛ только в одной ГСК или ГСЗ» +// Аналитика: md «Модель данных» (related_group_member, SCD2) +// Макет: «Состав», «Входит в ГСК / ГСЗ», «Редактировать состав» +// В модели: v4 (индекс уточнён — ANL-030); v5.14 — kind и индекс (legal_entity_id, kind) +Table related_group_member { + id uuid [pk] + related_group_id uuid [not null, ref: > related_group.id] + legal_entity_id uuid [not null, ref: > legal_entity.id] + kind related_group_kind [not null, note: 'v5.14: денормализация related_group.kind ради частичного уникального индекса; равенство с группой проверяет ядро при записи'] + valid_from timestamptz [not null] + valid_to timestamptz + is_current boolean [not null] + created_by uuid [ref: > app_user.id] + Indexes { + (related_group_id, legal_entity_id) [note: 'partial UNIQUE WHERE is_current'] + (legal_entity_id, kind) [note: 'partial UNIQUE WHERE is_current — v5.14: ЮЛ в одной ГСК И одной ГСЗ одновременно (решение владельца 04.10.2026, отменяет ANL-030); ГК у ЮЛ и у группы должна совпадать (проверяет ядро)'] + } + Note: 'Состав ГСК/ГСЗ — SCD2. Исключение = закрытие версии (valid_to, is_current=false)' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.2/6.5 (счета и субсчета 01…90, нормализация 60.1=60.01); Прил. 3/4 (пары счетов); сноска 32 +// Аналитика: md «Модель данных» (chart_of_account); md «Шахматка» (kind A/P/AP, row_type) +// Макет: фильтр «Дебетовые/Кредитовые счета», полный план счетов 1С в бандле +// В модели: v4 + v5 (row_type, is_off_balance) +Table chart_of_account { + id uuid [pk] + code varchar [not null, unique, note: 'нормализованный код: 60.01, 76.07.1'] + parent_id uuid [ref: > chart_of_account.id] + name varchar [not null] + kind account_kind + row_type account_row_type [not null, note: 'FIX: используется в «Шахматке»'] + is_off_balance boolean [not null, default: false, note: '001, 008, 009, 011'] + Note: 'План счетов' +} + + +// ADD ТЗ Прил. 3/4 как данные (сноски 32/35: пары могут корректироваться на этапе реализации) +// ИСТОЧНИК: +// ТЗ: ТЗ 6.4 + Прил. 3 «Перечень статей ББ» и Прил. 4 «Модель расчётов ОФР»; сноски 32/35 «могут быть скорректированы на этапе реализации» +// Аналитика: md «Автоматическое сопоставление ВГО» (таблица «Правила встречных счетов» — хардкод) +// Макет: — +// В модели: v5 новая +// Зачем: правила элиминации как данные, версионируемые +Table elimination_rule { + id uuid [pk] + statement_type statement_type [not null, note: 'balance = Прил. 3, income = Прил. 4'] + rule_no smallint [not null, note: '№ строки приложения'] + article_1_line varchar [not null, note: 'статья Компании 1, код строки ББ/ОФР, напр. 1230'] + article_2_line varchar [not null, note: 'статья Компании 2, напр. 1520'] + side_1 varchar [not null, note: 'D | K — сторона Компании 1'] + measure varchar [not null, note: 'closing | turnover — сальдо на конец (ББ) или оборот (ОФР)'] + elimination_mode varchar [not null, note: 'min | full | manual — min(A,B) / вся сумма ВГО (ОФР выручка) / вручную'] + vat_handling varchar [note: 'none | check_90_01_vs_2110 | weighted_rate — только для ОФР'] + excise_adjust boolean [not null, default: false] + comment text + version_no int [not null] + valid_from date [not null] + valid_to date + Indexes { (statement_type, rule_no, version_no) [unique] } + Note: 'Правило элиминации. Состав счетов — в elimination_rule_account' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ Прил. 3/4 (столбцы «Пары счетов Компании 1 и Компании 2», исключения «76 кроме 76.7.1») +// Аналитика: md «Автоматическое сопоставление ВГО» +// Макет: — +// В модели: v5 новая +// Зачем: состав счетов сторон правила +Table elimination_rule_account { + id uuid [pk] + rule_id uuid [not null, ref: > elimination_rule.id] + company_no smallint [not null, note: '1 или 2'] + account_id uuid [not null, ref: > chart_of_account.id] + is_excluded boolean [not null, default: false, note: 'true = исключение внутри маски (напр. «76 кроме 76.7.1»)'] + Note: 'Счета/субсчета сторон правила' +} + + +// ============ ПОЛЬЗОВАТЕЛИ И ДОСТУП ============ + +// ИСТОЧНИК: +// ТЗ: ТЗ 8.1 (роли, ГО/РФ, ЗО); Прил. 2 «Пользователь: ФИО, роль, привязка к РФ/ГО, ЗО, табельный номер»; РАИСА +// Аналитика: md «Аутентификация и авторизация» (users: email, role, JWT РАИСА); md «Модель данных» (app_user) +// Макет: «Пользователи»: Логин, Роль, Активен, Деактивация +// В модели: v4 + v5 (employee_no, business_segment) +Table app_user { + id uuid [pk] + external_id varchar [unique, note: 'субъект РАИСА/SSO; аутентификация внешняя (ANL-018)'] + email varchar [unique, note: 'v5.15: хранится в нижнем регистре (нормализация при записи), сравнение по lower(email) (OQ-59)'] + full_name varchar [not null] + employee_no varchar [note: 'ADD: табельный номер (Прил. 2 ТЗ)'] + regional_office_id uuid [not null, ref: > regional_office.id, note: 'ГО или РФ (DECISION-3)'] + business_segment business_segment [note: 'ADD: зона ответственности ДКБ/ДМСБ/ДМ (ТЗ 8.1)'] + is_active boolean [not null, default: true] + created_at timestamptz + updated_at timestamptz +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 8.1 таблица ролей (КА РФ, КА ГО, РКА, КМ, Куратор, Эксперт, Администратор); Прил. 2 «Роль» +// Аналитика: md «Ролевая модель»; md «Модель данных» (role.code) +// Макет: «Изменение ролей и прав доступа» (Аналитик ДКБ, Наблюдатель… — расходится с ТЗ, ANL-034) +// В модели: v4 (коды → ТЗ в v5); v5.13 — матрица полномочий в role_permission +Table role { + id uuid [pk] + code varchar [not null, unique, note: 'ТЗ 8.1: KA_RF | KA_GO | RKA | CLIENT_MANAGER | CURATOR_GO | EXPERT | ADMIN. Seed; администратор может заводить дополнительные роли (замена исключениям по пользователю)'] + name varchar [not null] + description text + is_system boolean [not null, default: false, note: 'роли ТЗ 8.1 — не удаляются'] + is_active boolean [not null, default: true] + Note: 'Роль. Полномочия — через role_permission (v5.13); код роли в бизнес-логике больше не проверяется' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ Прил. 2 «Роль: перечень полномочий»; сноска 29 «матрица доступов будет разработана» +// Аналитика: md «Ролевая модель» +// Макет: карточка роли: «Права: Просмотр, редактирование КФО / справочники / консолидации» +// В модели: v5 новая, убрана в v5.3/v5.4, ВОЗВРАЩЕНА в v5.13 (замечание 1) +// Зачем: атомарное право «объект × действие»; seed, администратор новые коды не создаёт +Table permission { + id uuid [pk] + code varchar [not null, unique, note: 'напр. CONSOLIDATION_EDIT, KFO_VERIFY, DIRECTORY_EDIT, USERS_ADMIN'] + object_type permission_object [not null] + action permission_action [not null] + name varchar [not null] + description text + Indexes { (object_type, action) [unique] } + Note: 'Справочник прав (seed, привязан к коду). Ограничения по ЗО/филиалу и статусу КФО — отдельный policy-слой поверх прав: право говорит «может», policy — «эту ли и сейчас ли»' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ Прил. 2 «Роль: перечень полномочий» +// Аналитика: нет +// Макет: «Права» в карточке роли, «Изменение ролей и прав доступа» +// В модели: v5.13 (возвращена) +// Зачем: матрица доступов как данные; редактируется администратором, история — audit_event(ROLE_PERMISSION_CHANGE) +Table role_permission { + role_id uuid [not null, ref: > role.id] + permission_id uuid [not null, ref: > permission.id] + granted_by uuid [ref: > app_user.id] + granted_at timestamptz + Indexes { (role_id, permission_id) [pk] } + Note: 'effective_permissions(user) = ∪ permissions(roles(user)). Прямых прав у пользователя нет (решение 30.09): исключения — через заведение роли' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 8.1 (роль пользователя); Прил. 2 «Пользователь — Роль: многие-к-одному» +// Аналитика: md «Модель данных» v4 (user_role M:N) +// Макет: «Роль» пользователя +// В модели: v4 +// Зачем: M:N оставлен (пользователь может быть КА и Куратором); если ТЗ строго 1:1 — заменить на app_user.role_id +Table user_role { + id uuid [pk] + user_id uuid [not null, ref: > app_user.id] + role_id uuid [not null, ref: > role.id] + Indexes { (user_id, role_id) [unique] } + Note: 'M:N current-state. История назначений — audit_event(USER_ROLE_CHANGE)' +} + +// ============ ФАЙЛЫ / РАСПОЗНАВАНИЕ ============ + +// ИСТОЧНИК: +// ТЗ: 6.2 (файлы с префиксом UUID, исходные документы хранятся); 8.4 «хранение 5 лет с даты прекращения отношений, архивирование/удаление»; ЕХ 6.2 «ссылка на исходные документы с возможностью скачать», ЕХ 8.3 «архивирование в data lake» +// Аналитика: md «Модель данных» v4 (s3_key, raw_result_s3_key — строки) +// Макет: — +// В модели: v5.2 новая (DECISION-4), подтверждена в v5.4 +// Зачем: единая точка ключей всех бакетов для lifecycle/ретеншна и дедупа; без реестра ключи размазаны по 4 таблицам +Table s3_object { + id uuid [pk] + bucket_role s3_bucket_role [not null] + bucket varchar [not null] + key varchar [not null, note: 'схема ключа: {file_id}/{job_id}/{name}'] + content_type varchar + size_bytes bigint + sha256 varchar + version_id varchar [note: 'S3 object version при включённом versioning'] + created_by varchar [note: 'arm-core | tabular-parser | scan-gateway | user:{id}'] + created_at timestamptz [not null] + expires_at timestamptz [note: 'lifecycle: NULL = весь срок (ТЗ 8.4); exports/ = 7 дней; results/ — решение ARCH-010'] + archived_to varchar [note: 'ссылка в data lake после архивирования (ЕХ 8.3)'] + Indexes { (bucket, key) [unique] } + Note: 'Реестр объектов S3. stored_file / recognition_job ссылаются сюда FK' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.2 (типы и форматы документов, UUID); 8.2 «первичные документы не редактируются, только замена с версионностью» +// Аналитика: md «Загрузка документов» (панель, UC-01…05); FNR01 «Маппинг stored_file» +// Макет: «Первичные документы», «Загрузка документов», «Замена документа», «Удаление документа» +// В модели: v4 + v5 (version_no, superseded_by) + v5.2 (s3_object_id); v5.13 — только ФИЗИЧЕСКИЙ файл, документы → document; v5.18 — consolidation_id +Table stored_file { + id uuid [pk] + legal_entity_id uuid [not null, ref: > legal_entity.id, note: 'организация-владелец (выбрана при загрузке)'] + file_type file_type [not null] + original_name varchar + s3_object_id uuid [not null, ref: > s3_object.id, note: 'исходный файл в uploads'] + content_hash varchar [note: 'sha256, дедуп (UC-01 A2)'] + size_bytes bigint + status file_status [not null] + version_no int [not null, default: 1, note: 'ADD ТЗ 8.2: версия при замене'] + superseded_by_file_id uuid [ref: > stored_file.id, note: 'ссылка на файл-замену; статус SUPERSEDED. Замена — файл ЦЕЛИКОМ со всеми документами в нём (решение 01.10)'] + current_recognition_job_id uuid [ref: > recognition_job.id, note: 'авторитетный прогон; его результат породил актуальные document'] + uploaded_by uuid [ref: > app_user.id] + uploaded_at timestamptz + updated_at timestamptz + consolidation_id uuid [ref: > consolidation.id, note: 'v5.18: консолидация (период ГК), в контексте которой загружен файл — основа «рабочего стола консоли» (полный состав — context/05-domain-rules.md §9.5 п. 11), общего для версий периода; NULL — без контекста. Пишется при загрузке; при автозамене файл без контекста наследует значение заменённого'] + Indexes { + (legal_entity_id, status) + (legal_entity_id, consolidation_id) [note: 'v5.18: основа рабочего стола консоли для ЮЛ (§9.5 п. 11)'] + current_recognition_job_id [note: 'v5.15: проверка FK при удалении recognition_job / файла (OQ-117)'] + } + Note: 'v5.13: физический файл одной загрузки (S3 — только ссылка). Что внутри — document (1:N). Первичка не редактируется. Удаление физическое запрещено после INITIATED — только SUPERSEDED (ANL-020). v5.18: consolidation_id — где загружен; что использует версия — consolidation_document' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.2 (типы документов: ББ, ОФР, ОСВ по счетам; обязательный набор); 5.1 (подход); 8.2; Прил. 2 «Документ ФО» +// Аналитика: md «Загрузка документов» (чек-лист, UC-01 A1 период, «Подтвердить данные»); md «Парсинг ОСВ» (счёт/период из шапки) +// Макет: «Чек-лист загруженных документов», «Соответствует период», «Не соответствует контрагент», «Подтвердить данные» +// В модели: v5.13 новая (замечание 6-бис); v5.19 — file_ordinal, уникальность типа только для не-форм; +// v5.20 — is_modified, original_values, modified_by/at (уточнение периода и счёта ОСВ, OQ-161) +// Зачем: один файл = N документов (PDF ББ+ОФР; xlsx с несколькими ОСВ). Чек-лист, проверки, подтверждение и +// FK разобранных данных — здесь; без этого «ОСВ 58 загружена?» по файлу не ответить +Table document { + id uuid [pk] + stored_file_id uuid [not null, ref: > stored_file.id] + legal_entity_id uuid [not null, ref: > legal_entity.id, note: 'денормализация stored_file.legal_entity_id — выборки чек-листа по ЮЛ+период'] + document_type document_type [not null] + osv_account_code varchar [note: 'для OSV — счёт по шапке (01, 60, 62…), нормализованный; NULL для прочих типов'] + period_year smallint [note: 'из шапки/формы'] + period_quarter period_quarter + is_cumulative boolean [note: 'true = нарастающий итог с начала года'] + reporting_date date [note: 'отчётная дата, если определена'] + locator varchar [note: 'где в файле: лист xlsx / диапазон страниц PDF (напр. «sheet:ОСВ 58», «pages:1-2»)'] + status document_status [not null] + period_check document_check_result [note: 'UC-01 A1 / макет «Соответствует период»'] + counterparty_check document_check_result [note: 'макет «Не соответствует контрагент» — ИНН/наименование из шапки vs legal_entity'] + confirmed_by uuid [ref: > app_user.id, note: 'кто нажал «Подтвердить данные» → audit_event(DOCUMENT_CONFIRM)'] + confirmed_at timestamptz + created_at timestamptz + updated_at timestamptz + file_ordinal smallint [not null, default: 0, note: 'v5.19: индекс документа в documents[] результата распознавания (с 0), у всех документов при любом MAJOR контракта; несозданный документ номер не занимает (номера с пропусками); различает две формы одного типа в файле (Р-10)'] + is_modified boolean [not null, default: false, note: 'v5.20: период или счёт ОСВ уточнены аналитиком и отличаются от распознанных (возврат к исходному снимает признак)'] + original_values jsonb [note: 'v5.20: как распознано, до первой правки — {period_year, period_quarter, is_cumulative, osv_account_code}; NULL = не правилось; после первой правки не меняется'] + modified_by uuid [ref: > app_user.id, note: 'v5.20: кто последним уточнил период или счёт'] + modified_at timestamptz + Indexes { + (stored_file_id, document_type, osv_account_code) [note: 'partial UNIQUE WHERE document_type NOT IN (\'BALANCE\', \'INCOME\') — NULLS NOT DISTINCT; v5.19: одна ОСВ по счёту / одна расшифровка / один прочий на файл; формы ББ/ОФР одного типа в файле могут повторяться (Р-10)'] + (stored_file_id, file_ordinal) [unique, note: 'v5.19: номер документа уникален в файле'] + (legal_entity_id, document_type, osv_account_code, period_year, period_quarter, status) [note: 'чек-лист required_document_rule'] + } + Note: 'Логический документ внутри файла. Создаётся ядром при маппинге результата recognition_job. Разобранные данные: OSV → osv_entry; BALANCE/INCOME → financial_statement_meta. Счётчики «исправлено полей» — COUNT(is_modified) по данным, не хранятся. v5.19: предупреждения и нарушения §7 — document_issue; две формы одного типа и периода в файле не автоподтверждаются (Р-18). v5.20: период и счёт ОСВ уточняются аналитиком на месте, распознанное — в original_values, + audit_event(RECOGNIZED_DATA_EDIT, before/after); уточнение подтверждённого документа сбрасывает подтверждение и снимает привязки к версиям (05-domain-rules §9.5 п. 12)' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.2 (статусы процесса распознавания, ИС Сканирование); 6.10 «повторная обработка»; 7.1 +// Аналитика: FNR01 «Маппинг recognition_job»; md «Загрузка документов» UC-02; md «Парсинг ОСВ» (схема группировок шапки) +// Макет: «Система распознавания: получен ответ», «Обработка», «Ошибка» +// В модели: v4, переписана в v5.2 под контракт NATS (DECISION-4); v5.13 — group_schema jsonb, убран raw_result +Table recognition_job { + id uuid [pk, note: 'job_id в контракте NATS'] + file_id uuid [not null, ref: > stored_file.id] + pipeline recognition_pipeline [not null, note: 'tabular → tabular-parser; image → scan-gateway'] + request_subject varchar [not null, note: 'recognition.tabular.request | recognition.image.request'] + request_msg_id varchar [unique, note: 'Nats-Msg-Id запроса (outbox)'] + result_msg_id varchar [unique, note: 'Nats-Msg-Id результата (inbox, дедуп)'] + schema_version varchar [not null, note: 'версия контракта сообщений'] + service_name varchar [note: 'tabular-parser | scan-gateway — из результата'] + service_version varchar + status recognition_status [not null] + attempt smallint [not null, default: 1] + max_attempts smallint [not null, default: 1, note: 'OCR: 1 (0 повторов), парсер: 3'] + requested_at timestamptz + published_at timestamptz + started_at timestamptz + finished_at timestamptz + reply_deadline timestamptz [note: 'таймаут ожидания (OCR — 20 мин)'] + external_task_id varchar [note: 'id задания в ИС Сканирование (только image)'] + error_code varchar [note: 'UNSUPPORTED_FORMAT | UNREADABLE | TIMEOUT | SCHEMA_MISMATCH | …'] + error_message text + result_s3_object_id uuid [ref: > s3_object.id, note: 'нормализованный JSON в results — единственная ссылка на результат (v5.13). Сырой ответ ИС Сканирование — S3 raw/{job_id}.json по конвенции, в БД не регистрируется'] + result_schema_version varchar [note: 'версия схемы JSON результата (ARCH-008/009)'] + group_schema jsonb [note: 'v5.13 (вместо osv_group_schema): схема группировок шапки ОСВ по листам — [{\"locator\":\"sheet:ОСВ 58\",\"groups\":[{\"type\":\"ACCOUNT\"},{\"type\":\"COUNTERPARTY\",\"has_inn\":true},{\"type\":\"CONTRACT\"}]}]; только для tabular'] + metrics jsonb [note: 'duration_ms, pages, rows, warnings (v5.19 / контракт 2.0: предупреждения уровня файла — структуры {code, severity, message, locator?}; error уровня файла блокирует RECOGNIZED документов файла)'] + fields_total int [note: 'v5.7: всего извлечённых значений (ячейки формы / строки ОСВ)'] + fields_low_confidence int [note: 'v5.7: значений с confidence < 100 (ТЗ 6.2) — заполняется при маппинге результата'] + fields_unrecognized int [note: 'v5.7: значений с is_recognized = false'] + statements_version varchar [note: 'v5.19: service.statements_version результата — коммит копии общего кода arm_statements; при пересчёте после правки сравнивается с копией ядра (расхождение — document_issue info)'] + Indexes { (file_id, attempt) [unique] } + Note: 'РЕШЕНИЕ v5.4: единственная точка обмена с NATS. Запись = outbox: создаётся в queued в одной транзакции с stored_file, фоновый публикатор переводит в published (при сбое публикации — повтор по queued старше N сек); результат приходит по NATS, дедуп по result_msg_id UNIQUE; redelivery после max_deliver → status=dlq, replay = сброс в queued с attempt+1. Ядро маппит JSON из S3 в document → osv_entry / financial_statement_*' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.2 (Osv_report_lines); 6.5 (строка ОСВ: компания, счёт, контрагент, признак, 6 сумм); Прил. 2 «Строка сводной ОСВ», «Распознанный показатель» +// Аналитика: FNR01 «Маппинг osv_entry»; md «Парсинг ОСВ» п.11 (row_number, level, group_type, data_type) +// Макет: «Оборотно-сальдовая ведомость»: Дебет/Кредит начало/оборот/конец, «Тип контрагента» +// В модели: v4 + v5 (owner_legal_entity_id — FIX, parent_entry_id, is_modified, is_excisable); v5.13 — document_id, group_type вместо group_schema_id; v5.16 — counterparty_match_kind +Table osv_entry { + id uuid [pk] + recognition_job_id uuid [not null, ref: > recognition_job.id] + document_id uuid [not null, ref: > document.id, note: 'v5.13: ОСВ-документ (счёт + период); файл — через document.stored_file_id'] + owner_legal_entity_id uuid [not null, ref: > legal_entity.id, note: 'FIX: организация-ВЛАДЕЛЕЦ ОСВ (денормализация). В v4 называлось legal_entity_id с ошибочной note'] + parent_entry_id uuid [ref: > osv_entry.id, note: 'родитель в дереве строк ОСВ (ТЗ 6.5). ОТКРЫТО (замечание 2, отложено 01.10): хранить ли только контрагентские строки и нужно ли дерево'] + group_type osv_group_type [note: 'v5.13: тип строки по схеме шапки (recognition_job.group_schema) — ACCOUNT / DEPARTMENT / COUNTERPARTY / CONTRACT / OTHER'] + group_name varchar [note: 'исходное название группировки из шапки («Контрагенты», «Договоры»)'] + row_number int + level smallint + row_value varchar [note: 'исходный текст строки'] + data_type osv_data_type + account_code varchar [note: 'сырой код счёта'] + account_id uuid [ref: > chart_of_account.id] + account_root varchar + counterparty_name varchar [note: 'сырое имя из ОСВ, не изменяется'] + counterparty_inn varchar [note: 'сырой ИНН, не изменяется'] + counterparty_id uuid [ref: > legal_entity.id, note: 'резолв по ИНН/имени/алиасу или ручное сопоставление; NULL = не сопоставлен. Признак ГСК/ГК/Внешний выводится из периметра версии (DECISION-5)'] + opening_debit numeric(18,2) + opening_credit numeric(18,2) + turnover_debit numeric(18,2) + turnover_credit numeric(18,2) + closing_debit numeric(18,2) + closing_credit numeric(18,2) + is_modified boolean [not null, default: false, note: 'значения правились аналитиком'] + original_values jsonb [note: 'v5.6: суммы до первой ручной правки {opening_debit,…}; NULL = не правилось'] + modified_by uuid [ref: > app_user.id] + modified_at timestamptz + is_excisable boolean [note: 'ADD ТЗ 6.4: признак «подакцизный товар» для ОСВ 90'] + counterparty_match_kind counterparty_match_kind [note: 'v5.16: NULL ⇔ counterparty_id NULL; INN/NAME/ALIAS — шаг автоматического резолва при маппинге; MANUAL — ручное сопоставление; PROPAGATED — автоприменение по имени в версии (DOC-221278 п. 12–13)'] + Indexes { + (document_id, row_number) [unique] + (owner_legal_entity_id, account_id, counterparty_id) + parent_entry_id [note: 'v5.15: обход дерева строк и проверка self-FK при удалении документа (OQ-117)'] + recognition_job_id [note: 'v5.15: проверка FK при удалении recognition_job / файла (OQ-117)'] + } + Note: 'Строка ОСВ. Правки сумм аналитиком — original_values/modified_by + audit_event(RECOGNIZED_DATA_EDIT, before/after)' +} + + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.2 «извлекаются значения по кодам форм Приказа 157н»; 6.3 проверки единиц измерения/даты +// Аналитика: FNR01 «fin_report_header» (report_type, org, unit, currency, reporting_date); md «Модель данных» v4 +// Макет: «Реквизиты организации» (ОКПО, ОКОПФ, ОКФС, ОКУД, ОКЕИ, адрес), «Единица измерения», «Отчетная дата» +// В модели: v4 (FIX pk) + v5.1 (реквизиты — ANL-044); v5.13 — document_id; v5.19 — form_variant, needs_review_fields +Table financial_statement_meta { + id uuid [pk, note: 'FIX: был без PK'] + document_id uuid [not null, unique, ref: > document.id, note: 'v5.13: документ BALANCE/INCOME (1:1); файл — через document'] + recognition_job_id uuid [not null, ref: > recognition_job.id] + statement_type statement_type [not null] + inn varchar + inn_original_value varchar + inn_confidence numeric(5,2) + inn_verified boolean + inn_modified boolean + organization_name varchar [note: 'как в документе; сверяется с legal_entity/alias, при несовпадении — document.counterparty_check'] + report_date date + report_date_original_value varchar [note: 'FIX: строка как распознано (был `date []`)'] + report_date_verified boolean + report_date_modified boolean + units varchar [note: 'тыс. руб. / руб.'] + units_original_value varchar + units_verified boolean + units_modified boolean + currency varchar [default: 'RUB'] + okpo varchar [note: 'v5.1 ANL-044: реквизиты по макету экрана распознавания'] + okopf varchar + okfs varchar + okud varchar [note: '0710001 / 0710002'] + okei varchar + legal_form varchar [note: 'ОПФ'] + ownership_form varchar + address varchar + subject_to_audit boolean + reviewed_by uuid [ref: > app_user.id, note: 'v5.9: кто проверил данные формы; подтверждение документа — document.confirmed_by'] + reviewed_at timestamptz + checks_accepted_by uuid [ref: > app_user.id, note: 'v5.9 ТЗ 6.3 п.7: акцепт КА непройденных проверок (напр. 1370/2400) с комментарием'] + checks_accepted_at timestamptz + checks_accepted_comment text + form_variant statement_form_variant [note: 'v5.19: full | simplified — по структуре кодов (§11.7); выбирает набор соотношений §7; NULL — документ до v5.19 или результат 1.x: набор полный'] + needs_review_fields jsonb [note: 'v5.19: имена полей шапки, требующих проверки (["report_date"]), как пришло от сервиса; правка поля или подтверждение тем же значением убирает его из списка'] + header_source jsonb [note: 'v5.19: шапка результата как пришла — {"<поле>": {"text": <поле>_text, "confidence": <поле>_confidence}} для organization_name, inn, report_date, units, okud, okpo, okopf, okfs, okei, address; не меняется. *_original_value — как прежде: inn_original_value = inn, report_date_original_value = report_date_text, units_original_value = units_text; inn_confidence = header_source.inn.confidence'] + organization_name_original_value varchar [note: 'v5.19: наименование организации из результата; правками не меняется'] + organization_name_modified boolean [note: 'v5.19: наименование правилось аналитиком (PATCH шапки)'] + Note: 'Шапка распознанной формы ББ/ОФР. v5.19: результат проверок §7 и предупреждения хранятся в document_issue как пришли от сервиса и пересчитываются ядром только после правок (пересматривает «не хранятся — считаются на лету»)' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.3 п.7 «стр. 1370 на конец и на начало года»; 6.7 «УК ДО на отчётную дату» +// Аналитика: FNR01 «rows[0].cells[2..4] — наименования колонок периода»; md «Логические проверки» («по каждой отчётной дате (колонке)») +// Макет: колонки «На 30 сентября 2025 г.», «На 31 декабря 2024 г.», «Выбор периодов» +// В модели: v5 новая (FIX-14) +// Зачем: дата колонки — без неё межформенная проверка и гудвилл не считаются +Table financial_statement_column { + id uuid [pk] + meta_id uuid [not null, ref: > financial_statement_meta.id] + column_index smallint [not null] + label varchar [note: 'как в форме: «На 30 сентября 2025 г.», «За 9 месяцев 2025 г.»'] + period_date date [note: 'ADD FIX-14: дата колонки — нужна для 1370(нач.года), гудвилла «на отчётную дату», сравнения версий'] + is_current boolean [note: 'колонка отчётного периода'] + period_kind varchar [note: 'v5.19: absolute | relative:current | relative:prev_year_end | relative:prev_prev_year_end | relative:prev_period | none; относительные подписи бланка 66н — period_date от эффективной даты документа, ядро досчитывает после правки даты отчёта (Р-6)'] + label_confidence numeric(5,2) [note: 'v5.19: уверенность подписи колонки (Excel — 100; подписи нет — NULL)'] + Indexes { (meta_id, column_index) [unique] } + Note: 'Колонки-периоды формы (2–3 сравнительные даты)' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.2 (коды статей по формам 157н); 6.3 (Таблица 1 — коды строк 1100…2400) +// Аналитика: FNR01 «fin_report_rows» (row_name, row_code, section, is_total_row); md «Модель данных» v4 +// Макет: «Результат распознавания»: Наименование показателя, Код, разделы +// В модели: v4 (FIX: убраны копипаст-поля); v5.19 — строки без кода и повторы кода, статусы, порядок, needs_review +Table financial_statement_line { + id uuid [pk] + meta_id uuid [not null, ref: > financial_statement_meta.id] + line_code varchar [note: 'код строки ОКУД, напр. 1230'] + line_code_original_value varchar [note: 'v5.19: line_code строки из результата как пришёл (NULL у unreadable / missing / detail и у строк, созданных правкой); правками кода не меняется. До v5.19 NULL был признаком «создана правкой» — теперь это row_index IS NULL'] + line_code_confidence numeric(5,2) + line_code_modified boolean + line_name varchar + line_name_original_value varchar + line_name_confidence numeric(5,2) + line_name_modified boolean [note: 'FIX: был numeric'] + row_index int [note: 'v5.19: порядок строки в документе источника (с 0). NULL ⇔ строка создана правкой аналитика (шаблонная, origin = template); у строк из результата — всегда не NULL (маппер 1.x и 2.0)'] + source_ref varchar [note: 'v5.19: положение в источнике (row:8, row:14#2, Баланс!C27); NULL у строк, созданных правкой'] + line_status statement_line_status [not null, default: 'ok', note: 'v5.19: ok | unreadable | missing | detail; line_code пуст ⇔ статус не ok'] + line_code_text varchar [note: 'v5.19: сырой текст ячейки кода, как распознано'] + parent_row_index int [note: 'v5.19: row_index строки-родителя у detail; пересчитывается при правке'] + needs_review boolean [not null, default: false, note: 'v5.19: неуверенный код не подтверждён структурой (как пришло от сервиса; правка или подтверждение кода — false)'] + is_confirmed boolean [not null, default: false, note: 'v5.19: код подтверждён аналитиком без изменения (PATCH lines confirmed)'] + Indexes { + (meta_id, line_code) [note: 'v5.19: не уникален — повтор кода законен (Р-4); чтения «по коду» — агрегат формы по коду'] + (meta_id, source_ref) [note: 'partial UNIQUE WHERE source_ref IS NOT NULL — v5.19: положение в источнике уникально в форме'] + } + Note: 'Строка формы как в источнике (v5.19): строки с кодом, без кода (unreadable / missing / detail) и повторы кода; раскладка экрана по коду и шаблон формы — на фронте и в ядре по словарю имён' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.2 «уверенность распознавания ниже 100% → Требуется ручная проверка»; Прил. 2 «Распознанный показатель: значение, уверенность, признак ручной корректировки» +// Аналитика: FNR01 (value_current/prior/prior2, confidence, скобки → отрицательное); md «Логические проверки» (правка ячеек) +// Макет: подсветка ячеек, «не распознано», «Редактировать/Сохранить», «Подтвердить данные» +// В модели: v4 + v5 (column_id, confidence, original_amount, modified_by); v5.13 — убран needs_review; v5.19 — needs_review хранится, source_text, is_confirmed +Table financial_statement_value { + id uuid [pk] + line_id uuid [not null, ref: > financial_statement_line.id] + column_id uuid [not null, ref: > financial_statement_column.id] + amount numeric(18,2) + string_value varchar [note: 'как распознано, если не число'] + confidence numeric(5,2) [note: 'уверенность распознавания (Прил. 2 ТЗ). v5.19: подсветка — только needs_review (уверенность, is_recognized и §7 сведены сервисом)'] + is_recognized boolean + is_modified boolean [not null, default: false] + original_amount numeric(18,2) [note: 'значение до ручной правки'] + modified_by uuid [ref: > app_user.id] + modified_at timestamptz + source_text varchar [note: 'v5.19: сырой текст ячейки источника (values[].text), не меняется'] + needs_review boolean [not null, default: false, note: 'v5.19: как пришло от сервиса (подтверждение проверкой §7, 05-domain-rules.md §11.9), пересчитывается ядром после правок; is_modified или is_confirmed ⇒ false. Пересматривает п. 4 v5.13'] + is_confirmed boolean [not null, default: false, note: 'v5.19: подтверждено аналитиком без изменения значения (is_modified не ставится)'] + confirmed_by uuid [ref: > app_user.id] + confirmed_at timestamptz + Indexes { (line_id, column_id) [unique] } +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.3 (логические проверки, акцепт); 6.2 «уверенность ниже 100% → Требуется ручная проверка» +// Аналитика: openspec/changes/archive/2026-10-19-unified-statement-normalization (design: шаг 8, «Что уходит из ядра») +// Макет: «Результат распознавания»: ошибки проверок, подсветка ячеек +// В модели: v5.19 новая +// Зачем: предупреждения сервиса и нарушения §7 с привязкой к строкам, ячейкам и полям шапки — экран показывает их у +// места и после сохранения; ядро не пересчитывает их при загрузке (Decisions № 17, 19) +Table document_issue { + id uuid [pk] + document_id uuid [not null, ref: > document.id] + kind document_issue_kind [not null] + code varchar [not null, note: 'код предупреждения (05-domain-rules.md §11.9); у relation — RELATION_FAILED (severity error), у soft — RELATION_SOFT (severity info)'] + severity issue_severity [not null] + message text [not null] + line_ids jsonb [note: 'массив financial_statement_line.id, к которым относится запись (нарушение — все строки кодов соотношения); FK нет — при удалении шаблонной строки (назначение её кода строке источника) ядро убирает её id из line_ids всех записей документа'] + column_id uuid [ref: > financial_statement_column.id] + column_index smallint [note: 'столбец сетки из предупреждения, если колонки нет среди financial_statement_column (COLUMN_SKIPPED и др.); у колонки формы — column_id'] + codes jsonb [note: 'для relation / soft: коды цели и членов соотношения (["1600","1100","1200"]); экран подсвечивает строки этих кодов'] + field varchar [note: 'поле шапки (report_date, inn, organization_name, …)'] + source issue_source [not null] + relation varchar [note: 'для relation / soft: текст соотношения (1600 = 1100 + 1200)'] + expected numeric(18,2) [note: 'для relation / soft: цель'] + actual numeric(18,2) [note: 'для relation / soft: правая часть'] + created_at timestamptz [not null] + Indexes { document_id } + Note: 'v5.19: предупреждения и нарушения документа (формы — предупреждения и нарушения §7; ОСВ — предупреждения листа OSV_* результата 2.0). Удаляются вместе с документом при перезагрузке файла; при пересчёте после правки relation / soft заменяются целиком, warning источника service сохраняются, кроме снимаемых правкой (таблица §11.9)' +} + + +// ============ КОНСОЛИДАЦИЯ ============ + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.10 (процесс формирования КФО за отчётный период); 7.2 «формируется по требованию»; Прил. 2 «Консолидация: ГСК, отчётный период» +// Аналитика: md «Сводная ОСВ» / «Шахматка» (consolidation.year/quarter); md «Модель данных» v4 +// Макет: «Создание консолидации: ГК → ГСК → Квартал» +// В модели: v4 + v5 (reporting_date) +// Зачем: логическая консолидация ГСК+период; версии — ниже +Table consolidation { + id uuid [pk] + company_group_id uuid [not null, ref: > company_group.id, note: 'v5.9: консолидация создаётся от ГК'] + related_group_id uuid [ref: > related_group.id, note: 'v5.9: ГСК — NULL до утверждения; фиксируется/создаётся при VERIFIED по составу consolidation_member (ANL-029)'] + year smallint [not null] + quarter period_quarter [not null] + reporting_date date [not null, note: 'ADD: 01.04 / 01.07 / 01.10 / 01.01 след. года — для ЕХ и сравнений'] + created_at timestamptz + Indexes { (company_group_id, year, quarter) [unique] } + Note: 'Логическая консолидация ГК за период; версии различаются периметром (consolidation_member). Прошлые периоды — по company_group_id. v5.18: файлы, загруженные в консолидацию, — stored_file.consolidation_id (основа рабочего стола; полный состав — context/05-domain-rules.md §9.5 п. 11)' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 5.1 (сценарий, подход, чекбокс Гудвилл); 6.10 (статусная модель, маршрут по инициатору, № и дата решения УОБ, «новая версия КФО» после Верифицирован); 6.4 (причины отклонений от Методики) +// Аналитика: md «Статусная модель»; md «Модель данных» v4 (consolidation_version: version_no, status varchar, initiator, approved_in_rf, verified_in_go, kfo_confirmation_enabled) +// Макет: «Версия», «Дата верификации», «Включить/Отключить подтверждение КФО», «Смена статуса отчёта», «Ответственный / Утвердил / Верифицировал» +// В модели: v4 + v5 (enum статусов, scenario, approach, goodwill_enabled, initiator_office_id, uob_*, methodology_deviations, previous_version_id) +Table consolidation_version { + id uuid [pk] + consolidation_id uuid [not null, ref: > consolidation.id] + version_no int [not null] + status consolidation_status [not null, note: 'CHG: enum вместо varchar'] + scenario consolidation_scenario [not null, note: 'ADD ТЗ 5.1'] + approach consolidation_approach [not null, default: 'BASIC', note: 'ADD ТЗ 5.1'] + goodwill_enabled boolean [not null, default: false, note: 'ADD ТЗ 5.1/6.7: чек-бокс расчёта Гудвилла'] + initiator_id uuid [not null, ref: > app_user.id] + initiator_office_id uuid [not null, ref: > regional_office.id, note: 'ГО/РФ инициатора — определяет маршрут (ТЗ 6.10)'] + approved_in_rf_by uuid [ref: > app_user.id] + approved_in_rf_at timestamptz + verified_in_go_by uuid [ref: > app_user.id] + verified_in_go_at timestamptz + uob_decision_no varchar [note: 'ADD ТЗ 6.10: № решения УОБ'] + uob_decision_date date [note: 'ADD ТЗ 6.10'] + methodology_deviations text [note: 'ADD ТЗ 6.4: причины отклонений от Методики'] + elimination_rules_version int [not null, note: 'v5.11; v5.23 not null: версия elimination_rule (version_no), действующая на дату создания версии консолидации (OQ-174); фиксируется при создании, не меняется'] + is_in_work boolean [not null, default: true] + previous_version_id uuid [ref: > consolidation_version.id, note: '«новая версия КФО» после VERIFIED'] + cancelled_reason text + created_at timestamptz + created_by uuid [ref: > app_user.id] + updated_by uuid [ref: > app_user.id] + updated_at timestamptz + Indexes { (consolidation_id, version_no) [unique] } + Note: 'Версия консолидации. После VERIFIED — read-only; изменения только через новую версию' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.10 (переходы, возврат на доработку); 8.2 «изменение статусов; согласование и утверждение КФО» +// Аналитика: md «Статусная модель» (переходы) +// Макет: «Смена статуса отчёта», «Комментарий (обязательно)», «Отклонено: отчёт возвращён на доработку» +// В модели: v5 новая +Table consolidation_status_history { + id uuid [pk] + version_id uuid [not null, ref: > consolidation_version.id] + from_status consolidation_status + to_status consolidation_status [not null] + changed_by uuid [not null, ref: > app_user.id] + changed_at timestamptz [not null] + comment text [note: 'обязателен при возврате на доработку'] + Note: 'ADD ТЗ 6.10/8.2: маршрут согласования' +} + +// ADD v5.1 (макет, ANL-036): «взять в работу» / перехват прав редактирования +// ИСТОЧНИК: +// ТЗ: нет в ТЗ (ANL-036) +// Аналитика: нет +// Макет: «Взятие КФО в работу (перехват прав редактирования)», «Причина: Отпуск», «В данный момент консолидация редактируется пользователем …» +// В модели: v5.1 новая (макет) +// Зачем: блокировка версии; подтвердить с заказчиком +// v5.16: без истечения по времени (OQ-119): активна, пока не снята владельцем/администратором или не перехвачена по причине +Table consolidation_lock { + id uuid [pk] + consolidation_version_id uuid [not null, ref: > consolidation_version.id] + locked_by uuid [not null, ref: > app_user.id] + locked_at timestamptz [not null] + released_at timestamptz [note: 'NULL = активная блокировка'] + taken_over_from uuid [ref: > app_user.id, note: 'при перехвате — предыдущий владелец'] + takeover_reason text [note: 'обязателен при перехвате (макет: «Причина: Отпуск»)'] + Indexes { consolidation_version_id [note: 'partial UNIQUE WHERE released_at IS NULL'] } + Note: 'Ответственный за версию сейчас = активная блокировка' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.1 «КА в рамках консолидации редактирует состав ГСК»; 6.10 «выбор состава ГСК»; ЕХ 6.3 «Периметр на дату» +// Аналитика: md «Сводная ОСВ» п.2 («зафиксированный периметр; изменение related_group_member не меняет версию»); md «Модель данных» v4 +// Макет: «Состав ЮЛ», «Минимум для консолидации: 2», «Редактировать состав» +// В модели: v4 + v5 (is_head_entity для Гудвилла) +Table consolidation_member { + id uuid [pk] + consolidation_version_id uuid [not null, ref: > consolidation_version.id] + legal_entity_id uuid [not null, ref: > legal_entity.id] + is_head_entity boolean [not null, default: false, note: 'ADD: головная организация (для Гудвилла)'] + Indexes { (consolidation_version_id, legal_entity_id) [unique] } + Note: 'Зафиксированный периметр версии. Изменение related_group_member не меняет существующие версии' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ Прил. 2 «Документ ФО: ссылка на Консолидацию и ЮЛ»; 6.4/6.5 «использование данных предыдущих периодов»; ЕХ 7 «повторное использование первички без дублей» +// Аналитика: md «Сводная ОСВ» п.3 (файлы выбираются по ЮЛ+год+квартал — без явной связи) +// Макет: «Первичные документы консолидации» +// В модели: v5 новая; v5.13 — document_id вместо stored_file_id +// Зачем: явная привязка документа к версии (переиспользование, монозаёмщики из ЕХ) +// v5.16: точки привязки/отвязки — подтверждение документа, добавление ЮЛ в периметр; замена/удаление файла, исключение ЮЛ (Срез 4, D-5) +Table consolidation_document { + id uuid [pk] + consolidation_version_id uuid [not null, ref: > consolidation_version.id] + document_id uuid [not null, ref: > document.id, note: 'v5.13: логический документ (ОСВ по счёту / ББ / ОФР), не файл'] + Indexes { (consolidation_version_id, document_id) [unique] } + Note: 'ADD Прил. 2 ТЗ «Документ ФО → Консолидация»: явная привязка документов к версии (переиспользование в нескольких версиях/периодах, монозаёмщики из ЕХ). Чек-лист = required_document_rule × периметр − consolidation_document' +} + + + + +// ---- Корректировки ---- +// ИСТОЧНИК: +// ТЗ: ТЗ 6.8 (форма корректировок: колонки ДБ/КР/Комментарий, >5%, импорт/экспорт, отдельная форма ОФР); 6.4 (доп. корректировки ОФР); Прил. 2 «Расхождение/корректировка»; Прил. 9 +// Аналитика: md «Корректировка данных» (correction: parent_correction_id, debit/credit_line_code, adjustment); md «Модель данных» v4 +// Макет: «Таблица корректировки»: Актив/Пассив/Контроль/Корректировка, «Строка баланса Дт/Кт», «Комментарий» +// В модели: v4 + v5 (statement_type, pair_match_id, reason_code, comment NOT NULL, status, version_no) +Table correction { + id uuid [pk] + consolidation_version_id uuid [not null, ref: > consolidation_version.id] + statement_type statement_type [not null, note: 'ADD: ББ или ОФР (ТЗ 6.8 — отдельные формы)'] + rule_id uuid [ref: > elimination_rule.id, note: 'v5.10: пара ВГО по естественному ключу (правило + компании); NULL = ручная без пары'] + parent_correction_id uuid [ref: > correction.id, note: 'дочерняя строка распределения по нескольким статьям; глубина 1'] + legal_entity_id uuid [ref: > legal_entity.id, note: 'компания 1 (чья первичка корректируется)'] + counterparty_id uuid [ref: > legal_entity.id, note: 'компания 2'] + debit_line_code varchar + debit_account_id uuid [ref: > chart_of_account.id] + debit_adjustment numeric(18,2) + credit_line_code varchar + credit_account_id uuid [ref: > chart_of_account.id] + credit_adjustment numeric(18,2) + deviation_amount numeric(18,2) + deviation_percent numeric(9,4) + reason_code varchar [note: 'ADD ТЗ 6.4: unrealized_revenue | excise | agency_commission | intra_lease_depreciation | intra_loan_interest | equity_income | other'] + comment text [not null, note: 'ТЗ 6.8: комментарий обязателен'] + status correction_status [not null, default: 'DRAFT'] + version_no int [not null, default: 1, note: 'сноска 22 ТЗ: история версий корректировки — audit_event(CORRECTION_EDIT, before/after); инкремент при каждом изменении'] + created_by uuid [ref: > app_user.id] + created_at timestamptz + updated_by uuid [ref: > app_user.id] + updated_at timestamptz + Indexes { + consolidation_version_id + (consolidation_version_id, rule_id, legal_entity_id, counterparty_id) + } + Note: 'Overlay поверх первички: итог = свод первички − Σ применённых корректировок. Расхождение пары (deviation_*) — справочно, пересчитывается' +} + + +// ---- Гудвилл (ТЗ 6.7, Прил. 3 п.2, Прил. 8) ---- +// ИСТОЧНИК: +// ТЗ: ТЗ 6.7 (Гудвилл: ФВ ГО − доля в капитале ДО, комментарий обязателен, отдельная строка ББ); Прил. 3 п.2 (58.01 против 80/83, стр. 1310/1350/1370); Прил. 8 +// Аналитика: md «Гудвилл» (шаги 1–10: 58.01, стр. 1310, доля владения, include_in_kfo); md «Модель данных» v4 (goodwill) +// Макет: «Таблица гудвилла», «Доля владения», «Учет в отчете», «Изменение долей владения (гудвилл)» +// В модели: v4 + v5 (additional_capital_amount, comment) +Table goodwill { + id uuid [pk] + consolidation_version_id uuid [not null, ref: > consolidation_version.id] + head_legal_entity_id uuid [not null, ref: > legal_entity.id] + subsidiary_legal_entity_id uuid [not null, ref: > legal_entity.id] + ownership_share numeric(7,4) [note: 'ручной ввод, %'] + financial_investment_amount numeric(18,2) [note: 'ΣДБ 58.01 ГО по ДО'] + charter_capital_amount numeric(18,2) [note: 'стр. 1310 ББ ДО на отчётную дату'] + additional_capital_amount numeric(18,2) [note: 'ADD ТЗ Прил. 3: стр. 1350 ББ ДО'] + participation_amount numeric(18,2) [note: '(1310 + 1350) * share / 100 — DECISION: уточнить у методологов, входит ли 1350 в базу'] + goodwill_amount numeric(18,2) + include_in_kfo boolean [not null, default: false] + comment text [note: 'ТЗ 6.7: обязателен при include_in_kfo'] + created_by uuid [ref: > app_user.id] + created_at timestamptz + updated_by uuid [ref: > app_user.id] + updated_at timestamptz + Indexes { (consolidation_version_id, head_legal_entity_id, subsidiary_legal_entity_id) [unique] } +} + +// ---- Результат КФО (ТЗ 6.4, Прил. 10) ---- +// ИСТОЧНИК: +// ТЗ: ТЗ 6.4 (итоговая форма КФО: подход, Гудвилл, расхождения, корректировки, верификация); 6.8 (контрольные пороги 10% ЧА / 1% ВБ, 10% прибыли / 1% выручки); Прил. 10 +// Аналитика: нет (пробел — ANL-008/009) +// Макет: «КФО», «Сводка расхождений КФО», «Есть несохранённые изменения в КФО» +// В модели: v5 новая +// Зачем: шапка результата + пороги +Table kfo_result { + id uuid [pk] + consolidation_version_id uuid [not null, unique, ref: > consolidation_version.id] + computed_at timestamptz [not null] + is_frozen boolean [not null, default: false, note: 'true после VERIFIED'] + net_assets numeric(18,2) [note: 'ЧА ГСК'] + balance_total numeric(18,2) [note: 'ВБ ГСК'] + revenue numeric(18,2) + sales_profit numeric(18,2) + total_deviation_bb numeric(18,2) [note: 'Σ расхождений по статьям ББ'] + total_deviation_ofr numeric(18,2) + threshold_bb_exceeded boolean [note: 'ТЗ 6.8: > 10% ЧА (или > 1% ВБ, если ЧА < 10% ВБ)'] + threshold_ofr_exceeded boolean [note: '> 10% прибыли от продаж (или > 1% выручки при рентабельности < 10%)'] + threshold_justification text [note: 'обоснование принятия риска при превышении'] + goodwill_total numeric(18,2) + has_deviations boolean + Note: 'Шапка результата КФО + контрольные пороги' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.4 «шаг 1 — сложение по кодам строк; шаг 2 — элиминация; неэлиминируемая часть остаётся»; Прил. 2 «Результат КФО: статья, значение»; Прил. 10; ФСБУ 4/2023 +// Аналитика: нет (пробел — ANL-008) +// Макет: колонки «в т.ч. взаимные обязательства», «Очищенные показатели», «Расхождения», «источник: Баланс/ОСВ», «в т.ч. Гудвилл» +// В модели: v5 новая + v5.1 (vgo_amount, source_kind, deviation_amount, comment) +Table kfo_result_line { + id uuid [pk] + kfo_result_id uuid [not null, ref: > kfo_result.id] + statement_type statement_type [not null] + line_code varchar [not null, note: 'код строки ФСБУ 4/2023; GOODWILL — отдельная строка раздела I'] + line_name varchar + sum_amount numeric(18,2) [note: 'шаг 1: простое сложение по компаниям'] + eliminated_auto numeric(18,2) [note: 'шаг 2: авто-элиминация по правилам'] + eliminated_manual numeric(18,2) [note: 'Σ применённых корректировок'] + goodwill_adjust numeric(18,2) + consolidated_amount numeric(18,2) [not null, note: 'итог («Очищенные показатели» в макете)'] + vgo_amount numeric(18,2) [note: 'v5.1 макет: «в т.ч. взаимные обязательства/обороты» = eliminated_auto + eliminated_manual'] + source_kind varchar [note: 'v5.1 макет: balance | osv — источник значения статьи'] + deviation_amount numeric(18,2) [note: 'v5.1 макет «Расхождения» по статье'] + comment text [note: 'v5.1 макет: пояснение к строке КФО'] + ordinal int + Indexes { (kfo_result_id, statement_type, line_code) [unique] } +} + +// ИСТОЧНИК: +// ТЗ: ЕХ ТЗ 6.6 «выгрузка расшифровки статей отчётности в разрезе контрагентов»; ТЗ 6.9 (настраиваемые поля экспорта) +// Аналитика: нет +// Макет: «Доля в показателе по группе, %», расшифровка по компаниям +// В модели: v5 новая + v5.1 (share_percent) +Table kfo_result_line_company { + kfo_result_line_id uuid [not null, ref: > kfo_result_line.id] + legal_entity_id uuid [not null, ref: > legal_entity.id] + amount numeric(18,2) + share_percent numeric(7,4) [note: 'v5.1 макет: «Доля в показателе по группе, %»'] + Indexes { (kfo_result_line_id, legal_entity_id) [pk] } + Note: 'Разрез по компаниям для расшифровки статьи (ЕХ 6.6 «расшифровка в разрезе контрагентов»)' +} + +// ---- Сценарий «Подтверждение КФО клиента» (ТЗ 5.1, 6.10) ---- +// ИСТОЧНИК: +// ТЗ: ТЗ 5.1 «подтверждение консолидированной отчётности, предоставленной Клиентом»; 6.10 «ручной ввод данных КФО клиента; сравнение и анализ расхождений»; Методика сноска 14 (процент к наименьшему) +// Аналитика: md «Статусная модель» (kfo_confirmation_enabled — только флаг; ANL-006) +// Макет: «Подтверждение КФО клиента»: Версия клиента / Версия банка, ВГО клиента / ВГО Банка, Расхождение, Причина +// В модели: v5 новая + v5.1 (client_vgo/bank_vgo/deviation_reason) +Table client_kfo_line { + id uuid [pk] + consolidation_version_id uuid [not null, ref: > consolidation_version.id] + statement_type statement_type [not null] + line_code varchar [not null] + client_amount numeric(18,2) [note: 'ручной ввод из КФО клиента («Консолидированная отчетность от клиента»)'] + client_vgo_amount numeric(18,2) [note: 'v5.1 макет: «ВГО клиента» — ручной ввод'] + bank_amount numeric(18,2) [note: 'из kfo_result_line на момент сравнения'] + bank_vgo_amount numeric(18,2) [note: 'v5.1 макет: «ВГО Банка» из kfo_result_line.vgo_amount'] + deviation_amount numeric(18,2) + deviation_percent numeric(9,4) [note: 'относительно наименьшего (Методика сноска 14)'] + deviation_reason text [note: 'v5.1 макет: «Причина расхождения»'] + comment text + entered_by uuid [ref: > app_user.id] + entered_at timestamptz + Indexes { (consolidation_version_id, statement_type, line_code) [unique] } +} + + + +// ============ КОММЕНТАРИИ, АУДИТ, ЭКСПОРТ ============ + +// ИСТОЧНИК: +// ТЗ: ТЗ 6.3 «возможность добавления комментария к отчётности» +// Аналитика: md «Загрузка документов» («Комментарий к документу») +// Макет: «Новый комментарий», «Комментарий к документу» +// В модели: v5 новая +// Зачем: полиморфные комментарии к объектам; сейчас используется привязка к документу +Table comment { + id uuid [pk] + object_type varchar [not null, note: 'document | consolidation_version | …'] + object_id uuid [not null] + text text [not null] + author_id uuid [not null, ref: > app_user.id] + created_at timestamptz [not null] + Indexes { (object_type, object_id) } + Note: 'ТЗ 6.3; AURORA-1446: комментарии к документу. Правка и удаление комментариев не предусмотрены; аудит не ведётся' +} + +// ИСТОЧНИК: +// ТЗ: ТЗ 8.2 (журнал изменений, логирование всех действий, перечень событий: вход/выход, создание консолидации, ГСК/ГК, загрузка, распознанные данные, корректировки, статусы, утверждение, выгрузка; хранение ≥ срока данных); Прил. 2 «Запись журнала изменений» +// Аналитика: нет (пробел — ANL-019); md «Ролевая модель» ссылается на «журнал аудита» +// Макет: «Журнал действий»: разделы, Объект/Событие/Что изменилось/Результат/Идентификатор, IP/браузер, «неверный пароль» +// В модели: v5 новая + v5.1 (section, result, changed_field, user_agent) +Table audit_event { + id uuid [pk] + occurred_at timestamptz [not null] + user_id uuid [ref: > app_user.id, note: 'NULL для системных событий'] + action audit_action [not null] + section audit_section [not null, note: 'v5.1 макет: раздел журнала'] + object_type varchar [not null] + object_id uuid + consolidation_version_id uuid [ref: > consolidation_version.id, note: 'для выборки «история изменений КФО»'] + description text + before_value jsonb + after_value jsonb + comment text + result varchar [note: 'v5.1 макет: Успешно / Отклонено / Ошибка'] + changed_field varchar [note: 'v5.1 макет: фильтр «Изменяемое поле»'] + ip_address varchar + user_agent varchar [note: 'v5.1 макет: браузер в событиях сеанса'] + Indexes { + (consolidation_version_id, occurred_at) + (object_type, object_id) + (user_id, occurred_at) + } + Note: 'ТЗ 8.2: журнал изменений/аудит. Append-only. Хранение ≥ срока хранения консолидации. Также покрывает: историю правок распознанных данных, факт/состав выгрузок (ЕХ 6.6), импорт справочников, изменения матрицы прав' +} + + + +// ============ ЕХФД (ТЗ BIQ-34649) ============ +// DECISION-2: срез = замороженный указатель на верифицированную версию + список её артефактов. + +// ИСТОЧНИК: +// ТЗ: ЕХ ТЗ 6.2 «запись срезами: одна ГСК на одну отчётную дату, после Верифицирован»; 6.4 «версии среза Актуальная/Архив, неизменяемость»; 5.3 «архивирование в data lake» +// Аналитика: нет (пробел — ANL-032) +// Макет: «Единое хранилище», «Сформированная отчетность», «Верифицирована» +// В модели: v5 новая (DECISION-2) +// Зачем: замороженный указатель на верифицированную версию +Table ex_snapshot { + id uuid [pk] + related_group_id uuid [not null, ref: > related_group.id] + company_group_id uuid [not null, ref: > company_group.id, note: 'денормализация на момент верификации'] + reporting_date date [not null] + year smallint [not null] + quarter period_quarter [not null] + version_no int [not null] + status ex_snapshot_status [not null, note: 'ACTUAL — последняя верифицированная; предыдущие → ARCHIVE'] + source_version_id uuid [not null, unique, note: 'v5.12: id consolidation_version-источника БЕЗ FK — источник удаляется по сроку, срез нет'] + source_version_no int [not null] + superseded_by_snapshot_id uuid [ref: > ex_snapshot.id, note: 'v5.12: для ARCHIVE — ссылка на актуальный срез, который его заместил'] + verified_at timestamptz [not null] + written_at timestamptz [not null] + written_by uuid [ref: > app_user.id, note: 'инициатор записи'] + archived_at timestamptz + data_lake_ref varchar [note: 'ссылка на архив в data lake'] + Indexes { + (related_group_id, year, quarter, version_no) [unique] + (related_group_id, year, quarter, status) + } + Note: 'Срез данных ЕХ: одна ГСК на одну отчётную дату (ЕХ 6.2). Неизменяем и самодостаточен (не зависит от таблиц консолидации). Состав — ex_snapshot_item + ex_snapshot_member' +} + +// ИСТОЧНИК: +// ТЗ: ЕХ ТЗ 6.3 «Периметр на дату: состав ЮЛ/ИП группы на отчётную дату» +// Аналитика: нет +// Макет: дерево «ГК → ГСК → Организации» с ИНН +// В модели: v5 новая +// Зачем: денормализация периметра на дату среза +Table ex_snapshot_member { + ex_snapshot_id uuid [not null, ref: > ex_snapshot.id] + legal_entity_id uuid [not null, ref: > legal_entity.id] + inn varchar [not null, note: 'денормализация на дату среза'] + name varchar [not null] + Indexes { (ex_snapshot_id, legal_entity_id) [pk] } + Note: 'Периметр на дату (ЕХ 6.3)' +} + +// ИСТОЧНИК: +// ТЗ: ЕХ ТЗ 5.2 «Состав хранимых данных» (КФО, первичные, сводная ОСВ, шахматка, гудвилл, корректировки, иные отчёты); 6.7.3/6.7.4 «Сформированная отчётность / Первичные документы», «Просмотр / Выгрузка» +// Аналитика: нет +// Макет: область документов ЕХ, «Скачать», «Связать» документ с организацией +// В модели: v5 новая; v5.13 — document_id вместо stored_file_id +// Зачем: состав среза со ссылками на объекты +Table ex_snapshot_item { + id uuid [pk] + ex_snapshot_id uuid [not null, ref: > ex_snapshot.id] + item_type varchar [not null, note: 'primary_document | summary_osv | vgo_pairs | chess | kfo_balance | kfo_income | goodwill | corrections | other_report'] + legal_entity_id uuid [ref: > legal_entity.id, note: 'для первички — организация'] + document_id uuid [ref: > document.id, note: 'v5.13: только для primary_document — исходники хранятся весь срок, FK допустим; «Скачать» — через document.stored_file → s3_object'] + payload jsonb [note: 'v5.12 DECISION-5: замороженные данные для всех остальных типов; самодостаточно, без ссылок на таблицы консолидации'] + payload_schema_version varchar + Indexes { (ex_snapshot_id, item_type) } + Note: 'Состав среза: primary_document → document; всё остальное → payload. «Просмотр» в ЛК ЕХ рендерит payload по схеме; «Выгрузка» собирает xlsx из payload на лету' +} + +// ============ ПРОЧЕЕ ============ + +// ИСТОЧНИК: +// ТЗ: ТЗ 5.1 (базовый / расширенный пакет ОСВ); 6.2 «набор обязательных ОСВ»; сноска 12 «процесс останавливается, если отсутствует документ» +// Аналитика: md «Загрузка документов» (чек-лист: «ОСВ по обязательным счетам», «прочие документы») +// Макет: «Чек-лист загруженных документов», «Условные обозначения статусов» +// В модели: v5 новая +// Зачем: конфигурация чек-листа по подходу; с v5.13 сверяется с document (тип + счёт + период), а не с файлом +Table required_document_rule { + id uuid [pk] + approach consolidation_approach [not null] + document_type document_type [not null] + account_id uuid [ref: > chart_of_account.id, note: 'для OSV'] + is_mandatory boolean [not null, note: 'обязателен → блокирует переход к консолидации (сноска 12 ТЗ)'] + Indexes { (approach, document_type, account_id) [unique] } + Note: 'ADD ТЗ 5.1/6.2: состав обязательных документов по подходу — основа чек-листа. Выполнено = есть document CONFIRMED с таким типом/счётом за период у каждого ЮЛ периметра' +} diff --git a/model/diagrams/part07_consolidation.png b/model/diagrams/part07_consolidation.png index 3a31cd77a7dcd95a3c394900d1ba2cee083913cd..8cdfe8eb1bd5a569223264b52cabb524c23592c8 100644 GIT binary patch delta 129212 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 z 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

Zz$ltGkM>UW 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�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 delta 128755 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 diff --git a/model/diagrams/part07_consolidation.svg b/model/diagrams/part07_consolidation.svg index f70a66d..a6fcbfc 100644 --- a/model/diagrams/part07_consolidation.svg +++ b/model/diagrams/part07_consolidation.svg @@ -370,7 +370,9 @@ elimination_rules_version     -int +int + +(!) is_in_work     diff --git a/model/diagrams/part09_audit_ex.svg b/model/diagrams/part09_audit_ex.svg index 61100c3..5bc3208 100644 --- a/model/diagrams/part09_audit_ex.svg +++ b/model/diagrams/part09_audit_ex.svg @@ -287,7 +287,7 @@ comment - + diff --git a/model/entities-v5.23.md b/model/entities-v5.23.md new file mode 100644 index 0000000..1e7c31b --- /dev/null +++ b/model/entities-v5.23.md @@ -0,0 +1,246 @@ +# АРМ КА — описание сущностей модели данных v5.23 + +Источник истины по структуре — `data-model-v5.23.dbml` (полный). Диаграммы по частям — `diagrams/` (part01…09 svg/png; перерисовываются `make diagrams` из текущего DBML). Здесь — что каждая таблица значит для бизнеса, как связана с соседями и откуда взялась. + +## Что изменилось в v5.23 (решения владельца 23.10.2026; RSHB/arm-ka-docs#164, AURORA-1536) + +| № | Изменение | Решение | +|---|---|---| +| 1 | `consolidation_version.elimination_rules_version` — `not null` | Версия правил элиминации (`elimination_rule.version_no`), действующая на **дату создания** версии консолидации (OQ-174), фиксируется при создании и дальше не меняется. По ней считаются шахматка по правилу-пресету и пары ВГО (`context/05-domain-rules.md` §4, §5). Вариант «пусто — значит последние открытые правила» отвергнут: после публикации новой версии правил старые консолидации молча пересчитались бы по ней. Версия консолидации без действующих правил не создаётся | + +Остальные таблицы и enum — как в v5.22. Реализация — одна миграция в `arm-core`: существующим версиям проставляется номер +версии правил, действовавшей на дату `created_at` (по Москве; если такой нет — последней открытой), затем `NOT NULL`; откат +снимает только ограничение. + +## Что изменилось в v5.22 (22.10.2026; AURORA-1446) + +Из описания `comment.object_type` убраны устаревшие варианты `chess_cell` и `kfo_result_line`. +Сохранены `document | consolidation_version | …`; сейчас используется привязка к документу. Комментарий к правке пары ВГО хранится +в `correction.comment`, к строкам КФО — в `kfo_result_line.comment` и `client_kfo_line.comment`. +Структура БД не меняется, миграция не требуется. Предыдущие версии модели сохранены. + +## Что изменилось в v5.21 (решение владельца 22.10.2026; RSHB/arm-ka-docs#149, AURORA-1442) + +| № | Изменение | Решение | +|---|---|---| +| 1 | `audit_action` + `FILE_REPROCESS` | Повторная обработка файла пользователем (`context/05-domain-rules.md` §9.5 п. 13) — отдельное событие журнала, раздел `PRIMARY_DOCUMENTS`. Файл не загружается заново: создаётся новое `recognition_job` с `attempt + 1` и становится `current_recognition_job_id`. `FILE_UPLOAD` отвергнут — это приём нового файла, и журнал показал бы вторую загрузку, которой не было; `FILE_REPLACE` — автозамена одного файла другим. Событие пишется на файл (`object_type = stored_file`): `before_value` — прежнее задание (`job_id`, `attempt`, `status`, `error_code`), `after_value` — новое (`job_id`, `attempt`); повторная обработка пакета версии — по событию на каждый отправленный файл, с `consolidation_id` в `after_value` | + +Остальные таблицы и enum — как в v5.20. Реализация — одна миграция в `arm-core`: только добавляет значение enum; откат при +наличии событий `FILE_REPROCESS` останавливается с ошибкой (журнал append-only). + +## Что изменилось в v5.20 (решения владельца 21.10.2026; RSHB/arm-ka-docs#147, OQ-161, AURORA-1442) + +| № | Изменение | Решение | +|---|---|---| +| 1 | `document`: `is_modified` (not null, default `false`), `original_values` (jsonb), `modified_by` (FK → `app_user`), `modified_at` | Аналитик уточняет **период и счёт документа ОСВ**, если они распознаны неверно (`context/05-domain-rules.md` §9.5 п. 12; OQ-161, вариант 2). Новые значения пишутся **на месте** — в `period_year`, `period_quarter`, `is_cumulative`, `osv_account_code` той же строки `document`; при первой правке прежние значения этих четырёх полей копируются в `original_values` и дальше не меняются; `is_modified` — текущие отличаются от исходных. Так же устроена правка сумм `osv_entry` (`original_values`) — первичка не мутируется: файл, JSON результата в S3 и исходные значения остаются как пришли. Копия `document` (второй документ с другим `file_ordinal`) отвергнута: `file_ordinal` — номер документа в `documents[]` результата, а не номер редакции; копия задвоила бы строки ОСВ, подтверждение и привязки. Строки `osv_entry` при смене счёта не меняются (у них свои коды субсчетов) | + +Остальные таблицы и enum — как в v5.19. Реализация — одна миграция в `arm-core`: только добавляет колонки (`is_modified = +false`, остальные `NULL`); откат на данных с `is_modified = true` останавливается с ошибкой (потерялись бы исходные значения). + +## Что изменилось в v5.19 (решения владельца 17.10.2026, Р-1…Р-19; RSHB/arm-ka-docs#116) + +Change `openspec/changes/archive/2026-10-19-unified-statement-normalization`: формы ББ/ОФР нормализуются общим кодом сервисов, контракт +результата v2.0; ядро хранит результат как пришёл (`context/05-domain-rules.md` §11, §9.3, §9.5). + +| № | Изменение | Решение | +|---|---|---| +| 1 | `financial_statement_line`: снята уникальность `(meta_id, line_code)` (индекс остаётся неуникальным); новые `row_index`, `source_ref` (частичный уникальный `(meta_id, source_ref) WHERE source_ref IS NOT NULL`), `line_status` (enum `statement_line_status`: `ok` / `unreadable` / `missing` / `detail`), `line_code_text`, `parent_row_index`, `needs_review`, `is_confirmed` | Повтор кода — законный случай (один код, разные наименования; Р-4): хранятся все строки, чтения «по коду» идут через агрегат формы по коду (сумма строк `ok`, не хранится — DECISION-5). Строки без кода хранятся со статусом (Р-8, отменяет OQ-36 / OQ-141): `detail` — расшифровка под строкой с кодом, в §7, агрегаты, КФО и ЕХ не входит; `unreadable` / `missing` блокируют подтверждение, пока у них есть суммы (Р-13). Порядок и положение в источнике (`row_index`, `source_ref`) нужны экрану, чтобы показать строку и предупреждение у места. **Признак «строка создана правкой аналитика» — `row_index IS NULL`** (прежний признак `line_code_original_value IS NULL` не годится: у строк `unreadable` / `missing` / `detail` источника кода тоже нет); `line_code_original_value` — код из результата как пришёл, правками не меняется | +| 2 | `financial_statement_value`: `source_text`, `needs_review`, `is_confirmed`, `confirmed_by`, `confirmed_at` | `needs_review` **хранится** (пересматривает п. 4 v5.13): его считает сервис («подтверждение проверкой» §7 — Р-5, Р-7), ядро пересчитывает только после правок; подтверждение ячейки без правки аналитиком переживает пересчёт. Сырой текст источника — подсказка ячейки | +| 3 | `financial_statement_column`: `period_kind`, `label_confidence` | Относительные подписи бланка 66н («На отчётную дату», «На 31 декабря предыдущего года») — дата колонки от эффективной даты документа, ядро досчитывает после правки даты отчёта (Р-6); колонка без даты остаётся с `period_kind = none` | +| 4 | `financial_statement_meta`: `form_variant` (enum `statement_form_variant`), `needs_review_fields`, `header_source` (jsonb), `organization_name_original_value`, `organization_name_modified` | Упрощённая форма — свой набор соотношений §7 (`NULL` — документ до v5.19 или результат 1.x, набор полный); поля шапки, требующие проверки (сейчас — неуверенная дата отчёта); сырой текст и уверенность всех полей шапки результата (`<поле>_text`, `<поле>_confidence`) — подсказка у поля на экране; наименование организации правится, как ИНН | +| 5 | Новая таблица `document_issue` + enum `document_issue_kind`, `issue_severity`, `issue_source` | Предупреждения и нарушения §7 документа с уровнем и привязкой к строкам (`line_ids`), колонке (`column_id`, а вне колонок формы — `column_index`), полю шапки; у нарушения — `codes` (коды цели и членов); как пришли от сервиса или посчитаны ядром. Очищается при перезагрузке файла; при пересчёте после правки `relation` / `soft` заменяются целиком, `warning` сервиса сохраняются, кроме снимаемых правкой. **Единственный источник нарушений** для экрана и подтверждения: для результатов 1.x ядро один раз при приёме считает §7 копией `arm_statements` и пишет записи с `source = core`; формы до миграции не пересчитываются (база очищается, Р-24). Ведётся и у документов ОСВ — предупреждения листа `OSV_*` результата 2.0 | +| 6 | `recognition_job.statements_version` | Коммит копии общего кода `arm_statements`, которым посчитан результат (`service.statements_version`); расхождение с копией ядра при пересчёте — `info` | +| 7 | `document`: уникальность `(stored_file_id, document_type, osv_account_code)` — частичная, кроме `BALANCE` / `INCOME`; новая колонка `file_ordinal` + уникальный `(stored_file_id, file_ordinal)` | Вторая форма того же типа в файле хранится (Р-10, Р-15); при двух формах одного типа и периода ни одна не автоподтверждается, подтверждение второй при подтверждённой первой — 409 `DUPLICATE_FORM` (Р-18). ОСВ по счёту, расшифровка и прочий — по-прежнему один на тип на файл (§9.5 п. 2) | +| 8 | `related_group.crm_id` (`varchar`, nullable, unique) | ID ГСК/ГСЗ в ЕЦП CRM из форм `51-03`, `51-04`, `77-02` (AURORA-1619, arm-core#112, OQ-33); вводится вручную, импорт ЕЦП не заполняет (OQ-91); уникален, как `crm_id` ГК и ЮЛ | + +Остальные таблицы и enum — как в v5.18. Реализация — одна миграция в `arm-core`; перед выкладкой база очищается от форм +ББ/ОФР (решение владельца 18.10.2026, Р-24), поэтому миграция только добавляет колонки, таблицу и значения по умолчанию и +§7 по существующим формам не считает. Заполнение (миграция проходит и на непустой базе): `row_index` — `NULL` у строк, +созданных правкой (`line_code_original_value IS NULL`), у остальных — по возрастанию `line_code` в форме; `line_status = +ok`, `needs_review` значений — **НЕ** `values_ok`, `source_text = string_value`, `period_kind` — `absolute` при +`period_date`, иначе `none`, `header_source` — из `*_original_value`, `file_ordinal` — по `(created_at, id)` в файле; +`document_issue` пуст — у форм, оставшихся в неочищенной базе, нарушения до первой правки не показываются. Откат +гарантирован на пустой БД и на данных, которые v5.18 представляет без потери первичных данных и ручного ввода (без +повторов кода, строк без кода, двух форм одного типа в файле, `crm_id` групп и правленого наименования организации); на +таких данных `downgrade` останавливается с ошибкой, а производные колонки v5.19 и `document_issue` удаляет с записью в +журнал миграции. + +## Что изменилось в v5.18 (решения владельца 09.10.2026, RSHB/arm-ka-docs#90) + +| № | Изменение | Решение | +|---|---|---| +| 1 | `stored_file.consolidation_id` (`uuid`, nullable, FK → `consolidation`) + индекс `(legal_entity_id, consolidation_id)` | Файл загружается **в консолидацию** (период ГК) и становится основой её «рабочего стола» (полный состав стола — `context/05-domain-rules.md` §9.5 п. 11), общего для всех версий периода; `NULL` — загрузка без контекста (страница ЮЛ, монозаёмщики, API). Панель «Первичные документы» в версии показывает рабочий стол консоли для ЮЛ плюс файлы с документами, привязанными к версиям консоли. Что использует конкретная версия — по-прежнему `consolidation_document`; заморозка после `VERIFIED` — привязки и `ex_snapshot`. Привязка файла к **версии** (`consolidation_file`) отвергнута: рабочие версии периода делят первичку, а новая версия после `VERIFIED` подхватывает подтверждённое (`openspec/changes/console-files/design.md`) | +| 2 | Note `recognition_job.reply_deadline` | Без изменения структуры: срок ответа OCR — 20 мин (OQ-159) | + +Остальные таблицы и enum — как в v5.17. Реализация — миграция `0006` в `arm-core` (backfill `consolidation_id` по `consolidation_document`). + +## Что изменилось в v5.17 (решение владельца 07.10.2026, пересмотр OQ-31, RSHB/arm-ka-docs#53) + +| № | Изменение | Решение | +|---|---|---| +| 1 | `legal_entity.kpp` и `legal_entity_history.kpp` (`varchar`, nullable) | КПП юридического лица нужен (макет: колонка «КПП» на экранах `50`, `61`, поле форм `51-02`, `79`; фронтенд: «в ручке получения ЮЛ не приходит КПП»). Формат — 9 символов: 4 цифры, 2 символа (цифра или латинская A–Z), 3 цифры, иначе `INVALID_KPP`. У ИП (`entity_type = ИП`) КПП запрещён. Для ЮЛ необязателен: существующие записи и импорт без колонки остаются валидными. Уникален по-прежнему только `inn` (КПП — атрибут; сопоставление контрагентов ОСВ по ИНН не меняется). Изменение КПП — обычная правка со снимком в `legal_entity_history`. Отменяет п. 2 v5.14 («КПП не вводится») | + +Остальные таблицы и enum — как в v5.16. Реализация — миграция `0005` в `arm-core`. + +## Что изменилось в v5.16 (Срез 4, решения владельца 06.10.2026) + +| № | Изменение | Решение | +|---|---|---| +| 1 | Enum `counterparty_match_kind` (`INN`, `NAME`, `ALIAS`, `MANUAL`, `PROPAGATED`) и колонка `osv_entry.counterparty_match_kind` (nullable) | Способ сопоставления контрагента строки ОСВ хранится. `NULL` ⇔ `counterparty_id` `NULL`; `INN` / `NAME` / `ALIAS` — шаг автоматического резолва при маппинге (ИНН; точное имя; нормализованное имя ЮЛ или алиас); `MANUAL` — ручное сопоставление аналитиком; `PROPAGATED` — автоприменение по имени в версии (DOC-221278 п. 12–13). Вычислять на чтение нельзя: после ручного связывания появляется алиас, и ручное сопоставление неотличимо от `ALIAS`. Миграция `0004` заполняет колонку по уже смапленным строкам (ИНН без пробелов = `legal_entity.inn` → `INN`; `trim(name) = legal_entity.name` → `NAME`; остальные с `counterparty_id` → `ALIAS` — приближение: ручных сопоставлений до Среза 4 не было) | +| 2 | Семантика `consolidation_document` | Без изменения структуры: строка создаётся при подтверждении документа (по документам ЮЛ — членов периметра версий «в работе») и при добавлении ЮЛ в периметр (подтверждённые подходящие документы подхватываются); удаляется при замене/удалении файла и исключении ЮЛ из периметра. Для одной (ЮЛ, `document_type`, `osv_account_code`, период, признак нарастающего) привязан один документ — самый поздний `confirmed_at` (D-5 Среза 4) | +| 3 | Семантика `consolidation_lock` | Без изменения структуры: блокировка без истечения по времени — активна, пока её не снял владелец, администратор или не перехватил другой пользователь с `CONSOLIDATION_EDIT` по причине (OQ-119) | + +Пробелы квартальной склейки и сама сводная ОСВ по-прежнему не хранятся (DECISION-5). Остальные таблицы и enum — как в v5.15 (43 таблицы; enum — 28). Реализация — миграция `0004` в `arm-core`. + +## Что изменилось в v5.15 (Срез 2c, решения владельца 05.10.2026) + +| № | Изменение | Решение | +|---|---|---| +| 1 | `osv_data_type` + `NU` (после `BU`) | Строки налогового учёта из ОСВ «БУ, НУ» хранятся в `osv_entry` как есть (OQ-45); контракт результата допускал `NU` с v1.0, ядро раньше такой строки принять не могло | +| 2 | `app_user.email` — в нижнем регистре | Без изменения структуры: нормализация при записи (seed, администрирование), поиск по `lower(email)` сохраняется, уникальность — существующий UNIQUE по `email` (OQ-59). Expression-индекс `lower(email)` не вводится: сверка ORM↔DBML не умеет expression-индексы. Миграция `0003` приводит существующие email к нижнему регистру (при дублях по регистру — падает, слияние решает человек) | +| 3 | Семантика `stored_file.status`, `recognition_job.group_schema` | Без изменения структуры: `PROCESSING` ставит inbox по ack сервиса, `PROCESSED`/`ERROR` — цикл маппинга результата (OQ-67); маппинг выполняется отдельно от inbox (OQ-69); `group_schema` заполняет маппер; «Итого» в `osv_entry` не хранится (OQ-01) | +| 4 | Индексы `osv_entry (parent_entry_id)`, `osv_entry (recognition_job_id)`, `stored_file (current_recognition_job_id)` | Индексы для удаления файла и обхода дерева строк: без них проверки FK (в том числе self-FK `parent_entry_id`) при `DELETE /files/{id}` и очистке файла перед повторным маппингом шли seq scan'ом. Замер: DELETE документа 1000 строк 8,6 с → 16 мс на 200 тыс. строк. Обычные (не unique) индексы; закрывает OQ-117 (I-1 финального ревью Среза 2c) | + +Остальные таблицы и enum — как в v5.14 (43 таблицы, 27 enum). Реализация — миграция `0003` в `arm-core`. + +## Что изменилось в v5.14 (Срез 1, решения владельца 04.10.2026) + +| № | Изменение | Решение | +|---|---|---| +| 1 | `related_group_member.kind` + индекс `(legal_entity_id, kind) WHERE is_current` | ЮЛ состоит **одновременно в одной ГСК и одной ГСЗ** (но только в одной группе каждого вида). Отменяет ANL-030 / v5.8 («только в одной ГСК или ГСЗ»). `kind` — денормализация `related_group.kind` (равенство проверяет ядро при записи, тест на рассинхрон); индекс не выразить через join, триггер не выбран. Закрывает OQ-32 | +| 2 | КПП | **Не вводится** *(отменено в v5.17: КПП введён)*. Поле есть только в макете; у `legal_entity` его нет, импорт его не читает (закрывал OQ-31 до v5.17) | +| 3 | Семантика `company_group.crm_id`, `base_regional_office_id` | Без изменения структуры: `crm_id` = «iD ГК» выгрузки ЕЦП CRM, `base_regional_office_id` = «Базовый РФ ГК в CRM»; флаги «входит в ГСК/ГСЗ» выгрузки → членство в одной неявной ГСК/ГСЗ на ГК (правила — `05-domain-rules.md` §13) | +| 4 | `audit_action` + `LEGAL_ENTITY_CHANGE`, `USER_CHANGE` | Журнал изменений ЮЛ (создание/изменение/закрытие/перевод, алиасы) и пользователей (создание/деактивация администратором) — ТЗ 8.2; в v5.13 для них не было действия (были `GROUP_CHANGE`, `MEMBERSHIP_CHANGE`, `USER_ROLE_CHANGE`) | + +Остальные таблицы и enum — как в v5.13 (43 таблицы). Реализация — миграция `0002` в `arm-core`. + +## Что изменилось в v5.13 (ревью 30.09–01.10) + +| № | Замечание | Решение | +|---|---|---| +| 1 | Вместо RBAC «в коде» — роли **и** права | `permission` + `role_permission` возвращены; права только через роли, прямых назначений пользователю нет. Исключения — заведением роли | +| 2 | `osv_entry.parent_entry_id` не нужен — храним только строки с контрагентами | **Отложено.** Открыт вопрос: хранить ли строки уровня ACCOUNT для сверки «Σ контрагентов = итог счёта»; аналитика «Парсинг ОСВ» п.11 пока говорит «все строки» | +| 3 | `osv_group_schema` не особо нужна | Убрана. Схема шапки — `recognition_job.group_schema jsonb`; тип строки — `osv_entry.group_type` | +| 4 | `financial_statement_value.needs_review` непонятен | Убран: производное от `confidence` / `is_recognized`, порог может меняться | +| 5 | В `recognition_job` не нужны и `result`, и `raw_result` | Оставлен только `result_s3_object_id`. Сырой ответ ИС Сканирование — S3 `raw/{job_id}.json` по конвенции, в БД не регистрируется | +| 6 | `stored_file.fields_modified` — что это | Счётчик «исправлено полей» с карточки документа (v5.7). Убран — `COUNT(is_modified)` по данным | +| 6-бис | `document_type` не предусматривает несколько ОСВ или ББ+ОФР в одном файле | **Разделение файл / документ**: `stored_file` — физический файл, `document` — логическая единица (1:N). Чек-лист, проверки, подтверждение, FK разобранных данных, `consolidation_document`, `ex_snapshot_item` — на `document`. Замена (`superseded_by`) — файл целиком | +| 7 | `file_type`: убрать Р7 | Убран. `xls/xlsx/xlsb → tabular-parser`, `pdf/png/jpg → scan-gateway` | + +**Принципы модели (коротко):** +- Первичка не редактируется: файлы и распознанные значения хранятся как пришли; правки аналитика — рядом (`is_modified`, `original_*`) и в аудите. +- Производные консолидации в работе (сводная ОСВ, пары ВГО, шахматка) **не хранятся** — считаются запросом. Хранятся только ручные решения (корректировки, гудвилл, подтверждение КФО клиента). +- При верификации всё замораживается в Единое хранилище (ЕХ) как самодостаточный срез, который не зависит от таблиц консолидации. +- Единственный писатель в БД — ядро `arm-core`; сервисы распознавания видят только NATS и S3. +- Права — данные (`role_permission`), ограничения по ЗО/филиалу/статусу — policy-слой поверх прав. + +--- + +## Часть 01 — Группы компаний, организации, филиалы + +| Сущность | Что это | Ключевые связи | Откуда | +|---|---|---|---| +| `regional_office` | Филиал банка: головной офис (ГО, `is_head_office`) и региональные филиалы (РФ). Определяет зону видимости пользователя и закрепление ГК. | ← `company_group.base_regional_office_id`, `legal_entity.regional_office_id`, `app_user.regional_office_id` | ТЗ 8.1 | +| `company_group` | Группа компаний (ГК) — верхний уровень справочника клиентов. Текущее состояние (SCD4). `crm_id` = «iD ГК» из ЕЦП CRM (NULL, если создана вручную Куратором; v5.14 — семантика по выгрузке), внутренний `code`, закрепление за филиалом (`base_regional_office_id` = «Базовый РФ ГК в CRM»), флаг архива. | → `regional_office`; ← `legal_entity`, `related_group`, `consolidation` | ТЗ 6.1, Прил. 2; макет | +| `company_group_history` | Прошлые снимки ГК: каждое изменение — новая строка с `valid_from/valid_to`. | → `company_group` | ТЗ 6.10, 8.2 | +| `legal_entity` | Юридическое лицо / ИП. Натуральный ключ — ИНН; **v5.17:** `kpp` — КПП (9 символов, nullable, только у ЮЛ, не ключ). `company_group_id` = текущая ГК; **NULL = монозаёмщик**. `close_date` — закрыто/архивировано. | → `company_group`, `regional_office`; ← `related_group_member`, `stored_file`, `document`, `osv_entry.counterparty_id`, `consolidation_member` | ТЗ 6.1, Прил. 2; ЕХ 6.1 | +| `legal_entity_history` | Прошлые снимки ЮЛ + вид события (создание, изменение, переход в другую ГК, закрытие, вывод из ГК) и дата вступления в силу. | → `legal_entity` | ТЗ 8.2; макет | +| `legal_entity_alias` | Словарь написаний контрагента: как имя встречается в ОСВ и нормализованный ключ для матчинга. Пополняется при ручном сопоставлении. | → `legal_entity` | ТЗ 6.5 | +| `related_group` | ГСК или ГСЗ внутри ГК; `kind` различает. Для ГСК формируется КФО. Иерархия не поддерживается. **v5.19:** `crm_id` — ID группы в ЕЦП CRM (вручную, уникален). | → `company_group`; ← `related_group_member`, `consolidation.related_group_id` | ТЗ 6.1, Прил. 2 | +| `related_group_member` | Состав ГСК/ГСЗ — история членства (SCD2). **v5.14:** ЮЛ может одновременно входить в **одну ГСК и одну ГСЗ** (не более одной группы каждого вида): колонка `kind` = `related_group.kind` (денормализация) и частичный уникальный индекс `(legal_entity_id, kind) WHERE is_current`. Решение владельца 04.10.2026, отменяет ANL-030. | → `related_group`, `legal_entity` | ТЗ 6.1; макет [79] | + +## Часть 02 — Пользователи, роли, права + +| Сущность | Что это | Ключевые связи | Откуда | +|---|---|---|---| +| `app_user` | Пользователь АРМ. Аутентификация внешняя (РАИСА/SSO, `external_id`). Филиал (ГО/РФ), зона ответственности (ДКБ/ДМСБ/ДМ), табельный номер. Видимость данных = права роли + филиал + ЗО. | → `regional_office`; ← `user_role`, все `*_by` поля | ТЗ 8.1, Прил. 2 | +| `role` | Роли: seed из ТЗ 8.1 (КА РФ, КА ГО, РКА, КМ, Куратор ГО, Эксперт, Администратор; `is_system`) + роли, заведённые администратором для исключений. **v5.13:** код роли в бизнес-логике не проверяется — только права. | ← `user_role`, `role_permission` | ТЗ 8.1 | +| `permission` | **v5.13.** Атомарное право «объект × действие»: `DIRECTORY/DOCUMENT/CONSOLIDATION/KFO/EX/EXPORT/USERS/AUDIT` × `VIEW/EDIT/APPROVE/VERIFY/DELETE/EXPORT/ADMIN`. Seed, привязан к коду — администратор новые коды не создаёт. Право говорит «может»; policy-слой (ЗО, филиал, статус КФО) — «эту ли и сейчас ли». | ← `role_permission` | ТЗ Прил. 2, сноска 29 | +| `role_permission` | **v5.13.** Матрица доступов как данные: `effective_permissions(user) = ∪ permissions(roles(user))`. Редактируется администратором на экране «Изменение ролей и прав доступа»; история — `audit_event(ROLE_PERMISSION_CHANGE)`. Прямых прав у пользователя нет. | → `role`, `permission` | ТЗ Прил. 2; макет | +| `user_role` | Назначение ролей пользователю (M:N). История — в аудите. | → `app_user`, `role` | ТЗ 8.1 | + +## Часть 03 — Бухгалтерские справочники и правила + +| Сущность | Что это | Ключевые связи | Откуда | +|---|---|---|---| +| `chart_of_account` | План счетов с иерархией, тип A/P/AP, признак забалансового. Seed — полный план 1С; нестандартные субсчета клиентов добавляет администратор. | ← `osv_entry.account_id`, `elimination_rule_account`, `required_document_rule` | ТЗ 6.2/6.5, Прил. 3/4 | +| `elimination_rule` | Правило элиминации из Прил. 3 (ББ) / Прил. 4 (ОФР) как данные: пара статей, сторона, мера, режим, НДС, акцизы. Версионируется. | ← `elimination_rule_account`, `correction.rule_id`; версия фиксируется в `consolidation_version` | ТЗ 6.4, Прил. 3/4 | +| `elimination_rule_account` | Счета/субсчета каждой стороны правила, включая исключения («76 кроме 76.7.1»). | → `elimination_rule`, `chart_of_account` | ТЗ Прил. 3/4 | +| `required_document_rule` | Какие документы обязательны по подходу. **v5.13:** сверяется с `document` (тип + счёт + период), а не с файлом: выполнено = есть `document CONFIRMED` у каждого ЮЛ периметра. | → `chart_of_account` | ТЗ 5.1, 6.2, сноска 12 | + +## Часть 04 — Файлы, документы, S3, задания распознавания + +| Сущность | Что это | Ключевые связи | Откуда | +|---|---|---|---| +| `s3_object` | Реестр всех объектов в S3: бакет-роль, ключ, размер, sha256, срок жизни, ссылка на архив в data lake. Единая точка ретеншна (5 лет по ТЗ 8.4) и дедупа. | ← `stored_file`, `recognition_job` | ТЗ 6.2, 8.4; ЕХ 8.3 | +| `stored_file` | **v5.13: только физический файл** одной загрузки: чей (ЮЛ), формат, hash, кто/когда загрузил, статус обработки (`UPLOADED → PROCESSING → PROCESSED / ERROR / SUPERSEDED`), версия при замене. **v5.18:** `consolidation_id` — консолидация, в контексте которой файл загружен (основа «рабочего стола консоли», общего для версий периода; полный состав — `context/05-domain-rules.md` §9.5 п. 11; `NULL` — без контекста). Что внутри файла — `document`. Замена — файл целиком со всеми документами. | → `legal_entity`, `consolidation`, `s3_object`, `recognition_job`; ← `document`, `recognition_job` | ТЗ 6.2, 8.2; UC-01…05 | +| `document` | **v5.13, новая.** Логический документ внутри файла: ББ, ОФР, ОСВ по счёту (`osv_account_code`), расшифровка, прочее. Период, отчётная дата, где в файле (`locator`: лист / страницы), статус проверки (`RECOGNIZED / NEEDS_CHECK / CONFIRMED / ERROR`), результаты проверок периода и контрагента, кто подтвердил. Один файл → N документов (PDF с ББ+ОФР; xlsx с несколькими ОСВ). Создаёт ядро при маппинге результата `recognition_job`. На документ ссылаются разобранные данные, чек-лист, консолидация и ЕХ. **v5.19:** `file_ordinal` — индекс документа в `documents[]` результата (у всех документов); формы ББ/ОФР одного типа в файле могут повторяться (ОСВ по счёту, расшифровка, прочий — один на тип); предупреждения и нарушения — `document_issue`. **v5.20:** период и счёт ОСВ уточняются аналитиком на месте, распознанные — в `original_values` (`is_modified`, `modified_by/at`). | → `stored_file`, `legal_entity`, `app_user`; ← `osv_entry`, `financial_statement_meta`, `document_issue`, `consolidation_document`, `ex_snapshot_item` | ТЗ 6.2, 5.1, 8.2; макет (чек-лист, «Подтвердить данные») | +| `recognition_job` | Одна попытка распознать/распарсить файл. **Единственная точка обмена с NATS** (outbox/inbox, дедуп по `result_msg_id`, DLQ). Хранит сервис и версию, **одну** ссылку на нормализованный JSON-результат в S3 (v5.13), метрики, и **схему группировок шапки ОСВ по листам** (`group_schema jsonb`, v5.13 — вместо `osv_group_schema`). **v5.19:** `statements_version` — версия копии общего кода нормализации, которой посчитан результат форм. | → `stored_file`, `s3_object`; ← `osv_entry`, `financial_statement_meta` | ТЗ 6.2, 6.10; DECISION-4 | + +## Часть 05 — Разобранные ОСВ + +| Сущность | Что это | Ключевые связи | Откуда | +|---|---|---|---| +| `osv_entry` | Строка ОСВ: документ (счёт + период), владелец, тип строки по схеме шапки (`group_type`, v5.13), уровень и родитель (`parent_entry_id` — **открыт вопрос, замечание 2**), код счёта и резолв в план счетов, сырое имя/ИНН контрагента, резолв в ЮЛ и способ сопоставления (`counterparty_match_kind`, v5.16), шесть сумм, тип данных (БУ/валюта/кол-во), «подакцизный» для 90-го. Ручные правки: `is_modified`, `original_values`, `modified_by`. Признак ГСК/ГК/Внешний не хранится — выводится из периметра версии; способ сопоставления контрагента хранится (`NULL` ⇔ контрагент не сопоставлен). | → `document`, `recognition_job`, `legal_entity` ×2, `chart_of_account` | ТЗ 6.2/6.5, Прил. 2; «Парсинг ОСВ» | + +## Часть 06 — Распознанные формы ББ/ОФР + +| Сущность | Что это | Ключевые связи | Откуда | +|---|---|---|---| +| `financial_statement_meta` | Шапка распознанной формы (1:1 с `document` BALANCE/INCOME): ИНН и наименование как в документе, отчётная дата, единица измерения, реквизиты. Ревью формы (`reviewed_by/at`) и акцепт КА непройденных логических проверок с комментарием. Подтверждение документа — `document.confirmed_by`. **v5.19:** `form_variant` (полная / упрощённая — набор соотношений §7), `needs_review_fields`, `header_source` (сырой текст и уверенность полей шапки), правка наименования (`organization_name_original_value`, `organization_name_modified`); результат проверок §7 и предупреждения хранятся в `document_issue` как пришли от сервиса, ядро пересчитывает их только после правок. | → `document`, `recognition_job`, `app_user`; ← `column`, `line` | ТЗ 6.2/6.3; FNR01; макет | +| `financial_statement_column` | Колонки-периоды формы с датой — нужны для межформенной проверки (1370 на начало года) и гудвилла. **v5.19:** `period_kind` (абсолютная / относительная подпись бланка / без даты), `label_confidence`. | → `meta`; ← `value` | ТЗ 6.3 п.7, 6.7 | +| `financial_statement_line` | Строка формы как в источнике: код (или его сырой текст) и наименование как распознано. **v5.19:** все строки источника — с кодом (`ok`, повторы кода тоже) и без (`unreadable`, `missing`, `detail` — расшифровка под родителем `parent_row_index`); порядок `row_index` (`NULL` ⇔ строка создана правкой аналитика), положение `source_ref`, `needs_review` неуверенного кода, подтверждение кода `is_confirmed`. Раскладка экрана — по коду «как на бумаге». | → `meta`; ← `value`, `document_issue.line_ids` | ТЗ 6.2, Прил. 2 | +| `financial_statement_value` | Число в ячейке (строка × колонка): сумма, уверенность, `is_recognized`, ручная правка с исходным значением. **v5.19:** подсветка — только `needs_review` (хранится: уверенность, `is_recognized` и §7 сведены сервисом, ядро пересчитывает после правок); `source_text` — сырой текст источника; `is_confirmed` / `confirmed_by/at` — подтверждено без правки. (v5.13 этот флаг убирала как производный.) | → `line`, `column`, `app_user` | ТЗ 6.2, Прил. 2 | +| `document_issue` | **v5.19, новая.** Предупреждение или нарушение §7 документа (у формы; у ОСВ — предупреждения листа): вид (`warning` / `relation` / `soft`), код и уровень (`error` / `info`), сообщение, привязка к строкам (`line_ids`), колонке (`column_id` или `column_index`) и полю шапки, источник (`service` / `core`); для нарушения — соотношение, `codes`, `expected`, `actual`. Экран показывает их у места. | → `document`, `financial_statement_column` | change `unified-statement-normalization` (design, шаг 8) | + +## Часть 07 — Консолидация + +| Сущность | Что это | Ключевые связи | Откуда | +|---|---|---|---| +| `consolidation` | Логическая консолидация: **ГК** + отчётный период. ГСК фиксируется/создаётся при верификации по фактическому периметру. Уникальна по (ГК, год, квартал). **v5.18:** файлы, загруженные в консолидацию, — `stored_file.consolidation_id` (основа рабочего стола, общего для версий периода; полный состав — `context/05-domain-rules.md` §9.5 п. 11). | → `company_group`, `related_group`; ← `consolidation_version`, `stored_file` | ТЗ 6.10, 7.2 | +| `consolidation_version` | Версия консолидации: номер, статус, сценарий, подход, гудвилл, инициатор и его офис (маршрут), кто утвердил / верифицировал, решение УОБ, отклонения от Методики, версия правил элиминации, ссылка на предыдущую. После VERIFIED — read-only. | → `consolidation`, `app_user`, `regional_office`, self; ← всё в частях 07–08 | ТЗ 5.1, 6.4, 6.10; макет | +| `consolidation_status_history` | Каждый переход статуса: из → в, кто, когда, комментарий (обязателен при возврате). | → `consolidation_version`, `app_user` | ТЗ 6.10, 8.2 | +| `consolidation_lock` | «Взять в работу»: кто редактирует версию, перехват с причиной (v5.16: без истечения по времени, OQ-119). Из макета — ANL-036. | → `consolidation_version`, `app_user` | макет | +| `consolidation_member` | Периметр версии — зафиксированный список ЮЛ; `is_head_entity` для гудвилла. | → `consolidation_version`, `legal_entity` | ТЗ 6.1, 6.10 | +| `consolidation_document` | **v5.13:** какие **документы** (не файлы) участвуют в версии. Чек-лист = `required_document_rule` × периметр − `consolidation_document`. Переиспользование одного документа в нескольких версиях/периодах, монозаёмщики из ЕХ. | → `consolidation_version`, `document` | ТЗ Прил. 2; ЕХ 7 | + +*Не хранятся (DECISION-5), считаются запросом по версии:* сводная ОСВ, признак контрагента ГСК/ГК/Внешний, пары ВГО, шахматка, результирующая таблица ВГО. + +## Часть 08 — Корректировки, гудвилл, результат КФО + +| Сущность | Что это | Ключевые связи | Откуда | +|---|---|---|---| +| `correction` | Ручная корректировка ВГО: пара (правило + компания 1 + компания 2 — естественный ключ), ББ/ОФР, строки и суммы по Дт и Кт, дочерние строки для распределения, причина, обязательный комментарий, статус, номер версии (история — в аудите). КФО = свод − Σ корректировок. | → `consolidation_version`, `elimination_rule`, `legal_entity` ×2, `chart_of_account` ×2, self | ТЗ 6.4, 6.8, Прил. 9 | +| `goodwill` | Строка расчёта гудвилла: головная × дочерняя, доля владения, ФВ по 58.01, УК (1310) и добавочный капитал (1350 — вопрос методологам), гудвилл, «включить в КФО», комментарий. | → `consolidation_version`, `legal_entity` ×2, `app_user` | ТЗ 6.7, Прил. 3 п.2, Прил. 8 | +| `kfo_result` | Шапка результата КФО: когда посчитан, заморожен ли, ЧА и ВБ, выручка, прибыль, расхождения, пороги, обоснование, итог гудвилла. | → `consolidation_version` (1:1); ← `kfo_result_line` | ТЗ 6.4, 6.8, Прил. 10 | +| `kfo_result_line` | Строка консолидированного ББ/ОФР по коду ФСБУ 4/2023: сумма → авто-элиминация → корректировки → гудвилл → итог; «в т.ч. ВГО», источник, расхождение, комментарий. | → `kfo_result`; ← `kfo_result_line_company` | ТЗ 6.4, Прил. 10; макет | +| `kfo_result_line_company` | Разрез строки КФО по компаниям периметра: сумма и доля. | → `kfo_result_line`, `legal_entity` | ЕХ 6.6; макет | +| `client_kfo_line` | Сценарий «подтверждение КФО клиента»: по строке — значение и ВГО от клиента (ручной ввод), значение и ВГО банка, расхождение, причина. | → `consolidation_version`, `app_user` | ТЗ 5.1, 6.10; макет | + +## Часть 09 — Комментарии, аудит, Единое хранилище + +| Сущность | Что это | Ключевые связи | Откуда | +|---|---|---|---| +| `comment` | Полиморфный комментарий к объекту (`document | consolidation_version | …`); сейчас используется для документов. Правка и удаление не предусмотрены; аудит не ведётся. | → `app_user`; `object_type + object_id` без FK | ТЗ 6.3; AURORA-1446; макет | +| `audit_event` | Журнал действий (append-only): кто, когда, действие, раздел, объект, версия консолидации, before/after, результат, IP/браузер. Покрывает историю правок распознанных данных, корректировок, выгрузок, импорта справочников, входов, **изменений матрицы прав** (v5.13), подтверждения документов, **изменений ЮЛ и пользователей** (v5.14: `LEGAL_ENTITY_CHANGE`, `USER_CHANGE`). | → `app_user`, `consolidation_version` | ТЗ 8.2, Прил. 2; макет | +| `ex_snapshot` | Срез ЕХ: одна ГСК на одну отчётную дату, версия, статус (актуальный/архив), когда и кем верифицирован и записан. Самодостаточен — на консолидацию ссылается только данными. | → `related_group`, `company_group`, `app_user`, self; ← `member`, `item` | ЕХ ТЗ 6.2, 6.4, 5.3 | +| `ex_snapshot_member` | Периметр среза на дату: ЮЛ с ИНН и наименованием на момент верификации. | → `ex_snapshot`, `legal_entity` | ЕХ ТЗ 6.3 | +| `ex_snapshot_item` | Содержимое среза. Два вида: исходный документ → ссылка на **`document`** (v5.13; скачать — через его файл) и всё производное → `payload` jsonb. | → `ex_snapshot`, `document`, `legal_entity` | ЕХ ТЗ 5.2, 6.7 | + +--- + +## Как читать модель по сценарию «сформировать КФО» + +1. **Справочники** (01–03): ГК → ЮЛ → ГСК/ГСЗ; план счетов; правила элиминации; что обязательно загрузить. +2. **Создание консолидации** (07): `consolidation` от ГК + период → `consolidation_version` → `consolidation_member` (периметр). +3. **Загрузка** (04): `stored_file` + `s3_object` → `recognition_job` (queued → NATS → сервис → результат в S3 → done) → ядро создаёт **`document`** на каждый ББ / ОФР / ОСВ по счёту, найденный в файле. +4. **Разбор** (05–06): ОСВ → `osv_entry`; ББ/ОФР → `financial_statement_meta/column/line/value`. Аналитик проверяет, правит, подтверждает **документ**; логические проверки — на лету; сопоставляет контрагентов (→ `osv_entry.counterparty_id`, `legal_entity_alias`). Чек-лист закрывается по `document CONFIRMED`. +5. **Консолидация** (вычисляется): сводная ОСВ, пары ВГО, шахматка — из `osv_entry` × периметр × правила. Аналитик вносит `correction`, заполняет `goodwill`, при сценарии подтверждения — `client_kfo_line`. Результат — `kfo_result(_line)`. +6. **Согласование** (07): `consolidation_status_history` по маршруту; блокировка `consolidation_lock`. Что можно — решает `role_permission` + policy-слой по статусу/ЗО. +7. **Верификация → ЕХ** (09): `ex_snapshot` + `member` + `item` (документы по ссылке, остальное — payload). Версия → read-only. Всё это время — `audit_event`. + +## Открытые вопросы после v5.14 + +- **Замечание 2** (`osv_entry.parent_entry_id`, какие строки ОСВ хранить) — отложено; затрагивает и аналитику «Парсинг ОСВ» п.11. +- Замена по-документно (одна ОСВ из файла с пятью) — сейчас не предусмотрена, замена файлом целиком. Если понадобится — `superseded_by` переезжает в `document`. +- Статус `document.RECOGNIZED` (ручная проверка не требуется по порогу) — подтвердить с аналитиками, нужен ли, или все документы проходят через `NEEDS_CHECK → CONFIRMED`. diff --git a/openspec/config.yaml b/openspec/config.yaml index 25a16f0..46b2381 100644 --- a/openspec/config.yaml +++ b/openspec/config.yaml @@ -1,12 +1,12 @@ schema: spec-driven context: | - Репозиторий arm-ka-docs — контекст, модель данных (DBML v5.22), правила домена, контракты между сервисами + Репозиторий arm-ka-docs — контекст, модель данных (DBML v5.23), правила домена, контракты между сервисами (docs/contracts/*.schema.json), макет UI и экспорт ТЗ системы АРМ КА (ДКБ, Россельхозбанк). Здесь оформляются СКВОЗНЫЕ изменения: контракт + окружение разработки (docs/dev) + проверки качества (make check) + изменения документов контекста. Код сервисов живёт в соседних репозиториях (../arm-core, ../tabular-parser, ../scan-gateway), у каждого свой openspec/ и свой change; сквозной change ссылается на них. - Источники истины по приоритету: docs/model/data-model-v5.22.dbml → docs/model/entities-v5.22.md → + Источники истины по приоритету: docs/model/data-model-v5.23.dbml → docs/model/entities-v5.23.md → docs/context/05-domain-rules.md → docs/source/tz (черновик, имена v4). Открытые вопросы — docs/context/07-open-questions.md; план срезов — docs/context/09-delivery-plan.md; соглашения шаблона команды — docs/context/03-architecture.md. Язык документов и коммитов — русский, идентификаторы — английские, как в DBML. docs/source/** не редактируется. diff --git a/repo-templates/arm-core.CLAUDE.md b/repo-templates/arm-core.CLAUDE.md index bdf2db2..492c744 100644 --- a/repo-templates/arm-core.CLAUDE.md +++ b/repo-templates/arm-core.CLAUDE.md @@ -16,7 +16,7 @@ - NATS subjects и схема ключей S3 — `../docs/context/03-architecture.md`. ## Правила репозитория -- ORM 1:1 с `../docs/model/data-model-v5.22.dbml`; `scripts/check_dbml_vs_orm.py` — обязательная проверка CI. +- ORM 1:1 с `../docs/model/data-model-v5.23.dbml`; `scripts/check_dbml_vs_orm.py` — обязательная проверка CI. - Алгоритмы — только из `../docs/context/05-domain-rules.md`; номер § — в docstring. - Вычисляемые объекты консолидации — `backend/app/domain/`, без ORM-таблиц. - Фронт: пользователь слаб во фронте — для TS/React изменений делай ревью сам и объясняй решения в PR.