kfo-table-back: vgo_assignment.side и kfo_result.snapshot #228
2
Makefile
@ -7,7 +7,7 @@ PY := $(if $(wildcard $(VENV)/bin/python),$(CURDIR)/$(VENV)/bin/python,python3)
|
|||||||
CHANGE ?=
|
CHANGE ?=
|
||||||
# Текущая версия модели данных — по ней рисуются диаграммы (make diagrams)
|
# Текущая версия модели данных — по ней рисуются диаграммы (make diagrams)
|
||||||
|
|
||||||
DBML ?= model/data-model-v5.26.dbml
|
DBML ?= model/data-model-v5.27.dbml
|
||||||
# Checkout библиотеки arm_statements (RSHB/pylib_ai_arm_statements) рядом с docs — для statements-orders-check
|
# Checkout библиотеки arm_statements (RSHB/pylib_ai_arm_statements) рядом с docs — для statements-orders-check
|
||||||
STATEMENTS_DIR ?= ../pylib_ai_arm_statements
|
STATEMENTS_DIR ?= ../pylib_ai_arm_statements
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
# Элиминация ВГО: правила, расчёт, корректировки
|
# Элиминация ВГО: правила, расчёт, корректировки
|
||||||
|
|
||||||
Документ для аналитика, 19.10.2026 (RSHB/arm-ka-docs#132; сопоставление — по решениям OQ-07 и OQ-173, #136). Основа — модель данных
|
Документ для аналитика, 19.10.2026 (RSHB/arm-ka-docs#132; сопоставление — по решениям OQ-07 и OQ-173, #136). Основа — модель данных
|
||||||
[`model/data-model-v5.26.dbml`](../model/data-model-v5.26.dbml) и правила предметной области
|
[`model/data-model-v5.27.dbml`](../model/data-model-v5.27.dbml) и правила предметной области
|
||||||
[`context/05-domain-rules.md`](../context/05-domain-rules.md) §3–§6, §8. Источник истины — они: при расхождении прав
|
[`context/05-domain-rules.md`](../context/05-domain-rules.md) §3–§6, §8. Источник истины — они: при расхождении прав
|
||||||
DBML и `05-domain-rules.md`, а этот документ поправь следом. Где написано наше прочтение ТЗ, а не прямая цитата, это
|
DBML и `05-domain-rules.md`, а этот документ поправь следом. Где написано наше прочтение ТЗ, а не прямая цитата, это
|
||||||
помечено; такие места собраны в раздел 6 вопросами.
|
помечено; такие места собраны в раздел 6 вопросами.
|
||||||
|
|||||||
@ -76,7 +76,7 @@ git remote add origin <url-arm-core> && git push -u origin main
|
|||||||
|
|
||||||
| Слой | Где | Статус | Правило для агента |
|
| Слой | Где | Статус | Правило для агента |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| Модель данных | `docs/model/data-model-v5.26.dbml` | стабильный, версионируется | единственный источник имён и структур |
|
| Модель данных | `docs/model/data-model-v5.27.dbml` | стабильный, версионируется | единственный источник имён и структур |
|
||||||
| Правила домена | `docs/context/05-domain-rules.md` | курируемый — пишет человек/агент по итогам ревью | **единственный вход алгоритмов в код**; из ТЗ напрямую не кодируем |
|
| Правила домена | `docs/context/05-domain-rules.md` | курируемый — пишет человек/агент по итогам ревью | **единственный вход алгоритмов в код**; из ТЗ напрямую не кодируем |
|
||||||
| Открытые вопросы | `docs/context/07-open-questions.md` | живой реестр | каждое допущение в коде — `ASSUMPTION(OQ-nn)` |
|
| Открытые вопросы | `docs/context/07-open-questions.md` | живой реестр | каждое допущение в коде — `ASSUMPTION(OQ-nn)` |
|
||||||
| Экспорт ТЗ | `docs/source/tz/` | снимок на дату из `docs/source/tz/_export.md` | читать для контекста; расхождение с §05 → вопрос, не код |
|
| Экспорт ТЗ | `docs/source/tz/` | снимок на дату из `docs/source/tz/_export.md` | читать для контекста; расхождение с §05 → вопрос, не код |
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
# 04. Как читать модель данных v5.26
|
# 04. Как читать модель данных v5.27
|
||||||
|
|
||||||
Файлы: `docs/model/data-model-v5.26.dbml` (источник истины), `docs/model/entities-v5.26.md` (смысл таблиц; предыдущие
|
Файлы: `docs/model/data-model-v5.27.dbml` (источник истины), `docs/model/entities-v5.27.md` (смысл таблиц; предыдущие
|
||||||
версии `data-model-v5.13…v5.20.dbml` и `entities-v5.13…v5.20.md` остаются как история),
|
версии `data-model-v5.13…v5.20.dbml` и `entities-v5.13…v5.20.md` остаются как история),
|
||||||
`docs/model/diagrams/part01…10.{svg,png}` (диаграммы v5.26 по частям из таблицы ниже; перерисовываются из DBML командой
|
`docs/model/diagrams/part01…10.{svg,png}` (диаграммы v5.27 по частям из таблицы ниже; перерисовываются из DBML командой
|
||||||
`make diagrams` в корне репозитория docs — скрипт `scripts/gen_model_diagrams.py`, нужен npx; при новой версии DBML
|
`make diagrams` в корне репозитория docs — скрипт `scripts/gen_model_diagrams.py`, нужен npx; при новой версии DBML
|
||||||
обновить `DBML` в Makefile, а новую таблицу — добавить в раскладку частей скрипта и в эту таблицу).
|
обновить `DBML` в Makefile, а новую таблицу — добавить в раскладку частей скрипта и в эту таблицу).
|
||||||
|
|
||||||
@ -21,6 +21,8 @@
|
|||||||
| 09 Комментарии, аудит, ЕХ | `comment`, `audit_event`, `ex_snapshot`, `ex_snapshot_member`, `ex_snapshot_item` | полиморфные комментарии, append-only журнал, замороженные срезы |
|
| 09 Комментарии, аудит, ЕХ | `comment`, `audit_event`, `ex_snapshot`, `ex_snapshot_member`, `ex_snapshot_item` | полиморфные комментарии, append-only журнал, замороженные срезы |
|
||||||
| 10 Метрики качества первички | `quality_intake_fact`, `quality_outcome_fact`, `quality_failure_fact` | факты распознавания и исхода документа, технические отказы — append-only, без FK |
|
| 10 Метрики качества первички | `quality_intake_fact`, `quality_outcome_fact`, `quality_failure_fact` | факты распознавания и исхода документа, технические отказы — append-only, без FK |
|
||||||
|
|
||||||
|
**v5.27:** КФО: ОФР и хранение (arm-core PR #251, миграция `0014_dbml_v5_27`): `vgo_assignment.side` (`D`/`K` для ОФР — независимые решения по позициям «строка ОСВ + сторона», `NULL` для ББ; §5 п. 2b); незамороженный результат КФО не хранится — до «Верифицирован» в `kfo_result`/`kfo_result_line` лишь ручные поля (комментарии строк, обоснование порога), полный снимок пишет заморозка (§8 «КФО» п. 12, OQ-192); `correction.ordinal` не вводится.
|
||||||
|
|
||||||
**v5.25:** три таблицы фактов качества распознавания (`quality_intake_fact`/`_outcome_fact`/`_failure_fact`),
|
**v5.25:** три таблицы фактов качества распознавания (`quality_intake_fact`/`_outcome_fact`/`_failure_fact`),
|
||||||
`s3_bucket_role.raw`, `stored_file.is_scan`, `recognition_job.raw_s3_object_id`, `permission_object.QUALITY_METRICS`
|
`s3_bucket_role.raw`, `stored_file.is_scan`, `recognition_job.raw_s3_object_id`, `permission_object.QUALITY_METRICS`
|
||||||
(AURORA-1759).
|
(AURORA-1759).
|
||||||
|
|||||||
@ -667,15 +667,38 @@ closing_* = closing_* строки Qn
|
|||||||
Правило 5 % для пар: суммы равны → маппим; расхождение ≤ 5 % (к меньшей) → берём `min`; > 5 % → подсветка, авто не
|
Правило 5 % для пар: суммы равны → маппим; расхождение ≤ 5 % (к меньшей) → берём `min`; > 5 % → подсветка, авто не
|
||||||
маппится, ждёт корректировки (`ADJUSTMENT`).
|
маппится, ждёт корректировки (`ADJUSTMENT`).
|
||||||
|
|
||||||
ОФР (`statement_type = income`, `measure = turnover`), из FNR03 — **[открыто]**: формализовать с методологами:
|
ОФР (`statement_type = income`, `measure = turnover`, `valid_from = 2024-01-01`; версия 1 — seed
|
||||||
|
`arm-core/api/seed/core/elimination_rules_income_v1.yaml`; источники — DOC-274230 «Правила пар счетов», раздел ОФР, и
|
||||||
|
DOC-277424 «Консолидированный ОФР», 09.11.2026; AURORA-1999). Суммы — обороты `turnover_debit` / `turnover_credit`, а не
|
||||||
|
сальдо. Позиция расчёта — «строка ОСВ + сторона D/K» (§5 п. 2b); у правила сторона 1 берётся по направлению, сторона 2 —
|
||||||
|
всегда по Кт:
|
||||||
|
|
||||||
| Статья | Сторона А | Сторона Б | mode / НДС |
|
| № | Статья 1 / статья 2 | Сторона 1 (компания 1) | Сторона 2 (компания 2) | mode | Что исключается |
|
||||||
|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| 2110 Выручка | Кт 90.01 (с НДС, приоритет) либо Дт 62.01/62.21/62.31 по контрагенту | Кт 60.01/60.21/60.31 + 76 (кроме 76.07.*, 76.03.*, плюс 76.07.2) | `full` — берётся сторона А; без НДС = с НДС / (1 + средневзвешенная ставка/100) |
|
| 1 | 2110 / 2120 | Кт 90.01 | Кт 60.01, 60.21, 60.31, 76 за вычетом 76.03 и 76.07.1, 76.07.5, 76.07.9 (сверка; 62.01/62.21/62.31 компании 1 — тоже только сверка, в seed не заведены) | `full` | сумма Кт 90.01 компании 1 по компании 2 **без НДС**; 2110 компании 1 и 2120 компании 2; `min` не применяется, сверка со счетами 60/62/76 информационная |
|
||||||
| 2120 Себестоимость | — | — | элиминация = ВГО по 2110 (зеркально, без НДС) |
|
| 2 | 2120 / 2110 | Кт 90.01 | — (счетов нет) | `full` | вторая сторона операции по правилу 1: та же сумма, собственной автосуммы нет |
|
||||||
| 2310 Доходы от участия | Дт 76.03 | Кт 76.03 | сторона А |
|
| 3 | 2310 / 2310 (заглушка) | Дт 76.03 | Кт 76.03 (сверка) | `full` | Дт 76.03 компании 1 по компании 2 из 2310 получателя; у компании 2 автоисключения нет, `min` не применяется |
|
||||||
| 2320 Проценты к получению | Дт 76.03/76.05/76.08/76.09 | Кт 66.02/.04/.06/.22/.24/.26, 67.02/.04/.06/.22/.24/.26 | min |
|
| 4 | 2320 / 2330 | Дт 76.03, 76.05, 76.08, 76.09 | Кт 66.02/.04/.06/.22/.24/.26, 67.02/.04/.06/.22/.24/.26, 76.07.5, 76.08, 76.28, 76.38 | `min` | `min(ΣA, ΣB)` **обычный, со знаком**, если есть позиции обеих сторон (сторона с нулём — тоже данные); 2320 кредитора и 2330 заёмщика; без встречной стороны автоисключения нет — ручной разбор |
|
||||||
| 2330 Проценты к уплате | Кт чётных субсчетов 66/67 + 76.07.5/76.08/76.28/76.38 | Дт 76.03/.05/.08/.09 | min |
|
| 5 | 2330 / 2320 | Кт тех же счетов 66/67/76 | Дт 76.03/.05/.08/.09 | `min` | зеркало правила 4 (сторона заёмщика той же операции), собственной автосуммы нет |
|
||||||
|
| 6 | 2340 | — | — | — | **только вручную** (КА при необходимости); в seed не заведено |
|
||||||
|
| 7 | 2350 | — | — | — | **только вручную**; в seed не заведено |
|
||||||
|
|
||||||
|
Агрегаты ОФР строятся по основному правилу: 1 и 2 → правило 1, 3 → 3, 4 и 5 → 4; автосумму дают только 1, 3 и 4. Ключ
|
||||||
|
агрегата — версия × правило × компания 1 × компания 2, направленный (А → Б и Б → А — разные агрегаты); `side` в ключ не
|
||||||
|
входит.
|
||||||
|
|
||||||
|
**Выручка и НДС (правило 1, DOC-277424 §4).** Общие по компании 1 за период: `V_TOTAL` — Кт 90.01, `VAT_TOTAL` — Дт 90.03,
|
||||||
|
`R_2110` — статья 2110 формы. `V_TOTAL` сравнивается с 2110 с точностью представления формы (форма в тыс. руб. — после
|
||||||
|
округления `V_TOTAL` до тысяч; в расчёте остаётся полный оборот). Равны → оборот без НДС, сумма агрегата как есть. `V_TOTAL`
|
||||||
|
больше 2110 и `V_TOTAL ≠ 0` → `K = VAT_TOTAL / V_TOTAL` (эффективная доля, не ставка), сумма `S = V_AB × (1 − K)`, где
|
||||||
|
`V_AB` — Кт 90.01 по покупателю из периметра. Иначе автоисключения нет. Акцизы не учитываются; сумма по 2120 покупателя не
|
||||||
|
ограничивается самой статьёй. В коде — `domain/kfo.revenue_exclusion`; `vat_handling = check_90_01_vs_2110` у правила — только
|
||||||
|
метка (код поле не читает).
|
||||||
|
|
||||||
|
**Ограничение seed (правило 1, компания 2).** Субсчета 76.07 вычитаются раскрытием масок (включённые минус исключённые),
|
||||||
|
поэтому в исключениях стоят `76.03` и `76.07.1`, `76.07.5`, `76.07.9`; 76.07.2 остаётся в счетах правила. Голый `76.07`
|
||||||
|
(без субсчёта) остаётся выбранным через маску `76` — на практике такие строки в ОСВ редки; это ограничение стороны сверки,
|
||||||
|
на автосумму правила 1 (она берётся с компании 1) не влияет.
|
||||||
|
|
||||||
Дополнительные ручные корректировки ОФР (ТЗ 6.4, `correction.reason_code`): нереализованная выручка, акцизы
|
Дополнительные ручные корректировки ОФР (ТЗ 6.4, `correction.reason_code`): нереализованная выручка, акцизы
|
||||||
(`osv_entry.is_excisable` для 90), агентское вознаграждение, внутригрупповая амортизация по аренде, проценты по
|
(`osv_entry.is_excisable` для 90), агентское вознаграждение, внутригрупповая амортизация по аренде, проценты по
|
||||||
@ -686,8 +709,8 @@ closing_* = closing_* строки Qn
|
|||||||
## §5. Автоматическое сопоставление ВГО и ручное распределение строк (DOC-223044, DOC-272613; OQ-07, OQ-173 — решения владельца 19.10, 21.10 и 23.10.2026; AURORA-1751/1540/1541 — реализовано, слито в main)
|
## §5. Автоматическое сопоставление ВГО и ручное распределение строк (DOC-223044, DOC-272613; OQ-07, OQ-173 — решения владельца 19.10, 21.10 и 23.10.2026; AURORA-1751/1540/1541 — реализовано, слито в main)
|
||||||
|
|
||||||
Границы: только `closing_debit` / `closing_credit`; только компании периметра версии; правила и счета сторон — из §4
|
Границы: только `closing_debit` / `closing_credit`; только компании периметра версии; правила и счета сторон — из §4
|
||||||
(версия правил — `consolidation_version.elimination_rules_version`), только правила ББ (`statement_type = balance`,
|
(версия правил — `consolidation_version.elimination_rules_version`), в пп. 1–2a — только правила ББ (`statement_type = balance`,
|
||||||
`measure = closing`; правило с другим показателем — ошибка `INVALID_RULE`); строки `group_type = COUNTERPARTY`,
|
`measure = closing`; правило с другим показателем — ошибка `INVALID_RULE`); ОФР — п. 2b; строки `group_type = COUNTERPARTY`,
|
||||||
`data_type ∈ (BU, SUM)`. Единица расчёта — **тройка** (правило r, компания A, компания B). Правила считаются для каждой
|
`data_type ∈ (BU, SUM)`. Единица расчёта — **тройка** (правило r, компания A, компания B). Правила считаются для каждой
|
||||||
упорядоченной пары компаний — и (A, B), и (B, A); поэтому зеркальные правила № 9–16 Прил. 3 в seed не нужны (№ 14 для
|
упорядоченной пары компаний — и (A, B), и (B, A); поэтому зеркальные правила № 9–16 Прил. 3 в seed не нужны (№ 14 для
|
||||||
(A, B) — это № 6 для (B, A)).
|
(A, B) — это № 6 для (B, A)).
|
||||||
@ -774,8 +797,29 @@ AURORA-1751; эндпоинт `GET …/vgo-assignments/distribute`, домен `
|
|||||||
- «не учитывать в КФО» (`is_exclude`) — **только у нераспределённой строки** (строка агрегата так не отмечается:
|
- «не учитывать в КФО» (`is_exclude`) — **только у нераспределённой строки** (строка агрегата так не отмечается:
|
||||||
её сначала убирают из правила — `UNASSIGNED`, — и уже нераспределённую отмечают); CHECK в БД запрещает
|
её сначала убирают из правила — `UNASSIGNED`, — и уже нераспределённую отмечают); CHECK в БД запрещает
|
||||||
`is_exclude = true` одновременно с `rule_id`;
|
`is_exclude = true` одновременно с `rule_id`;
|
||||||
- поле `side` (черновик `dev/api-contract-corrections.md` предполагал его для строки с одновременно дебетовым и
|
- у **ББ** `side = NULL`: решение одно на обе позиции строки (сальдо). У **ОФР** (DBML v5.27) решение хранится по
|
||||||
кредитовым сальдо) в реализации нет — решение одно на обе позиции строки.
|
позиции «строка + `side`» — п. 2b.
|
||||||
|
|
||||||
|
**2b. Разнесение ОФР по позициям D/K (DOC-277424 §3; `statement_type = income`; `GET …/vgo-assignments/distribute?
|
||||||
|
statement_type=income`; домен `api/src/domain/vgo.py`, `VgoService`).** Из каждой контрагентской строки свода
|
||||||
|
(`group_type = COUNTERPARTY`, БУ/СВОД, счёт определён, владелец и контрагент — разные компании периметра) независимо
|
||||||
|
получаются две **позиции**: `(osv_entry_id, D)` с суммой `turnover_debit` и `(osv_entry_id, K)` с суммой `turnover_credit`;
|
||||||
|
`NULL` — нет значения (причина `MISSING_AMOUNT`), 0 и отрицательные числа сохраняются. Назначение одной позиции другую не
|
||||||
|
затрагивает; одна позиция входит не более чем в один агрегат (`DUPLICATE_VGO_POSITION` — внутренняя ошибка расчёта).
|
||||||
|
1. ручное решение (`vgo_assignment` с `side`) важнее автоматики; `ASSIGN` проверяется на допустимость правила для счёта,
|
||||||
|
направления и компаний (`INVALID_VGO_POSITION`), иначе позиция идёт на проверку (`MANUAL_REVIEW_REQUIRED`);
|
||||||
|
2. без ручного решения — правило определяется по счёту и направлению (роль компании 1/2 по §4); единственное
|
||||||
|
подходящее правило назначает позицию даже без встречной; несколько — нераспределённая (`MULTIPLE_RULES`), ни одного —
|
||||||
|
`NO_RULE`; `UNASSIGNED` — снята вручную; исключённая вручную в расчёте не участвует;
|
||||||
|
3. агрегаты — по основному правилу (§4: 1 и 2 → 1, 4 и 5 → 4, 3 → 3); сторона 1 — позиции компании 1 по её направлению
|
||||||
|
(правило 1 — K, остальные — D), сторона 2 — K компании 2;
|
||||||
|
4. решения аналитика: `ASSIGN` (`rule_id`, `side`), `UNASSIGNED`, `is_exclude` — как у ББ (п. 2a), но все операции
|
||||||
|
принимают **обязательный `side`**; запрос без `side` у ОФР — 422 `INVALID_VGO_SIDE`, у ББ `side` указывать нельзя.
|
||||||
|
Смена разнесения ОФР **не переводит корректировки в `DRAFT`** (решение R-4 OpenSpec `kfo-calculation`, DOC-277424 §3.5
|
||||||
|
п. 5: применённые ручные корректировки сохраняют приоритет); у ББ поведение прежнее. Исключение уже назначенной позиции
|
||||||
|
— `UNASSIGNED` + `is_exclude`; «Сбросить» (`reset`) удаляет решение. Распределить сумму одного оборота по нескольким
|
||||||
|
статьям можно только корректировкой стороны агрегата (`correction`), не дроблением позиции.
|
||||||
|
Знаки и точность (§3.7 DOC-277424): суммы со знаком, `min` — обычный (`min(−100; −80) = −100`), автосумма — до двух знаков.
|
||||||
|
|
||||||
Сумма стороны агрегата здесь — Σ всех её строк (п. 1 + п. 2 + ручные), включая односторонние (п. 3) и перенесённые
|
Сумма стороны агрегата здесь — Σ всех её строк (п. 1 + п. 2 + ручные), включая односторонние (п. 3) и перенесённые
|
||||||
вручную; агрегат целиком уходит в КФО, лишнюю строку убирают из правила, а не из агрегата (ответ Лысенко п. 4). Аудит
|
вручную; агрегат целиком уходит в КФО, лишнюю строку убирают из правила, а не из агрегата (ответ Лысенко п. 4). Аудит
|
||||||
@ -813,7 +857,7 @@ min = 106 311 116,46 (до 10.11.2026, с 76.АВ: ΣA = 110 429 113,15, 3,87 %)
|
|||||||
расхождение); при ручном выборе забалансовые счета допускаются. Дополнительно пресетом может быть **правило ББ из §4**
|
расхождение); при ручном выборе забалансовые счета допускаются. Дополнительно пресетом может быть **правило ББ из §4**
|
||||||
(`statement_type = balance`): дебетовые и кредитовые счета берутся из сторон правила (с исключениями `is_excluded`),
|
(`statement_type = balance`): дебетовые и кредитовые счета берутся из сторон правила (с исключениями `is_excluded`),
|
||||||
показатель — `measure` правила (у всех правил ББ seed v1 — `closing`); каскада §5 нет — это просмотр сумм по счетам правила, не сумма элиминации (решение владельца
|
показатель — `measure` правила (у всех правил ББ seed v1 — `closing`); каскада §5 нет — это просмотр сумм по счетам правила, не сумма элиминации (решение владельца
|
||||||
21.10.2026, arm-core #141). Правила ОФР пресетом не являются (ОФР в §4 открыт).
|
21.10.2026, arm-core #141). Правила ОФР пресетом не являются (они описаны в §4 и считаются по оборотам в агрегатах §5 п. 2b).
|
||||||
|
|
||||||
Шахматка — суммы первички: корректировки (§8) в ячейках не учитываются, список «строк без пары» шахматка не даёт —
|
Шахматка — суммы первички: корректировки (§8) в ячейках не учитываются, список «строк без пары» шахматка не даёт —
|
||||||
строки ОСВ ячейки — AURORA-1653 (`osv_entry_ids_*` ячейки), строки без пары — упаковка §5 п. 2 (AURORA-1536).
|
строки ОСВ ячейки — AURORA-1653 (`osv_entry_ids_*` ячейки), строки без пары — упаковка §5 п. 2 (AURORA-1536).
|
||||||
@ -976,8 +1020,10 @@ OQ-145); тем же правилом сервисы разрешают ничь
|
|||||||
- **Автосумма агрегата** (`eliminated_amount`) — по режиму правила, **одной функцией домена с КФО** (блок «КФО», п. 4):
|
- **Автосумма агрегата** (`eliminated_amount`) — по режиму правила, **одной функцией домена с КФО** (блок «КФО», п. 4):
|
||||||
`min` — меньшая сторона в допуске, иначе 0; `manual` — 0; `min_or_full` (правило 2 после правки seed в AURORA-1546)
|
`min` — меньшая сторона в допуске, иначе 0; `manual` — 0; `min_or_full` (правило 2 после правки seed в AURORA-1546)
|
||||||
— меньшая сторона при обеих > 0, `amount_1` при пустой стороне 2, порога нет: `exceeds_threshold = false`, статус
|
— меньшая сторона при обеих > 0, `amount_1` при пустой стороне 2, порога нет: `exceeds_threshold = false`, статус
|
||||||
`AUTO` при обеих сторонах, `ONE_SIDED` при пустой стороне 2 (`eliminated_amount = amount_1`). Сейчас
|
`AUTO` при обеих сторонах, `ONE_SIDED` при пустой стороне 2 (`eliminated_amount = amount_1`). Функция —
|
||||||
`services/correction_source.py` знает только `manual` и «остальное как `min`» — правится вместе с seed.
|
`domain/corrections.automatic_elimination`, общая для таблицы корректировок и КФО (ББ; у ОФР таблица автосумму не
|
||||||
|
считает, см. блок «КФО», п. 4, I-2). Для ОФР режимы `full` и `min` и
|
||||||
|
отсутствие автосуммы у правил 2 и 5 — блок «КФО», п. 4.
|
||||||
- **Порог отклонения агрегата** (`exceeds_threshold`, не путать с контролем выше): `deviation_percent = |ΣA − ΣB| /
|
- **Порог отклонения агрегата** (`exceeds_threshold`, не путать с контролем выше): `deviation_percent = |ΣA − ΣB| /
|
||||||
min(ΣA, ΣB) × 100` сторон агрегата (§5, п. 1/2a); реализовано **строго больше 5 %** (R-35, `domain/corrections.py`,
|
min(ΣA, ΣB) × 100` сторон агрегата (§5, п. 1/2a); реализовано **строго больше 5 %** (R-35, `domain/corrections.py`,
|
||||||
`arm-core#215`/Task 8) — ровно 5,00 % в допуске. ТЗ/DOC-272613 читались как «от 5 % включительно»; аналитик на это не
|
`arm-core#215`/Task 8) — ровно 5,00 % в допуске. ТЗ/DOC-272613 читались как «от 5 % включительно»; аналитик на это не
|
||||||
@ -1012,10 +1058,10 @@ OQ-145); тем же правилом сервисы разрешают ничь
|
|||||||
- **КФО** — блок «КФО» ниже, п. 8: ветка гудвилла идёт по паре этой таблицы независимо от агрегатов корректировок;
|
- **КФО** — блок «КФО» ниже, п. 8: ветка гудвилла идёт по паре этой таблицы независимо от агрегатов корректировок;
|
||||||
у пары с `use_goodwill` — ГО `1170` на ФВ, ДО `1310` на P, строка `GOODWILL` на G, агрегат правила 2 той же пары не
|
у пары с `use_goodwill` — ГО `1170` на ФВ, ДО `1310` на P, строка `GOODWILL` на G, агрегат правила 2 той же пары не
|
||||||
применяется; при `G ≤ 0` или выключенном `goodwill_enabled` — обычный агрегат правила 2. Изменение ввода,
|
применяется; при `G ≤ 0` или выключенном `goodwill_enabled` — обычный агрегат правила 2. Изменение ввода,
|
||||||
переключателя или источников делает результат КФО устаревшим.
|
переключателя или источников видно в КФО сразу: пока версия не заморожена, КФО считается на каждом чтении (п. 12).
|
||||||
|
|
||||||
**КФО** (ТЗ 6.4, 6.8, Прил. 10; AURORA-1546 — расчёт, AURORA-1547 — экран, AURORA-1417 — пересчёт; ещё не реализовано;
|
**КФО** (ТЗ 6.4, 6.8, Прил. 10; AURORA-1546 — расчёт, AURORA-1547 — экран, AURORA-1417 — заморозка; ОФР — AURORA-1999;
|
||||||
контракт — `dev/api-contract-kfo.md`). Источники, в порядке приоритета: DOC-274230 «Правила пар счетов» (Лысенко,
|
реализовано в arm-core PR #251, OpenSpec `kfo-calculation`; контракт — `dev/api-contract-kfo.md`). Источники, в порядке приоритета: DOC-274230 «Правила пар счетов» (Лысенко,
|
||||||
27.10.2026), DOC-259025 «Гудвилл» (03.11), DOC-272613 «Корректировка данных агрегатом» (04.11); черновик команды
|
27.10.2026), DOC-259025 «Гудвилл» (03.11), DOC-272613 «Корректировка данных агрегатом» (04.11); черновик команды
|
||||||
DOC-274636 «Расчёт КФО» и DOC-274647 «Экран: КФО» — там, где страниц Лысенко нет (решение владельца 28.10.2026: страницы
|
DOC-274636 «Расчёт КФО» и DOC-274647 «Экран: КФО» — там, где страниц Лысенко нет (решение владельца 28.10.2026: страницы
|
||||||
аналитика важнее черновика). Развилки, которые решает заказчик, закрыты вариантом черновика как стартовым и помечены
|
аналитика важнее черновика). Развилки, которые решает заказчик, закрыты вариантом черновика как стартовым и помечены
|
||||||
@ -1055,7 +1101,11 @@ OQ — менять по ответу.
|
|||||||
| `min` (ББ 3–8) | `min(amount_1, amount_2)`, если обе стороны > 0 и отклонение в допуске (порог — блок «Корректировка», OQ-178); иначе 0 | `article_1_line` компании 1, `article_2_line` компании 2 |
|
| `min` (ББ 3–8) | `min(amount_1, amount_2)`, если обе стороны > 0 и отклонение в допуске (порог — блок «Корректировка», OQ-178); иначе 0 | `article_1_line` компании 1, `article_2_line` компании 2 |
|
||||||
| `min_or_full` (ББ 2) | `amount_1 ≤ 0` → 0; иначе `amount_2 > 0` → `min(amount_1, amount_2)`, `amount_2 ≤ 0` (пусто или встречная позиция) → `amount_1`; порога нет (DOC-274230, правило 2) | `article_1_line` компании 1; компании 2 — каскадом по `article_2_line` |
|
| `min_or_full` (ББ 2) | `amount_1 ≤ 0` → 0; иначе `amount_2 > 0` → `min(amount_1, amount_2)`, `amount_2 ≤ 0` (пусто или встречная позиция) → `amount_1`; порога нет (DOC-274230, правило 2) | `article_1_line` компании 1; компании 2 — каскадом по `article_2_line` |
|
||||||
| `manual` (ББ 1) | 0 — только корректировка | — |
|
| `manual` (ББ 1) | 0 — только корректировка | — |
|
||||||
| режимы ОФР | по правилам ОФР (DOC-274230, AURORA-1999, §5); до неё агрегатов ОФР нет — `INCOME_RULES_MISSING` | по правилу |
|
| `full` (ОФР 1, 3) | **правило 1** — сумма Кт 90.01 компании 1 по компании 2 **без НДС** (§4: сравнение Кт 90.01 с 2110, при превышении — `× (1 − Дт 90.03 / Кт 90.01)`; иначе автоисключения нет), `min` не применяется; **правило 3** — вся сторона 1 (Дт 76.03 компании 1), встречная сторона и расхождение на сумму не влияют | правило 1: 2110 компании 1 и 2120 компании 2; правило 3: 2310 компании 1, у компании 2 автоисключения нет |
|
||||||
|
| `min` (ОФР 4) | `min(amount_1, amount_2)` — **обычный, со знаком**, без порога 5 %, если присутствуют позиции обеих сторон (сумма 0 — данные, `min` с ней считается); нет встречных позиций — автосуммы нет, ручной разбор | 2320 компании 1 (кредитор), 2330 компании 2 (заёмщик) |
|
||||||
|
| ОФР 2, 5 | собственной автосуммы **нет**: правило 2 — вторая сторона операции правила 1, правило 5 — зеркало правила 4; агрегаты строятся по основному правилу (§5 п. 2b) | — |
|
||||||
|
| ОФР 6, 7 | не заведены — только ручная корректировка (§4) | — |
|
||||||
|
| нет правил ОФР у версии (база до seed) | агрегатов ОФР нет; ББ считается как прежде, ОФР — без исключений, `INCOME_RULES_MISSING` | — |
|
||||||
|
|
||||||
**Каскад** (составная статья «a/b/c»): сумма снимается со строки `a` компании в пределах её доступного остатка
|
**Каскад** (составная статья «a/b/c»): сумма снимается со строки `a` компании в пределах её доступного остатка
|
||||||
(«по данным клиента» строки в рублях минус уже снятое с неё другими агрегатами, не ниже 0), остаток — со строки `b`,
|
(«по данным клиента» строки в рублях минус уже снятое с неё другими агрегатами, не ниже 0), остаток — со строки `b`,
|
||||||
@ -1069,14 +1119,20 @@ OQ — менять по ответу.
|
|||||||
`article_2_line: "1310/1350/1370"`. **Правило 1 остаётся `manual`**: по DOC-274230 обе его суммы — у компании 2
|
`article_2_line: "1310/1350/1370"`. **Правило 1 остаётся `manual`**: по DOC-274230 обе его суммы — у компании 2
|
||||||
(Кт 76.7.1 − Дт 76.7.9 с каскадом 1150 → 1450 → 1550), а сторона агрегата устроена «компания 1 — сторона 1,
|
(Кт 76.7.1 − Дт 76.7.9 с каскадом 1150 → 1450 → 1550), а сторона агрегата устроена «компания 1 — сторона 1,
|
||||||
компания 2 — сторона 2»; автосумма правила 1 — после переработки seed (OQ-193), до того — корректировкой.
|
компания 2 — сторона 2»; автосумма правила 1 — после переработки seed (OQ-193), до того — корректировкой.
|
||||||
|
Правила ОФР 1–5 версии 1 — отдельный seed `elimination_rules_income_v1.yaml` (§4, идемпотентный: повторный seed
|
||||||
|
ничего не дублирует и правила ББ не меняет).
|
||||||
|
|
||||||
Автосумма — **одна функция домена** для таблицы корректировок и КФО (блок «Корректировка», `eliminated_amount`).
|
Автосумма — **одна функция домена** для таблицы корректировок и КФО (блок «Корректировка», `eliminated_amount`) —
|
||||||
|
**только для ББ**. Для ОФР (I-2, отложено): в таблице корректировок `eliminated_amount`/`status` не вычисляются
|
||||||
|
(0 / `MANUAL`), порог 5 % (`exceeds_threshold`) к ОФР не применяется; автосуммы ОФР (правило 1 — выручка без НДС,
|
||||||
|
правило 3 — вся сторона 1, правило 4 — `min` со знаком) считает только источник КФО (`KfoIncomeSource`) и показывает
|
||||||
|
только КФО. Единая функция для таблицы и КФО по ОФР — после доработки.
|
||||||
5. **Корректировка заменяет автосумму.** Применённая корректировка агрегата отменяет его автосумму целиком и к ней не
|
5. **Корректировка заменяет автосумму.** Применённая корректировка агрегата отменяет его автосумму целиком и к ней не
|
||||||
прибавляется (DOC-274636, допущение 4; DOC-272613: корректировки не меняют суммы сторон). Исключения: компания 1 —
|
прибавляется (DOC-274636, допущение 4; DOC-272613: корректировки не меняют суммы сторон). Исключения: компания 1 —
|
||||||
статьи `debit[]` (основная, затем дочерние), компания 2 — `credit[]`, суммы как введены. Если заполнены обе стороны
|
статьи `debit[]` (основная, затем дочерние), компания 2 — `credit[]`, суммы как введены. Если заполнены обе стороны
|
||||||
и их итоги разные, каждая сторона исключает **меньший** итог (ответ Лысенко п. 8): снимается со статей стороны по
|
и их итоги разные, каждая сторона исключает **меньший** итог (ответ Лысенко п. 8): снимается со статей стороны по
|
||||||
порядку — основная, затем дочерние в порядке ввода — до исчерпания. Пустая сторона ничего не исключает, другая — как
|
порядку — основная, затем дочерние в порядке ввода — до исчерпания. Пустая сторона ничего не исключает, другая — как
|
||||||
введена (одностороннее правило 1, правила ОФР 1–3).
|
введена (одностороннее правило 1, правила ОФР 1 и 3).
|
||||||
6. **«В т. ч. взаимные» по компании (`vgo_amount`).** Σ исключений компании по строке в рублях → тыс. руб., **до целых
|
6. **«В т. ч. взаимные» по компании (`vgo_amount`).** Σ исключений компании по строке в рублях → тыс. руб., **до целых
|
||||||
тысяч, половина — от нуля** (`ROUND_HALF_UP` по модулю), со **знаком строки**: у строк расходов (п. 2, они ≤ 0)
|
тысяч, половина — от нуля** (`ROUND_HALF_UP` по модулю), со **знаком строки**: у строк расходов (п. 2, они ≤ 0)
|
||||||
`vgo_amount` отрицательный. На всех строках одно равенство `cleaned_amount = client_amount − vgo_amount`; исключение
|
`vgo_amount` отрицательный. На всех строках одно равенство `cleaned_amount = client_amount − vgo_amount`; исключение
|
||||||
@ -1092,6 +1148,10 @@ OQ — менять по ответу.
|
|||||||
`goodwill_adjust` (у `GOODWILL` и итогов, куда он входит), **`bank_amount = sum_amount − vgo_amount + goodwill_adjust`**
|
`goodwill_adjust` (у `GOODWILL` и итогов, куда он входит), **`bank_amount = sum_amount − vgo_amount + goodwill_adjust`**
|
||||||
(`kfo_result_line.consolidated_amount`).
|
(`kfo_result_line.consolidated_amount`).
|
||||||
|
|
||||||
|
**Ручная корректировка ОФР** заменяет автоисключение **только своей стороны** агрегата (DOC-277424 §7.2–7.3): сторона 2
|
||||||
|
сохраняет автосумму или свою корректировку; суммы строк корректировки ОФР допускают отрицательные значения (у ББ — только
|
||||||
|
неотрицательные). Знак расходных строк ОФР (2120, 2210, 2220, 2330, 2350) соблюдается: исключение приближает значение к нулю.
|
||||||
|
|
||||||
**Итоговые строки** (1100, 1200, 1300, 1400, 1500, 1600, 1700; 2100, 2200, 2300, 2400, 2500): «по данным клиента» —
|
**Итоговые строки** (1100, 1200, 1300, 1400, 1500, 1600, 1700; 2100, 2200, 2300, 2400, 2500): «по данным клиента» —
|
||||||
итог из формы компании, а если строки итога в форме нет (упрощённая форма, `form_variant = simplified`) — Σ «по
|
итог из формы компании, а если строки итога в форме нет (упрощённая форма, `form_variant = simplified`) — Σ «по
|
||||||
данным клиента» его слагаемых; «в т. ч. взаимные» — Σ `vgo_amount` слагаемых **с коэффициентом +1** (знак уже в
|
данным клиента» его слагаемых; «в т. ч. взаимные» — Σ `vgo_amount` слагаемых **с коэффициентом +1** (знак уже в
|
||||||
@ -1099,7 +1159,9 @@ OQ — менять по ответу.
|
|||||||
2120; 2200 ← 2100 + 2210 + 2220; 2300 ← 2200 + 2310…2350; 2400 и 2500 — слагаемые по формулам §7 своей редакции
|
2120; 2200 ← 2100 + 2210 + 2220; 2300 ← 2200 + 2310…2350; 2400 и 2500 — слагаемые по формулам §7 своей редакции
|
||||||
(66н / ФСБУ 4), но **без вычитания** (формулы §7 с минусом к КФО не применяются); строки «в т. ч.» (2421 и подобные)
|
(66н / ФСБУ 4), но **без вычитания** (формулы §7 с минусом к КФО не применяются); строки «в т. ч.» (2421 и подобные)
|
||||||
— не слагаемые; `goodwill_adjust` — Σ слагаемых (то есть G у 1100 и 1600); очищенные — разность. Итог КФО — подписанный
|
— не слагаемые; `goodwill_adjust` — Σ слагаемых (то есть G у 1100 и 1600); очищенные — разность. Итог КФО — подписанный
|
||||||
клиентом итог минус взаимные, а не сумма своих строк (OQ-183). Доли компаний у 1100/1600 в сумме меньше 100 % на долю
|
клиентом итог минус взаимные, а не сумма своих строк (OQ-183): у итога `cleaned_amount = client_amount − vgo_amount`, а
|
||||||
|
`bank_amount = sum_amount − vgo_amount + goodwill_adjust` — на **всех** строках, включая итоговые ББ и ОФР (если подписанный
|
||||||
|
в форме итог ОФР 2200 не равен сумме слагаемых, расхождение остаётся и не «чинится» пересчётом, R-10). Доли компаний у 1100/1600 в сумме меньше 100 % на долю
|
||||||
гудвилла — у него нет разреза по компаниям. `deviation_amount` у итоговых строк — `null`.
|
гудвилла — у него нет разреза по компаниям. `deviation_amount` у итоговых строк — `null`.
|
||||||
8. **Гудвилл** (DOC-259025, блок «Гудвилл» выше). По паре ГО → ДО таблицы гудвилла с `use_goodwill` при
|
8. **Гудвилл** (DOC-259025, блок «Гудвилл» выше). По паре ГО → ДО таблицы гудвилла с `use_goodwill` при
|
||||||
`goodwill_enabled` версии: исключения ГО `1170` на ФВ (все строки 58.01 и потомков пары, как в таблице гудвилла),
|
`goodwill_enabled` версии: исключения ГО `1170` на ФВ (все строки 58.01 и потомков пары, как в таблице гудвилла),
|
||||||
@ -1133,16 +1195,23 @@ OQ — менять по ответу.
|
|||||||
итогов, тыс. руб.), причины отклонений от Методики
|
итогов, тыс. руб.), причины отклонений от Методики
|
||||||
(`consolidation_version.methodology_deviations` — ввод на вкладке «КФО»), решение УОБ (номер и дата — только
|
(`consolidation_version.methodology_deviations` — ввод на вкладке «КФО»), решение УОБ (номер и дата — только
|
||||||
чтение). «Подход по Методике» и «согласовано клиентом» — не делаем до ответа заказчика (OQ-190, OQ-191).
|
чтение). «Подход по Методике» и «согласовано клиентом» — не делаем до ответа заказчика (OQ-190, OQ-191).
|
||||||
12. **Пересчёт и заморозка.** Результат хранится у версии (`kfo_result`, одна запись). Пока версия не заморожена,
|
12. **Расчёт, хранение и заморозка** (решение владельца 13.11.2026, R-1; OQ-192). **Пока версия не заморожена, результат
|
||||||
чтение отдаёт результат по текущим данным: если входы изменились после `computed_at`, сервер пересчитывает и
|
не хранится:** каждое чтение (`GET …/kfo`) считает таблицу заново по текущим данным (формы, привязанные документы,
|
||||||
сохраняет до ответа (как обнаруживать изменения — AURORA-1417). Кнопки «Рассчитать» нет (OQ-192). Комментарии строк
|
сводная ОСВ, агрегаты таблицы корректировок, гудвилл), `computed_at` — время запроса; признака «результат устарел» и
|
||||||
и обоснование переносятся при пересчёте по (тип отчёта, код строки). При «Верифицирован» `is_frozen = true` (ставит
|
отдельного запроса состояния нет (`GET …/kfo/state` и поле `data_changed` убраны, R-3). Кнопки «Рассчитать» нет.
|
||||||
AURORA-2002) — дальше результат только читается. **Предупреждения** `{code, message, legal_entity_id?,
|
**В БД до заморозки — только ручные поля:** `kfo_result` (шапка с обоснованием порога, без расчётных сумм),
|
||||||
statement_type?, count?}` не блокируют расчёт; они и сводка корректировок — часть результата и **хранятся в
|
`consolidation_version.methodology_deviations` и строки `kfo_result_line` лишь у строк с комментарием
|
||||||
`kfo_result`** (`warnings`), чтобы замороженная версия отдавала то, что видели при верификации. Коды:
|
(`consolidated_amount = 0`, суммы не заполнены, строк по компаниям нет; снятие комментария строку удаляет).
|
||||||
|
**При «Верифицирован»** (переход статуса, `services/kfo.freeze`, одна транзакция с переходом) таблица считается по
|
||||||
|
текущим источникам, поверх неё накладываются ручные поля (комментарий к 1520, записанный до верификации, остаётся у
|
||||||
|
1520, строка одна), полный снимок — все строки и разрезы по компаниям, `warnings`, сводка корректировок — пишется и
|
||||||
|
`is_frozen = true`; дальше `GET` читает сохранённое без пересчёта и первички, повторная заморозка не пересчитывает.
|
||||||
|
**Предупреждения** `{code, message, legal_entity_id?, statement_type?, count?}` не блокируют расчёт; у замороженной
|
||||||
|
версии они хранятся в `kfo_result.warnings`, чтобы версия отдавала то, что видели при верификации. Коды:
|
||||||
`FORM_MISSING`, `FORM_AMBIGUOUS`, `FORM_UNITS_UNKNOWN`, `LINE_OUTSIDE_BLANK`, `UNALLOCATED_ROWS`,
|
`FORM_MISSING`, `FORM_AMBIGUOUS`, `FORM_UNITS_UNKNOWN`, `LINE_OUTSIDE_BLANK`, `UNALLOCATED_ROWS`,
|
||||||
`INCOME_RULES_MISSING`, `GOODWILL_NOT_APPLIED`, `GOODWILL_ROW_REASSIGNED`, `CORRECTION_SUPERSEDED_BY_GOODWILL`.
|
`INCOME_RULES_MISSING`, `GOODWILL_NOT_APPLIED`, `GOODWILL_ROW_REASSIGNED`, `CORRECTION_SUPERSEDED_BY_GOODWILL`.
|
||||||
Правка ручных полей — аудит `KFO_EDIT`.
|
Правка ручных полей — аудит `KFO_EDIT`. Допущение: блокировка версии на чтении (`FOR UPDATE`) остаётся — расчёт и
|
||||||
|
заморозка не идут параллельно с переходом статуса (R-9); время чтения замеряется на стенде.
|
||||||
|
|
||||||
**Пример** (тыс. руб., если не сказано иное; те же числа — в `examples` контракта). Три компании: А «Альфа», Б «Бета»,
|
**Пример** (тыс. руб., если не сказано иное; те же числа — в `examples` контракта). Три компании: А «Альфа», Б «Бета»,
|
||||||
В «Гамма»; отчётная дата 01.10.2025 (ФСБУ 4). Агрегаты, рубли:
|
В «Гамма»; отчётная дата 01.10.2025 (ФСБУ 4). Агрегаты, рубли:
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
| OQ-06 | Замена одного документа внутри многодокументного файла | DBML | срез 3 | решено: замена файлом целиком |
|
| OQ-06 | Замена одного документа внутри многодокументного файла | DBML | срез 3 | решено: замена файлом целиком |
|
||||||
| OQ-07 | Матчинг ВГО: одна строка = одна позиция (DOC-223044) или агрегировать по (компания, контрагент, счёт) (FNR03)? | DOC-223044 vs FNR03 | срез 5 | **закрыт решением владельца 19.10.2026 (docs #136):** внутри тройки «правило × компания A × компания B» строки сопоставляются группами **1:1, 1:N, N:1** (правило охватывает несколько счетов), N:M нет; выбирается **минимальная упаковка** — меньше строк (закрывается и 1:2, и 1:3 → 1:2); закрытие — точно или ≤ 5 % к меньшей; N ≤ 5; ничья → ручное. Упаковка — детализация; в КФО — агрегат min(ΣA, ΣB) по тройке, на него способ упаковки не влияет. Алгоритм — `05-domain-rules.md` §5 |
|
| OQ-07 | Матчинг ВГО: одна строка = одна позиция (DOC-223044) или агрегировать по (компания, контрагент, счёт) (FNR03)? | DOC-223044 vs FNR03 | срез 5 | **закрыт решением владельца 19.10.2026 (docs #136):** внутри тройки «правило × компания A × компания B» строки сопоставляются группами **1:1, 1:N, N:1** (правило охватывает несколько счетов), N:M нет; выбирается **минимальная упаковка** — меньше строк (закрывается и 1:2, и 1:3 → 1:2); закрытие — точно или ≤ 5 % к меньшей; N ≤ 5; ничья → ручное. Упаковка — детализация; в КФО — агрегат min(ΣA, ΣB) по тройке, на него способ упаковки не влияет. Алгоритм — `05-domain-rules.md` §5 |
|
||||||
| OQ-08 | Знак порога 5 % в правиле пары (≤ или <), и к чему считать % — к меньшей сумме (Методика сноска 14) | FNR03 (знак потерян) | срез 5 | допущение: `≤ 5 %` к меньшей |
|
| OQ-08 | Знак порога 5 % в правиле пары (≤ или <), и к чему считать % — к меньшей сумме (Методика сноска 14) | FNR03 (знак потерян) | срез 5 | допущение: `≤ 5 %` к меньшей |
|
||||||
| OQ-09 | Правила элиминации ОФР (2110/2120/2310/2320/2330): точный состав субсчетов, источник средневзвешенной ставки НДС, выбор субсчетов «работником ПА самостоятельно» | FNR03 | срез 6 | не реализовывать авто-элиминацию ОФР до решения; только ручные `correction` |
|
| OQ-09 | Правила элиминации ОФР (2110/2120/2310/2320/2330): точный состав субсчетов, источник средневзвешенной ставки НДС, выбор субсчетов «работником ПА самостоятельно» | FNR03 | срез 6 | **допущение принято (AURORA-1999, arm-core PR #251):** правила ОФР 1–5 версии 1 заведены seed по DOC-274230 и DOC-277424 (Лысенко, 09.11.2026), §4 и §8 «КФО» п. 4. НДС правила 1 — по DOC-277424 §4.3: эффективная доля `Дт 90.03 / Кт 90.01` по общим оборотам компании 1, применяется, только если Кт 90.01 больше 2110 формы (с точностью её представления), а не средневзвешенная ставка; сумма — Кт 90.01 по покупателю без НДС, `min` не применяется. Правила 6 (2340) и 7 (2350) — только вручную. Ограничение seed: голый `76.07` у компании 2 правила 1 остаётся в сверке (маска 76). Подтверждение заказчика не получено |
|
||||||
| OQ-10 | Гудвилл: входит ли стр. 1350 (добавочный капитал) в базу участия; УК из ББ (1310) или из ОСВ 80/83 | DBML, DOC-259025, FNR03 | срез 6 | допущение: 1310 из ББ; 1350 — настраиваемый флаг, по умолчанию выключен. **06.11:** DOC-259025 (Лысенко, 03.11) — «для УК используется 1310», 1350 в формулу не входит; так реализовано (arm-core #222), флага нет; подтверждение методологов (AURORA-1369) не получено |
|
| OQ-10 | Гудвилл: входит ли стр. 1350 (добавочный капитал) в базу участия; УК из ББ (1310) или из ОСВ 80/83 | DBML, DOC-259025, FNR03 | срез 6 | допущение: 1310 из ББ; 1350 — настраиваемый флаг, по умолчанию выключен. **06.11:** DOC-259025 (Лысенко, 03.11) — «для УК используется 1310», 1350 в формулу не входит; так реализовано (arm-core #222), флага нет; подтверждение методологов (AURORA-1369) не получено |
|
||||||
| OQ-11 | Строка «ППА» в КФО (правило № 1, когда у А нет ОСВ 03) — что это и куда | FNR03 | срез 6 | не реализовывать |
|
| OQ-11 | Строка «ППА» в КФО (правило № 1, когда у А нет ОСВ 03) — что это и куда | FNR03 | срез 6 | не реализовывать |
|
||||||
| OQ-12 | Формулы ОФР: знаки 2410/2420/2430 по ФСБУ 4/2023 vs 66н; состав 1100 (1120–1140) | DOC-221281 | срез 3 | допущение: формулы §7, строки без значения = 0; **06.11.2026 закрыт в части 2410** (AURORA-1864, решение владельца 27.10.2026): знак 2410 не определяется, соотношения 2400 — группа альтернатив §7 (`2300 − 2410` и `2300 + 2410`); 2420/2430 и состав 1100 — открыты; **расширение 07.10.2026:** формулы и справочники по редакциям форм (`66n` / `fsbu4`) — OQ-146 |
|
| OQ-12 | Формулы ОФР: знаки 2410/2420/2430 по ФСБУ 4/2023 vs 66н; состав 1100 (1120–1140) | DOC-221281 | срез 3 | допущение: формулы §7, строки без значения = 0; **06.11.2026 закрыт в части 2410** (AURORA-1864, решение владельца 27.10.2026): знак 2410 не определяется, соотношения 2400 — группа альтернатив §7 (`2300 − 2410` и `2300 + 2410`); 2420/2430 и состав 1100 — открыты; **расширение 07.10.2026:** формулы и справочники по редакциям форм (`66n` / `fsbu4`) — OQ-146 |
|
||||||
@ -197,10 +197,11 @@
|
|||||||
| OQ-189 | Что делает превышение порога: только подсветка, обязательное обоснование до отправки на верификацию, только до финала или блокировка верификации? | DOC-274636 «Расчёт КФО» (черновик), «Что решить», вопрос 13; DOC-037736 («НЕ ТОЧНО»); Excel В-01 | §8 «КФО» п. 10; AURORA-2002/1414 | открыт, вопрос заказчику; допущение принято (docs #206): обоснование обязательно до отправки на «Верификацию РФ/ГО» и до финала; проверяет переход статуса |
|
| OQ-189 | Что делает превышение порога: только подсветка, обязательное обоснование до отправки на верификацию, только до финала или блокировка верификации? | DOC-274636 «Расчёт КФО» (черновик), «Что решить», вопрос 13; DOC-037736 («НЕ ТОЧНО»); Excel В-01 | §8 «КФО» п. 10; AURORA-2002/1414 | открыт, вопрос заказчику; допущение принято (docs #206): обоснование обязательно до отправки на «Верификацию РФ/ГО» и до финала; проверяет переход статуса |
|
||||||
| OQ-190 | «Подход» в реквизитах КФО: пакет документов (`approach` BASIC/EXTENDED, ТЗ 5.1) или подход по Методике (сноска 15: «по Методике / индивидуальный / принята аудированная отчётность»)? Для второго нужно новое поле версии | DOC-274636 «Расчёт КФО» (черновик), «Что решить», вопрос 14 | §8 «КФО» п. 11 | открыт, вопрос заказчику; допущение принято (docs #206): показывается только `approach`; поле «подход по Методике» не заводим до ответа |
|
| OQ-190 | «Подход» в реквизитах КФО: пакет документов (`approach` BASIC/EXTENDED, ТЗ 5.1) или подход по Методике (сноска 15: «по Методике / индивидуальный / принята аудированная отчётность»)? Для второго нужно новое поле версии | DOC-274636 «Расчёт КФО» (черновик), «Что решить», вопрос 14 | §8 «КФО» п. 11 | открыт, вопрос заказчику; допущение принято (docs #206): показывается только `approach`; поле «подход по Методике» не заводим до ответа |
|
||||||
| OQ-191 | Где фиксируется согласование КФО клиентом (Методика 5.8, 6.1): поле версии «да / нет / не направлялось» с датой или не вести в АРМ? | DOC-274636 «Расчёт КФО» (черновик), «Что решить», вопрос 15 | §8 «КФО» п. 11 | открыт, вопрос заказчику; допущение принято (docs #206): не ведём до ответа (вариант черновика — поле версии) |
|
| OQ-191 | Где фиксируется согласование КФО клиентом (Методика 5.8, 6.1): поле версии «да / нет / не направлялось» с датой или не вести в АРМ? | DOC-274636 «Расчёт КФО» (черновик), «Что решить», вопрос 15 | §8 «КФО» п. 11 | открыт, вопрос заказчику; допущение принято (docs #206): не ведём до ответа (вариант черновика — поле версии) |
|
||||||
| OQ-192 | Пересчёт КФО: автоматически после каждого изменения (Excel Р-11, Р-23), по кнопке «Рассчитать КФО» с пометкой «устарела» (FNR03) или только при открытии? | DOC-274636 «Расчёт КФО» (черновик), «Что решить», вопрос 16; AURORA-1417 | §8 «КФО» п. 12 | открыт, вопрос заказчику; допущение принято (docs #206): автоматически: чтение пересчитывает устаревший результат, кнопки нет |
|
| OQ-192 | Пересчёт КФО: автоматически после каждого изменения (Excel Р-11, Р-23), по кнопке «Рассчитать КФО» с пометкой «устарела» (FNR03) или только при открытии? | DOC-274636 «Расчёт КФО» (черновик), «Что решить», вопрос 16; AURORA-1417 | §8 «КФО» п. 12 | **допущение принято, решение владельца 13.11.2026 (R-1):** пока версия не заморожена, результат КФО не хранится — каждое чтение считает по текущим данным, кнопки «Рассчитать» и признака «устарел» нет (`GET …/kfo/state` и `data_changed` убраны); в БД до заморозки — только ручные поля (комментарии строк, обоснование порога); полный снимок пишется при «Верифицирован», дальше только чтение. Ответ заказчика не получен — менять по нему |
|
||||||
| OQ-193 | Правило ББ 1 (76.7.1 / 76.7.9) автоматически по DOC-274230: обе суммы — у компании 2 (Кт 76.7.1 − Дт 76.7.9, каскад 1150 → 1450 → 1550), а сторона агрегата §5 устроена «компания 1 — сторона 1». Как переложить правило в seed (стороны, режим)? | DOC-274230 правило 1; `arm-core/api/seed/core/elimination_rules_v1.yaml` | §5 п. 1, §8 «КФО» п. 4 | открыт, задача команды (follow-up AURORA-1546); до решения правило 1 — `manual`, только корректировкой |
|
| OQ-193 | Правило ББ 1 (76.7.1 / 76.7.9) автоматически по DOC-274230: обе суммы — у компании 2 (Кт 76.7.1 − Дт 76.7.9, каскад 1150 → 1450 → 1550), а сторона агрегата §5 устроена «компания 1 — сторона 1». Как переложить правило в seed (стороны, режим)? | DOC-274230 правило 1; `arm-core/api/seed/core/elimination_rules_v1.yaml` | §5 п. 1, §8 «КФО» п. 4 | открыт, задача команды (follow-up AURORA-1546); до решения правило 1 — `manual`, только корректировкой |
|
||||||
| OQ-194 | КФО при неполном комплекте документов (обязательный комплект и проверки перед расчётом отложены, Excel В-01, В-08): считать по тому, что подтверждено и привязано, с предупреждением, или не считать, пока комплект не полон? | DOC-274636 «Расчёт КФО» (черновик), «Что решить», допущение 17 | §8 «КФО» п. 2 | открыт, вопрос заказчику; допущение принято (docs #206): считать, у компании без формы — нули и `FORM_MISSING` |
|
| OQ-194 | КФО при неполном комплекте документов (обязательный комплект и проверки перед расчётом отложены, Excel В-01, В-08): считать по тому, что подтверждено и привязано, с предупреждением, или не считать, пока комплект не полон? | DOC-274636 «Расчёт КФО» (черновик), «Что решить», допущение 17 | §8 «КФО» п. 2 | открыт, вопрос заказчику; допущение принято (docs #206): считать, у компании без формы — нули и `FORM_MISSING` |
|
||||||
| OQ-195 | Кто переводит прежний срез ЕХ в архив: вручную до верификации новой версии (Excel статусно-ролевой модели, Р-35) или автоматически при записи нового среза (ЕХ ТЗ 6.4)? | DOC-274686 «Версии и прошлые периоды», вопрос 1; AURORA-1397 | §15 п. 2 | открыт, вопрос заказчику (аналитик — AURORA-1397); допущение принято (docs #208): вручную, запись нового среза прежний не архивирует |
|
| OQ-195 | Кто переводит прежний срез ЕХ в архив: вручную до верификации новой версии (Excel статусно-ролевой модели, Р-35) или автоматически при записи нового среза (ЕХ ТЗ 6.4)? | DOC-274686 «Версии и прошлые периоды», вопрос 1; AURORA-1397 | §15 п. 2 | открыт, вопрос заказчику (аналитик — AURORA-1397); допущение принято (docs #208): вручную, запись нового среза прежний не архивирует |
|
||||||
| OQ-196 | Ключ «того же периода» для одного актуального среза и блокировки верификации: ГК × дата (решения Excel Р-35/Р-36) или ГСК × дата (ЕХ ТЗ 6.2, 6.4)? | DOC-274686, вопрос 2; AURORA-1397 | §15 п. 2; AURORA-2002 | открыт, вопрос заказчику; допущение: ГК × дата для «один актуальный» и `superseded_by_snapshot_id`, нумерация — по ГСК (индекс модели) |
|
| OQ-196 | Ключ «того же периода» для одного актуального среза и блокировки верификации: ГК × дата (решения Excel Р-35/Р-36) или ГСК × дата (ЕХ ТЗ 6.2, 6.4)? | DOC-274686, вопрос 2; AURORA-1397 | §15 п. 2; AURORA-2002 | открыт, вопрос заказчику; допущение: ГК × дата для «один актуальный» и `superseded_by_snapshot_id`, нумерация — по ГСК (индекс модели) |
|
||||||
| OQ-197 | Срез при верификации не записался: повторять запись с признаком «не передана в ЕХ», делать верификацию и запись одной операцией или не повторять? | DOC-274687, вопрос 6; Excel 13.10.2026 («механизм повторной передачи не определён») | §15 п. 9 | открыт, вопрос заказчику; допущение: верификация остаётся, признак вычисляется (VERIFIED без среза), такая версия блокирует финал следующей |
|
| OQ-197 | Срез при верификации не записался: повторять запись с признаком «не передана в ЕХ», делать верификацию и запись одной операцией или не повторять? | DOC-274687, вопрос 6; Excel 13.10.2026 («механизм повторной передачи не определён») | §15 п. 9 | открыт, вопрос заказчику; допущение: верификация остаётся, признак вычисляется (VERIFIED без среза), такая версия блокирует финал следующей |
|
||||||
| OQ-198 | Нужен ли PDF «Консолидированная отчётность» в ЕХ (макет [83-01]) и что в нём? | DOC-274687, вопрос 2; макет [83-01]; ЕХ ТЗ 6.7.3 | §15 п. 10 | открыт, вопрос заказчику (продолжение OQ-39); допущение: не формируется и не хранится, xlsx — из payload на лету |
|
| OQ-198 | Нужен ли PDF «Консолидированная отчётность» в ЕХ (макет [83-01]) и что в нём? | DOC-274687, вопрос 2; макет [83-01]; ЕХ ТЗ 6.7.3 | §15 п. 10 | открыт, вопрос заказчику (продолжение OQ-39); допущение: не формируется и не хранится, xlsx — из payload на лету |
|
||||||
|
| OQ-199 | Подтверждённая форма ББ/ОФР без колонки на конец отчётного квартала (или с несколькими такими колонками): нули в КФО молча или предупреждение (предложенный код `FORM_COLUMN_MISSING`)? | Финальное ревью arm-core #251 (I-3), `services/kfo.py` | §8 «КФО» | открыт; допущение: нули без предупреждения |
|
||||||
|
|||||||
@ -48,8 +48,8 @@
|
|||||||
|
|
||||||
| Файл | Что |
|
| Файл | Что |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `data-model-v5.26.dbml` | источник истины; changelog v5.1…v5.26 в шапке; блоки «ИСТОЧНИК» над каждой таблицей (v5.13…v5.25 остаются рядом как история) |
|
| `data-model-v5.27.dbml` | источник истины; changelog v5.1…v5.27 в шапке; блоки «ИСТОЧНИК» над каждой таблицей (v5.13…v5.26 остаются рядом как история) |
|
||||||
| `entities-v5.26.md` | описание сущностей по частям 01–09, таблицы «Что изменилось» по версиям, сценарий «как читать модель», открытые вопросы (v5.13…v5.24 остаются как история) |
|
| `entities-v5.27.md` | описание сущностей по частям 01–09, таблицы «Что изменилось» по версиям, сценарий «как читать модель», открытые вопросы (v5.13…v5.26 остаются как история) |
|
||||||
| `diagrams/part01…09.{svg,png}` | диаграммы v5.21 по частям; перерисовываются `make diagrams` (`scripts/gen_model_diagrams.py`) |
|
| `diagrams/part01…09.{svg,png}` | диаграммы v5.21 по частям; перерисовываются `make diagrams` (`scripts/gen_model_diagrams.py`) |
|
||||||
| `source/tz/data-model-part1_4.dbml` (лежит не в `model/`, а в экспорте ТЗ) | v4 часть 1 — историческое |
|
| `source/tz/data-model-part1_4.dbml` (лежит не в `model/`, а в экспорте ТЗ) | v4 часть 1 — историческое |
|
||||||
|
|
||||||
|
|||||||
@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
1. `CLAUDE.md` (workspace) и `docs/context/00-workspace-layout.md` — как устроена рабочая область, статус аналитики, макет.
|
1. `CLAUDE.md` (workspace) и `docs/context/00-workspace-layout.md` — как устроена рабочая область, статус аналитики, макет.
|
||||||
2. `docs/context/01-project-overview.md`, `02-glossary.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.26.dbml` и
|
3. `docs/context/03-architecture.md`, `04-data-model-guide.md`, затем **весь** `docs/model/data-model-v5.27.dbml` и
|
||||||
`docs/model/entities-v5.26.md`.
|
`docs/model/entities-v5.27.md`.
|
||||||
4. `docs/context/05-domain-rules.md` — алгоритмы (особенно §1.0 и §12 — парсеры ищут структуру по содержимому);
|
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`.
|
`06-test-data.md`; `07-open-questions.md`; `10-user-journey.md`; `09-delivery-plan.md`.
|
||||||
5. `arm-core/`, `tabular-parser/`, `scan-gateway/` — три репозитория, развёрнутые из нулевого коммита шаблона команды,
|
5. `arm-core/`, `tabular-parser/`, `scan-gateway/` — три репозитория, развёрнутые из нулевого коммита шаблона команды,
|
||||||
@ -37,7 +37,7 @@ NATS, MinIO, эмулятор ИС Сканирование), контракт `
|
|||||||
`07-open-questions.md`; если нужен ответ для среза — делай допущение по правилам из этого файла.
|
`07-open-questions.md`; если нужен ответ для среза — делай допущение по правилам из этого файла.
|
||||||
|
|
||||||
Ограничения на всё время работы:
|
Ограничения на всё время работы:
|
||||||
- имена таблиц, колонок и enum'ов — ровно как в DBML v5.26; поля, которых нет в DBML, не изобретать;
|
- имена таблиц, колонок и enum'ов — ровно как в DBML v5.27; поля, которых нет в DBML, не изобретать;
|
||||||
- алгоритмы — только из `05-domain-rules.md`; из страниц ТЗ напрямую не кодировать;
|
- алгоритмы — только из `05-domain-rules.md`; из страниц ТЗ напрямую не кодировать;
|
||||||
- парсеры: никаких координат ячеек, букв колонок, имён листов и номеров строк в коде — структура по содержимому,
|
- парсеры: никаких координат ячеек, букв колонок, имён листов и номеров строк в коде — структура по содержимому,
|
||||||
синонимы в `rules/*.yaml`; фикстуры — регрессия, не спецификация;
|
синонимы в `rules/*.yaml`; фикстуры — регрессия, не спецификация;
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
3. ТЗ 6.8, Прил. 9 — только там, где аналитика молчит.
|
3. ТЗ 6.8, Прил. 9 — только там, где аналитика молчит.
|
||||||
|
|
||||||
На `[design-23-10-check]` (12 пунктов + 3 по ТЗ) Лысенко ответил 29.10; ссылки вида «ответ п. N» — на этот комментарий.
|
На `[design-23-10-check]` (12 пунктов + 3 по ТЗ) Лысенко ответил 29.10; ссылки вида «ответ п. N» — на этот комментарий.
|
||||||
Открыты: ОФР (AURORA-1396) и граница ровно 5 % (§2). Разделение работ с бэкендом — комментарии `[allocation-split]` в
|
Открыта граница ровно 5 % (§2); ОФР (AURORA-1396, AURORA-1999) реализован — §3.5 и DOC-277424. Разделение работ с бэкендом — комментарии `[allocation-split]` в
|
||||||
AURORA-1540 и AURORA-1751 (29.10): разнесение строк и решения по строкам — 1751, корректировка и таблица — 1540.
|
AURORA-1540 и AURORA-1751 (29.10): разнесение строк и решения по строкам — 1751, корректировка и таблица — 1540.
|
||||||
|
|
||||||
## 1. Общее
|
## 1. Общее
|
||||||
@ -34,8 +34,9 @@ AURORA-1540 и AURORA-1751 (29.10): разнесение строк и реше
|
|||||||
|
|
||||||
- **Строка** — неделимая строка сводной ОСВ версии (как `ConsolidatedRowOut`): `entry_ids` — её исходные `osv_entry`.
|
- **Строка** — неделимая строка сводной ОСВ версии (как `ConsolidatedRowOut`): `entry_ids` — её исходные `osv_entry`.
|
||||||
В разнесении участвуют строки уровня «счёт — контрагент», владелец и контрагент — компании периметра, тип данных — БУ
|
В разнесении участвуют строки уровня «счёт — контрагент», владелец и контрагент — компании периметра, тип данных — БУ
|
||||||
(DOC-272613 §1). Для ББ сумма строки — сальдо на конец, для ОФР — обороты по правилу (`measure`). Строка с дебетовым и
|
(DOC-272613 §1). Для ББ сумма строки — сальдо на конец, для ОФР — обороты по правилу (`measure`). Строка ОФР всегда даёт
|
||||||
кредитовым сальдо одновременно даёт две позиции — `side = "D"` и `side = "K"`.
|
две независимые позиции — `side = "D"` (`turnover_debit`) и `side = "K"` (`turnover_credit`); решения по ним хранятся
|
||||||
|
раздельно (§3.5). У ББ решение одно на обе позиции строки, `side` не передаётся.
|
||||||
- **Агрегат** — правило × компания 1 × компания 2 (× тип отчётности, он следует из правила). Отдельно не хранится, считается
|
- **Агрегат** — правило × компания 1 × компания 2 (× тип отчётности, он следует из правила). Отдельно не хранится, считается
|
||||||
при каждом запросе (DOC-272613 §3). Ключ агрегата — `(rule_id, company_1_id, company_2_id)`.
|
при каждом запросе (DOC-272613 §3). Ключ агрегата — `(rule_id, company_1_id, company_2_id)`.
|
||||||
- **Разнесение** (DOC-272613 «Распределение строк по правилам», ответы 1(б), 2(а)) — чистая функция от версии консолидации,
|
- **Разнесение** (DOC-272613 «Распределение строк по правилам», ответы 1(б), 2(а)) — чистая функция от версии консолидации,
|
||||||
@ -91,8 +92,10 @@ AURORA-1540 и AURORA-1751 (29.10): разнесение строк и реше
|
|||||||
— дочерние (хранение — `correction.parent_correction_id`, глубина 1). Пустая сторона допустима, обе пустые — 422
|
— дочерние (хранение — `correction.parent_correction_id`, глубина 1). Пустая сторона допустима, обе пустые — 422
|
||||||
`EMPTY_CORRECTION`.
|
`EMPTY_CORRECTION`.
|
||||||
- `line_code` — код строки формы ББ (ОФР) этой компании; не из формы — 422 `INVALID_LINE_CODE` с `detail.line_code`.
|
- `line_code` — код строки формы ББ (ОФР) этой компании; не из формы — 422 `INVALID_LINE_CODE` с `detail.line_code`.
|
||||||
Сумма — строка ≥ 0, не больше 16 цифр до запятой и двух после (`numeric(18,2)`); это уменьшение статьи. Иное — 422
|
Сумма — строка, не больше 16 цифр до запятой и двух после (`numeric(18,2)`); у ББ ≥ 0 (это уменьшение статьи), у ОФР
|
||||||
массивом pydantic.
|
допустимы и отрицательные суммы (DOC-277424 §7.5). Иное — 422 массивом pydantic. У ОФР сумма — **величина исключения
|
||||||
|
в конвенции оборота**, а знак расходных строк (2120, 2210, 2220, 2330, 2350) сервер применяет сам
|
||||||
|
(`domain/kfo.py`, `apply_income_exclusions`): клиент сумму заранее не инвертирует.
|
||||||
- `comment` обязателен всегда, пустой после обрезки — 422 `COMMENT_REQUIRED` (DOC-272613, ответ п. 6); не длиннее
|
- `comment` обязателен всегда, пустой после обрезки — 422 `COMMENT_REQUIRED` (DOC-272613, ответ п. 6); не длиннее
|
||||||
1000 символов (как комментарий смены статуса), длиннее — 422 массивом pydantic.
|
1000 символов (как комментарий смены статуса), длиннее — 422 массивом pydantic.
|
||||||
- Сохранение сразу применяет корректировку — `status = APPLIED`; поля `status` в теле нет (ответ п. 9). `DRAFT` есть в модели,
|
- Сохранение сразу применяет корректировку — `status = APPLIED`; поля `status` в теле нет (ответ п. 9). `DRAFT` есть в модели,
|
||||||
@ -105,7 +108,9 @@ AURORA-1540 и AURORA-1751 (29.10): разнесение строк и реше
|
|||||||
- Корректировку можно сохранить, даже если стороны не сошлись; ответ показывает `balance` (контроль распределения). В КФО по
|
- Корректировку можно сохранить, даже если стороны не сошлись; ответ показывает `balance` (контроль распределения). В КФО по
|
||||||
выбранным статьям уходит меньшая сумма (ответ п. 8). Ограничения «только при отклонении > 5 %» нет (ответ по ТЗ).
|
выбранным статьям уходит меньшая сумма (ответ п. 8). Ограничения «только при отклонении > 5 %» нет (ответ по ТЗ).
|
||||||
- Каждое сохранение увеличивает `version_no`; аудит `CORRECTION_CREATE` (первая) / `CORRECTION_EDIT` (следующие) с `before` /
|
- Каждое сохранение увеличивает `version_no`; аудит `CORRECTION_CREATE` (первая) / `CORRECTION_EDIT` (следующие) с `before` /
|
||||||
`after`; результат КФО помечается устаревшим (AURORA-1417).
|
`after`. КФО отдельной пометки не получает: до заморозки он считается на каждом чтении по текущим корректировкам, после
|
||||||
|
«Верифицирован» — только чтение (`dev/api-contract-kfo.md` §3.1). У ОФР корректировка заменяет автоисключение только
|
||||||
|
**своей** стороны агрегата.
|
||||||
|
|
||||||
Ответ — пересчитанный агрегат.
|
Ответ — пересчитанный агрегат.
|
||||||
|
|
||||||
@ -134,7 +139,7 @@ AURORA-1540 и AURORA-1751 (29.10): разнесение строк и реше
|
|||||||
`composition_changed = true` (ответ 5). Ответ — вся таблица (решение меняет и агрегаты, и нераспределённые строки).
|
`composition_changed = true` (ответ 5). Ответ — вся таблица (решение меняет и агрегаты, и нераспределённые строки).
|
||||||
|
|
||||||
Аудит: реализовано существующим `audit_action.ASSIGNMENT_CHANGE` (не новым значением, как предполагалось здесь раньше) —
|
Аудит: реализовано существующим `audit_action.ASSIGNMENT_CHANGE` (не новым значением, как предполагалось здесь раньше) —
|
||||||
таблица `vgo_assignment` в DBML v5.24 (AURORA-1751); поля `side` в ней нет (решение см. там же).
|
таблица `vgo_assignment` в DBML v5.24 (AURORA-1751); поле `side` — только для ОФР (DBML v5.27, §3.5).
|
||||||
|
|
||||||
### 3.4 `GET …/export` — xlsx
|
### 3.4 `GET …/export` — xlsx
|
||||||
|
|
||||||
@ -143,6 +148,42 @@ AURORA-1540 и AURORA-1751 (29.10): разнесение строк и реше
|
|||||||
суммы в рублях. Имя файла — `Корректировки_<название ГК>_<год>_<квартал>.xlsx` в `Content-Disposition` (`filename*`, ASCII
|
суммы в рублях. Имя файла — `Корректировки_<название ГК>_<год>_<квартал>.xlsx` в `Content-Disposition` (`filename*`, ASCII
|
||||||
запасное `corrections.xlsx`), как в WIP API (#208). Выбор колонок и фильтры в первой версии не передаются. Аудит `EXPORT`.
|
запасное `corrections.xlsx`), как в WIP API (#208). Выбор колонок и фильтры в первой версии не передаются. Аудит `EXPORT`.
|
||||||
|
|
||||||
|
### 3.5 `…/vgo-assignments/*` — разнесение строк (как реализовано) и ОФР
|
||||||
|
|
||||||
|
Фактический API разнесения (`arm-core#208`; ОФР — PR #251, DBML v5.27). Права — как в §1 (чтение `CONSOLIDATION_VIEW`,
|
||||||
|
правки `CONSOLIDATION_EDIT`).
|
||||||
|
|
||||||
|
| Метод и путь | Запрос | Ответ |
|
||||||
|
|---|---|---|
|
||||||
|
| `GET /consolidations/versions/{version_id}/vgo-assignments/distribute` | query `statement_type` (`balance` по умолчанию / `income`) | `VgoAssignmentCandidatesOut`: группы-агрегаты, ручные назначения, нераспределённые строки |
|
||||||
|
| `PUT …/vgo-assignments/rule` | `VgoAssignmentAttachRuleIn {entry_ids[], rule_id, side?}` | `VgoAssignmentOut[]` |
|
||||||
|
| `DELETE …/vgo-assignments/rule` | `VgoAssignmentDetachRuleIn {statement_type, entry_ids[], side?, reset?}` | `VgoAssignmentOut[]` (при `reset = true` — `[]`) |
|
||||||
|
| `PUT …/vgo-assignments/exclude` | `VgoAssignmentExcludeIn {statement_type, entry_ids[], is_exclude, side?}` | `VgoAssignmentOut[]` |
|
||||||
|
|
||||||
|
**`side`.** У ББ (`statement_type = balance`) `side` **не передаётся** (`NULL`): решение одно на обе позиции строки. У ОФР
|
||||||
|
(`income`) `side` **обязателен** (`"D"` или `"K"`): позиция — это «строка ОСВ + сторона», действие на оба оборота по
|
||||||
|
умолчанию не распространяется. Нарушение (ОФР без `side`, ББ с `side`) — 422 `INVALID_VGO_SIDE`. Остальные ошибки ОФР:
|
||||||
|
422 `INVALID_VGO_RULE` (правило не относится к версии правил версии консолидации), 422 `INVALID_VGO_POSITION` (позиция
|
||||||
|
или направление не подходят правилу ОФР, значения оборота нет, владелец или контрагент вне периметра), 422
|
||||||
|
`INVALID_OSV_ENTRY_IDS` (`entry_ids` не образуют полные строки свода). `side` есть и в `VgoAssignmentOut`,
|
||||||
|
`VgoAssignmentRowOut`, `VgoUnallocatedPositionOut`.
|
||||||
|
|
||||||
|
**Семантика ОФР** (DOC-277424 §3.4–3.5): `ASSIGN` — `rule_id`, `is_exclude = false`; `UNASSIGNED` — `rule_id = NULL`;
|
||||||
|
исключение назначенной позиции — `UNASSIGNED` + `is_exclude = true`; `reset` удаляет решение по позиции (она снова
|
||||||
|
разносится автоматически); `rule_id` вместе с `is_exclude = true` не хранятся. Решение по `D` не меняет решение по `K` той же
|
||||||
|
строки. **Смена разнесения ОФР не переводит применённые корректировки в `DRAFT`** (они сохраняют приоритет, DOC-277424 §3.5
|
||||||
|
п. 5); у ББ — как прежде, корректировки затронутых пар становятся `DRAFT`.
|
||||||
|
|
||||||
|
**Что приходит для ОФР в `GET …/corrections?statement_type=income` и `…/distribute?statement_type=income`:** агрегаты по
|
||||||
|
основному правилу (1, 3, 4; правила 2 и 5 — вторые стороны, собственных агрегатов нет), суммы — обороты; в строках агрегата и
|
||||||
|
в нераспределённых — `side` позиции и `company_role` (`1` или `2`: роль владельца в агрегате; для ББ `null`). Сторона может
|
||||||
|
быть без значения: `amount_present = false`, `amount`/`deviation_amount` — `null` (`NULL` не подменяется нулём,
|
||||||
|
DOC-277424 §3.1). Причина нераспределённой позиции `reason` — строка: `MULTIPLE_RULES`, `NO_RULE`, `UNASSIGNED`,
|
||||||
|
`MANUAL_REVIEW_REQUIRED`, `MISSING_AMOUNT`; у ББ — прежние `MULTIPLE_RULES` и `UNASSIGNED` (и `unassigned_reason =
|
||||||
|
PARTIAL_MANUAL_ASSIGNMENT` у строки). Правило в `rules[]` несёт `elimination_mode` (`min`, `min_or_full`, `manual`, `full`).
|
||||||
|
Корректировка ОФР вводится как у ББ (§3.2): `line_code` — статья ОФР компании, суммы со знаком; правила 6 и 7
|
||||||
|
(2340, 2350) в seed не заведены — только ручная корректировка по статье, агрегата у них нет.
|
||||||
|
|
||||||
## 4. Схемы
|
## 4. Схемы
|
||||||
|
|
||||||
Поля без `?` есть всегда; `null` указан явно.
|
Поля без `?` есть всегда; `null` указан явно.
|
||||||
@ -176,7 +217,7 @@ deviation_amount money
|
|||||||
deviation_percent percent | null к меньшей стороне; null — меньшая сторона ≤ 0
|
deviation_percent percent | null к меньшей стороне; null — меньшая сторона ≤ 0
|
||||||
exceeds_threshold bool deviation_percent ≥ 5, или одна сторона пуста при ненулевой другой; у min_or_full — всегда false
|
exceeds_threshold bool deviation_percent ≥ 5, или одна сторона пуста при ненулевой другой; у min_or_full — всегда false
|
||||||
status "AUTO" | "DISCREPANCY" | "ONE_SIDED" | "MANUAL" как EliminationTotalItemOut
|
status "AUTO" | "DISCREPANCY" | "ONE_SIDED" | "MANUAL" как EliminationTotalItemOut
|
||||||
eliminated_amount money автосумма агрегата по режиму правила (§8 «КФО» п. 4) — её исключает КФО, если нет корректировки
|
eliminated_amount money автосумма агрегата по режиму правила (§8 «КФО» п. 4) — её исключает КФО, если нет корректировки; только ББ, у `income` всегда 0 (I-2)
|
||||||
composition_changed bool состав или суммы изменились после применённой корректировки (ответ 5; ответ п. 10 — подсвечивать)
|
composition_changed bool состав или суммы изменились после применённой корректировки (ответ 5; ответ п. 10 — подсвечивать)
|
||||||
correction CorrectionOut | null действующая корректировка (APPLIED; DRAFT — зарезервирован)
|
correction CorrectionOut | null действующая корректировка (APPLIED; DRAFT — зарезервирован)
|
||||||
```
|
```
|
||||||
@ -248,11 +289,8 @@ rule_id? (uuid, для ASSIGN)}`.
|
|||||||
перечитывает таблицу после вызова.
|
перечитывает таблицу после вызова.
|
||||||
- `vgo_assignment` (DBML v5.24) — **только ручные решения**, автоматическое разнесение не хранится (DECISION-5): иначе
|
- `vgo_assignment` (DBML v5.24) — **только ручные решения**, автоматическое разнесение не хранится (DECISION-5): иначе
|
||||||
ручное решение не отличить от автоматического и при пересчёте после замены ОСВ оно затрётся. Поля:
|
ручное решение не отличить от автоматического и при пересчёте после замены ОСВ оно затрётся. Поля:
|
||||||
`consolidation_version_id, statement_type, osv_entry_id, rule_id (NULL), action (ASSIGN | UNASSIGNED), is_exclude
|
`consolidation_version_id, statement_type, osv_entry_id, side (D | K, v5.27, только ОФР), rule_id (NULL), action (ASSIGN | UNASSIGNED), is_exclude
|
||||||
(bool), created_by/at, updated_by/at`; `ASSIGN` — с `rule_id`, `UNASSIGNED` — без; уникальность
|
(bool), created_by/at, updated_by/at`; `ASSIGN` — с `rule_id`, `UNASSIGNED` — без; уникальность: ББ — `(версия, тип, osv_entry_id)`, ОФР — `(версия, тип, osv_entry_id, side)`; `side` обязателен у `income` и `NULL` у `balance` (§3.5). До v5.27 поля не было — решение было одно на обе позиции строки.
|
||||||
`(consolidation_version_id, statement_type, osv_entry_id)`. **Поля `side`, которое черновик этого пункта предполагал
|
|
||||||
для строки с одновременно дебетовым и кредитовым сальдо, в реализации нет** — решение одно на обе позиции строки, не
|
|
||||||
по стороне отдельно.
|
|
||||||
- Разнесение — чистая функция в `api/src/domain/` (как `elimination_packing`): строки свода × правила × ручные решения →
|
- Разнесение — чистая функция в `api/src/domain/` (как `elimination_packing`): строки свода × правила × ручные решения →
|
||||||
агрегаты и нераспределённые строки (с `line_code` и `candidate_rule_ids`). Нынешняя упаковка считает каждое правило
|
агрегаты и нераспределённые строки (с `line_code` и `candidate_rule_ids`). Нынешняя упаковка считает каждое правило
|
||||||
отдельно (TODO в `intercompany_matrix.build_pairs`) — для таблицы корректировок строка должна попадать не более чем в одно
|
отдельно (TODO в `intercompany_matrix.build_pairs`) — для таблицы корректировок строка должна попадать не более чем в одно
|
||||||
@ -262,9 +300,11 @@ rule_id? (uuid, для ASSIGN)}`.
|
|||||||
`eliminated_amount = min`, `status = AUTO`; сторона 2 пуста → `eliminated_amount = amount_1`, `status = ONE_SIDED`;
|
`eliminated_amount = min`, `status = AUTO`; сторона 2 пуста → `eliminated_amount = amount_1`, `status = ONE_SIDED`;
|
||||||
сторона 1 пуста → 0, `ONE_SIDED`; `exceeds_threshold = false` всегда (порога 5 % у правила нет). **Правило 1** остаётся
|
сторона 1 пуста → 0, `ONE_SIDED`; `exceeds_threshold = false` всегда (порога 5 % у правила нет). **Правило 1** остаётся
|
||||||
`manual` (`status = MANUAL`, 0) до переработки seed (OQ-193). Автосумма — **та же функция, по которой считает КФО**:
|
`manual` (`status = MANUAL`, 0) до переработки seed (OQ-193). Автосумма — **та же функция, по которой считает КФО**:
|
||||||
что аналитик видит в `eliminated_amount`, то и исключает КФО, если корректировки нет (корректировка её заменяет).
|
что аналитик видит в `eliminated_amount`, то и исключает КФО, если корректировки нет (корректировка её заменяет) —
|
||||||
- ОФР: тот же ответ с `statement_type = income` **(ждёт ответа в AURORA-1396)**; до него сервер может отдавать пустые
|
**для ББ**. Для ОФР (I-2, отложено) таблица автосумму не считает: `eliminated_amount = 0`, `status = MANUAL`,
|
||||||
`aggregates` и `unallocated` для `income`.
|
`exceeds_threshold` (порог 5 %) не применяется; автосуммы ОФР (правило 1 — выручка без НДС, правило 3 — вся
|
||||||
|
сторона 1, правило 4 — `min` со знаком) вычисляет и показывает только КФО (`KfoIncomeSource`, `services/kfo.py`).
|
||||||
|
- ОФР: тот же ответ с `statement_type = income`; правила 1–5 версии 1 заведены seed, агрегаты — по оборотам, позиции D/K независимы (§3.5, `05-domain-rules.md` §4 и §5 п. 2b, DOC-277424).
|
||||||
|
|
||||||
## 6. Пример
|
## 6. Пример
|
||||||
|
|
||||||
|
|||||||
@ -1,15 +1,16 @@
|
|||||||
# Контракт API результата КФО (AURORA-1546 / AURORA-1547)
|
# Контракт API результата КФО (AURORA-1546 / AURORA-1547)
|
||||||
|
|
||||||
Контракт вкладки «КФО» отчёта версии консолидации — **до реализации** (docs #206, OpenSpec change
|
Контракт вкладки «КФО» отчёта версии консолидации; реализован в arm-core (PR #251, OpenSpec `kfo-calculation`).
|
||||||
`kfo-calculation-contract`). Машиночитаемая копия — `dev/api-contract-kfo.openapi.yaml` с тремя полными примерами
|
Машиночитаемая копия — `dev/api-contract-kfo.openapi.yaml`: пути и схемы **выгружаются из `app.openapi()`**
|
||||||
ответа (их можно брать как фейк для экрана); она генерируется `scripts/kfo_contract/gen_kfo_openapi.py` из
|
(`python -m scripts.export_kfo_contract` из `api/` arm-core), три полных примера ответа и пример тела PUT (`examples`)
|
||||||
сквозного примера §8 (`scripts/kfo_contract/kfo_example.py`, там же проверки правил) — руками не править. Когда расчёт появится в `arm-core`, копия выгружается из `app.openapi()` и
|
переносятся из прежней версии файла (числа — сквозной пример §8, `scripts/kfo_contract/kfo_example.py`; можно брать как
|
||||||
сверяется тестом, как у гудвилла; если файлы разойдутся с кодом — прав код, оба файла правятся вслед за ним.
|
фейк для экрана). Руками файл не правится; сверяет его с кодом тест `api/tests/test_kfo_contract.py` (как у гудвилла:
|
||||||
|
расходится с кодом — прав код, файл выгружается заново).
|
||||||
|
|
||||||
Источники, в порядке приоритета:
|
Источники, в порядке приоритета:
|
||||||
1. `05-domain-rules.md` §8 «КФО» — алгоритм (п. 1–12) и сквозной пример. Здесь формулы не повторяются — только
|
1. `05-domain-rules.md` §8 «КФО» — алгоритм (п. 1–12) и сквозной пример. Здесь формулы не повторяются — только
|
||||||
ссылки «п. N».
|
ссылки «п. N».
|
||||||
2. DBML v5.26: `kfo_result`, `kfo_result_line`, `kfo_result_line_company`, `consolidation_version`.
|
2. DBML v5.27: `kfo_result`, `kfo_result_line`, `kfo_result_line_company`, `consolidation_version`.
|
||||||
3. DOC-274647 «Экран: КФО» (черновик) и макет `[31-04]`, `[31-04-01]` — состав колонок, состояния экрана.
|
3. DOC-274647 «Экран: КФО» (черновик) и макет `[31-04]`, `[31-04-01]` — состав колонок, состояния экрана.
|
||||||
|
|
||||||
## 1. Общее
|
## 1. Общее
|
||||||
@ -36,7 +37,7 @@
|
|||||||
- **Строки** — бланк ББ и ОФР редакции на отчётную дату версии (66н до 31.12.2024, ФСБУ 4 позже) плюс служебная
|
- **Строки** — бланк ББ и ОФР редакции на отчётную дату версии (66н до 31.12.2024, ФСБУ 4 позже) плюс служебная
|
||||||
`GOODWILL` в разделе I сразу после 1170 (§8 «КФО» п. 1, 8). Приходят все строки бланка в его порядке (`ordinal`),
|
`GOODWILL` в разделе I сразу после 1170 (§8 «КФО» п. 1, 8). Приходят все строки бланка в его порядке (`ordinal`),
|
||||||
включая нулевые; `is_total` — итоговая строка.
|
включая нулевые; `is_total` — итоговая строка.
|
||||||
- **По компании** (`companies[]` строки, порядок — как `KfoResultOut.companies`): «По данным клиента»
|
- **По компании** (`companies[]` строки, порядок — как `KfoTableOut.companies`): «По данным клиента»
|
||||||
(`client_amount`), «В том числе взаимные обязательства / обороты» (`vgo_amount`), «Очищенные показатели»
|
(`client_amount`), «В том числе взаимные обязательства / обороты» (`vgo_amount`), «Очищенные показатели»
|
||||||
(`cleaned_amount = client_amount − vgo_amount`), «Доля в показателе по группе, %» (`share_percent`; `null` при нулевом
|
(`cleaned_amount = client_amount − vgo_amount`), «Доля в показателе по группе, %» (`share_percent`; `null` при нулевом
|
||||||
итоге строки или `|доля| ≥ 1000 %`). Строки расходов
|
итоге строки или `|доля| ≥ 1000 %`). Строки расходов
|
||||||
@ -62,17 +63,18 @@
|
|||||||
|
|
||||||
| Метод и путь | Право | Запрос | Ответ | Ошибки |
|
| Метод и путь | Право | Запрос | Ответ | Ошибки |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| `GET /consolidations/versions/{version_id}/kfo` | `KFO_VIEW` | — | 200 `KfoResultOut` | 404 `NOT_FOUND` |
|
| `GET /consolidations/versions/{version_id}/kfo` | `KFO_VIEW` | — | 200 `KfoTableOut` | 404 `NOT_FOUND` |
|
||||||
| `PUT /consolidations/versions/{version_id}/kfo/annotations` | `CONSOLIDATION_EDIT` | `KfoAnnotationsIn` | 200 `KfoResultOut` | 404 `NOT_FOUND`, 409 правок версии, 422 `UNKNOWN_LINE`, 422 валидации тела |
|
| `PUT /consolidations/versions/{version_id}/kfo/annotations` | `CONSOLIDATION_EDIT` | `KfoAnnotationsIn` | 200 `KfoTableOut` | 404 `NOT_FOUND`, 409 правок версии, 422 `UNKNOWN_LINE`, 422 валидации тела |
|
||||||
|
|
||||||
Выгрузки («Таблица», «Форма 2.03.01.01с») — AURORA-1565, отдельным контрактом.
|
Выгрузки («Таблица», «Форма 2.03.01.01с») — AURORA-1565, отдельным контрактом.
|
||||||
|
|
||||||
### 3.1 `GET …/kfo` — результат
|
### 3.1 `GET …/kfo` — результат
|
||||||
|
|
||||||
Весь результат одним ответом, без страниц. **Пока версия не заморожена, ответ — по текущим данным версии**: если
|
Весь результат одним ответом, без страниц. **Пока версия не заморожена, результат не хранится: каждый запрос считает
|
||||||
что-то изменилось после `computed_at` (документы, сопоставление, разнесение, корректировки, гудвилл), сервер
|
таблицу по текущим данным версии** (формы, привязанные документы, сводная ОСВ, агрегаты таблицы корректировок, гудвилл),
|
||||||
пересчитывает и сохраняет результат до ответа (как он это обнаруживает — AURORA-1417). Кнопки «Рассчитать» нет. У
|
`computed_at` — время запроса; расчётные суммы в БД не пишутся (решение владельца 13.11.2026, OQ-192). Признака «результат
|
||||||
замороженной версии (`is_frozen = true`, ставится при «Верифицирован») — сохранённый результат без пересчёта,
|
устарел» и отдельного запроса состояния нет — они не нужны. Кнопки «Рассчитать» нет. У замороженной версии
|
||||||
|
(`is_frozen = true`, снимок записывается при «Верифицирован») — сохранённый результат без пересчёта и чтения первички,
|
||||||
`editable = false`.
|
`editable = false`.
|
||||||
|
|
||||||
Версия без компаний или без форм — не ошибка: строки бланка с нулями и `warnings` (`FORM_MISSING` по каждой компании
|
Версия без компаний или без форм — не ошибка: строки бланка с нулями и `warnings` (`FORM_MISSING` по каждой компании
|
||||||
@ -96,31 +98,31 @@
|
|||||||
`detail.line_code`; ничего не сохраняется.
|
`detail.line_code`; ничего не сохраняется.
|
||||||
- `threshold_justification`, `methodology_deviations` — ≤ 4000 символов; длиннее — 422 массивом pydantic.
|
- `threshold_justification`, `methodology_deviations` — ≤ 4000 символов; длиннее — 422 массивом pydantic.
|
||||||
- Обоснование можно сохранить и без превышения — сервер его не стирает; `justification_required` от этого не меняется.
|
- Обоснование можно сохранить и без превышения — сервер его не стирает; `justification_required` от этого не меняется.
|
||||||
- Всё одной транзакцией; комментарии и обоснование переживают пересчёт (по `statement_type`, `line_code`).
|
- Всё одной транзакцией. До заморозки в БД сохраняются только ручные поля: комментарии строк (строка `kfo_result_line` без сумм, `consolidated_amount = 0`; снятие комментария строку удаляет), обоснование порога, отклонения от Методики; при заморозке они накладываются на рассчитанную таблицу по `(statement_type, line_code)`. Повтор кода в запросе — побеждает последний элемент; все коды проверяются до записи.
|
||||||
- Аудит — одно событие `KFO_EDIT` на запрос (`object_type = kfo_result`, раздел `KFO`), `before` / `after` — только
|
- Аудит — одно событие `KFO_EDIT` на запрос (`object_type = kfo_result`, раздел `KFO`), `before` / `after` — только
|
||||||
изменённые поля. Запрос без изменений аудит не пишет.
|
изменённые поля. Запрос без изменений аудит не пишет.
|
||||||
|
|
||||||
Ответ — `KfoResultOut` целиком (с пересчётом, если он нужен).
|
Ответ — `KfoTableOut` целиком (рассчитан заново, как у `GET`).
|
||||||
|
|
||||||
## 4. Схемы
|
## 4. Схемы
|
||||||
|
|
||||||
Полностью — в OpenAPI. Кратко:
|
Полностью — в OpenAPI. Кратко:
|
||||||
|
|
||||||
```
|
```
|
||||||
KfoResultOut
|
KfoTableOut
|
||||||
version_id uuid; computed_at date-time; is_frozen bool; editable bool; read_only_reason enum|null
|
version_id uuid; computed_at date-time; is_frozen bool; editable bool; read_only_reason enum|null
|
||||||
units "thousand_rub"
|
units "thousand_rub"
|
||||||
companies[] {legal_entity_id, name, inn} — порядок колонок (по имени)
|
companies[] KfoCompany {legal_entity_id, name, inn} — порядок колонок (по имени)
|
||||||
requisites KfoRequisitesOut
|
requisites KfoRequisitesOut
|
||||||
summary {balance: KfoThresholdOut, income: KfoThresholdOut}
|
summary {balance: KfoThresholdOut, income: KfoThresholdOut}
|
||||||
justification_required bool; threshold_justification string|null
|
justification_required bool; threshold_justification string|null
|
||||||
goodwill {enabled bool, total money}
|
goodwill {enabled bool, total money}
|
||||||
balance, income {lines: KfoLineOut[]}
|
balance, income KfoStatementOut {lines: KfoLine[]}
|
||||||
warnings[] KfoWarningOut {code, message, legal_entity_id?, statement_type?, count?}
|
warnings[] KfoWarningOut {code, message, legal_entity_id?, statement_type?, count?}
|
||||||
|
|
||||||
KfoLineOut
|
KfoLine
|
||||||
line_code, line_name, ordinal, is_total, is_threshold_base
|
line_code, line_name, ordinal, is_total, is_threshold_base
|
||||||
companies[] {legal_entity_id, client_amount, vgo_amount, cleaned_amount, share_percent|null} (у GOODWILL — [])
|
companies[] KfoCompanyCell {legal_entity_id, client_amount, vgo_amount, cleaned_amount, share_percent|null} (у GOODWILL — [])
|
||||||
sum_amount, vgo_amount, eliminated_auto, eliminated_manual, goodwill_adjust, bank_amount money
|
sum_amount, vgo_amount, eliminated_auto, eliminated_manual, goodwill_adjust, bank_amount money
|
||||||
deviation_amount money|null (у итогов null)
|
deviation_amount money|null (у итогов null)
|
||||||
comment string|null
|
comment string|null
|
||||||
@ -142,7 +144,7 @@ KfoAnnotationsIn {comments?: [{statement_type, line_code, comment|null}], thre
|
|||||||
| Состояние | Как видно из ответа |
|
| Состояние | Как видно из ответа |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Нет форм у части компаний | `warnings[].code = FORM_MISSING` с `legal_entity_id`, `statement_type`; у компании нули |
|
| Нет форм у части компаний | `warnings[].code = FORM_MISSING` с `legal_entity_id`, `statement_type`; у компании нули |
|
||||||
| ОФР не исключается автоматически | `INCOME_RULES_MISSING` (до AURORA-1999); взаимные обороты — только корректировками |
|
| У версии нет правил ОФР (старая база до seed) | `INCOME_RULES_MISSING` со `statement_type = income`: ББ считается как прежде, ОФР — без автоисключений; при заведённых правилах ОФР 1–5 (seed) предупреждения нет |
|
||||||
| Есть нераспределённые строки | `UNALLOCATED_ROWS`, `count` |
|
| Есть нераспределённые строки | `UNALLOCATED_ROWS`, `count` |
|
||||||
| Превышение порога | `summary.*.exceeded = true`, `is_threshold_base` у строки базы, `justification_required = true` |
|
| Превышение порога | `summary.*.exceeded = true`, `is_threshold_base` у строки базы, `justification_required = true` |
|
||||||
| Гудвилл учтён | `goodwill.enabled = true`, `goodwill.total`, строка `GOODWILL` с `bank_amount` |
|
| Гудвилл учтён | `goodwill.enabled = true`, `goodwill.total`, строка `GOODWILL` с `bank_amount` |
|
||||||
@ -177,5 +179,5 @@ KfoAnnotationsIn {comments?: [{statement_type, line_code, comment|null}], thre
|
|||||||
Варианты, принятые на старте, могут измениться по ответу заказчика — контракт меняется вместе с §8: OQ-180 (строки вне
|
Варианты, принятые на старте, могут измениться по ответу заказчика — контракт меняется вместе с §8: OQ-180 (строки вне
|
||||||
бланка), OQ-181 (колонки), OQ-182 (значение без формы), OQ-183 (итоговая строка), OQ-184 (округление), OQ-185 (место
|
бланка), OQ-181 (колонки), OQ-182 (значение без формы), OQ-183 (итоговая строка), OQ-184 (округление), OQ-185 (место
|
||||||
гудвилла), OQ-186 (объём расхождений), OQ-187 (ЧА), OQ-188 (нулевая база), OQ-189 (действие при превышении),
|
гудвилла), OQ-186 (объём расхождений), OQ-187 (ЧА), OQ-188 (нулевая база), OQ-189 (действие при превышении),
|
||||||
OQ-190/191 (подход по Методике, согласование клиентом — полей нет), OQ-192 (пересчёт), OQ-194 (КФО при неполном
|
OQ-190/191 (подход по Методике, согласование клиентом — полей нет), OQ-192 (пересчёт — допущение по решению владельца 13.11.2026: считается на каждом чтении, хранится при заморозке), OQ-194 (КФО при неполном
|
||||||
комплекте).
|
комплекте).
|
||||||
|
|||||||
@ -1,36 +1,32 @@
|
|||||||
# Сгенерировано scripts/kfo_contract/gen_kfo_openapi.py из сквозного примера §8 «КФО» (docs #206).
|
|
||||||
# Руками не править: правка генератора (и kfo_example.py) → перегенерация; текст — dev/api-contract-kfo.md.
|
|
||||||
openapi: 3.1.0
|
openapi: 3.1.0
|
||||||
info:
|
info:
|
||||||
title: АРМ КА — результат КФО (AURORA-1546/1547)
|
title: АРМ КА — результат КФО (AURORA-1546/1547)
|
||||||
version: '0.1'
|
version: '1.0'
|
||||||
description: 'Контракт до реализации (docs #206). Правила — context/05-domain-rules.md §8 «КФО»; текст — dev/api-contract-kfo.md.
|
|
||||||
Деньги — строки с двумя знаками в тыс. руб. (units).'
|
|
||||||
paths:
|
paths:
|
||||||
/api/v1/consolidations/versions/{version_id}/kfo:
|
/api/v1/consolidations/versions/{version_id}/kfo:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
- consolidations
|
- consolidations
|
||||||
summary: Результат КФО версии
|
summary: Table
|
||||||
description: 'Право KFO_VIEW. Пока версия не заморожена — результат по текущим данным: устаревший пересчитывается и
|
description: Возвращает актуальную таблицу; для замороженной версии — сохранённый результат.
|
||||||
сохраняется до ответа. Замороженный — только чтение сохранённого.'
|
operationId: table_api_v1_consolidations_versions__version_id__kfo_get
|
||||||
operationId: kfo_get
|
|
||||||
security:
|
security:
|
||||||
- bearerAuth: []
|
- bearerAuth: []
|
||||||
parameters: &id001
|
parameters:
|
||||||
- name: version_id
|
- name: version_id
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
|
title: Version Id
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: Результат КФО
|
description: Successful Response
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/KfoResultOut'
|
$ref: '#/components/schemas/KfoTableOut'
|
||||||
examples:
|
examples:
|
||||||
goodwill_exceeded:
|
goodwill_exceeded:
|
||||||
summary: Гудвилл включён, превышение порога ББ (сквозной пример §8)
|
summary: Гудвилл включён, превышение порога ББ (сквозной пример §8)
|
||||||
@ -2018,30 +2014,28 @@ paths:
|
|||||||
legal_entity_id: 33333333-3333-4333-8333-333333333333
|
legal_entity_id: 33333333-3333-4333-8333-333333333333
|
||||||
statement_type: income
|
statement_type: income
|
||||||
count: null
|
count: null
|
||||||
'403':
|
'422':
|
||||||
description: Нет права KFO_VIEW
|
description: Validation Error
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/ErrorOut'
|
$ref: '#/components/schemas/HTTPValidationError'
|
||||||
'404':
|
|
||||||
description: Версия не найдена или вне видимости — NOT_FOUND
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ErrorOut'
|
|
||||||
/api/v1/consolidations/versions/{version_id}/kfo/annotations:
|
/api/v1/consolidations/versions/{version_id}/kfo/annotations:
|
||||||
put:
|
put:
|
||||||
tags:
|
tags:
|
||||||
- consolidations
|
- consolidations
|
||||||
summary: Ручные поля КФО
|
summary: Annotations
|
||||||
description: Право CONSOLIDATION_EDIT, блокировка версии. Комментарии строк, обоснование порога, причины отклонений
|
operationId: annotations_api_v1_consolidations_versions__version_id__kfo_annotations_put
|
||||||
от Методики — одной транзакцией; отсутствующее поле не меняется, null очищает. Аудит KFO_EDIT. Ответ — KfoResultOut
|
|
||||||
целиком.
|
|
||||||
operationId: kfo_annotations_put
|
|
||||||
security:
|
security:
|
||||||
- bearerAuth: []
|
- bearerAuth: []
|
||||||
parameters: *id001
|
parameters:
|
||||||
|
- name: version_id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
title: Version Id
|
||||||
requestBody:
|
requestBody:
|
||||||
required: true
|
required: true
|
||||||
content:
|
content:
|
||||||
@ -2059,292 +2053,294 @@ paths:
|
|||||||
threshold_justification: Расхождение по 1520 — Бета → Альфа, сверка в работе; риск принят
|
threshold_justification: Расхождение по 1520 — Бета → Альфа, сверка в работе; риск принят
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: Результат КФО после сохранения
|
description: Successful Response
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/KfoResultOut'
|
$ref: '#/components/schemas/KfoTableOut'
|
||||||
'403':
|
|
||||||
description: Нет права CONSOLIDATION_EDIT
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ErrorOut'
|
|
||||||
'404':
|
|
||||||
description: NOT_FOUND
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ErrorOut'
|
|
||||||
'409':
|
|
||||||
description: VERSION_NOT_EDITABLE | LOCK_REQUIRED | LOCKED_BY_OTHER
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ErrorOut'
|
|
||||||
'422':
|
'422':
|
||||||
description: UNKNOWN_LINE (detail.statement_type, detail.line_code) или массив ошибок валидации тела (длины 2000/4000)
|
description: Validation Error
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
oneOf:
|
$ref: '#/components/schemas/HTTPValidationError'
|
||||||
- $ref: '#/components/schemas/ErrorOut'
|
|
||||||
- type: object
|
|
||||||
components:
|
components:
|
||||||
schemas:
|
schemas:
|
||||||
KfoLineCompanyOut:
|
ConsolidationApproach:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- BASIC
|
||||||
|
- EXTENDED
|
||||||
|
title: ConsolidationApproach
|
||||||
|
description: DBML `consolidation_approach`.
|
||||||
|
ConsolidationScenario:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- CREATE
|
||||||
|
- CONFIRM
|
||||||
|
title: ConsolidationScenario
|
||||||
|
description: DBML `consolidation_scenario`.
|
||||||
|
ConsolidationStatus:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- INITIATED
|
||||||
|
- DOCUMENTS_PROCESSING
|
||||||
|
- DATA_CORRECTION
|
||||||
|
- CONSOLIDATION_RF
|
||||||
|
- ADJUSTMENT
|
||||||
|
- VERIFICATION_RF
|
||||||
|
- CONSOLIDATION_GO
|
||||||
|
- VERIFICATION_GO
|
||||||
|
- VERIFIED
|
||||||
|
- CANCELLED
|
||||||
|
- REJECTED
|
||||||
|
- ARCHIVED
|
||||||
|
title: ConsolidationStatus
|
||||||
|
description: DBML `consolidation_status`.
|
||||||
|
HTTPValidationError:
|
||||||
|
properties:
|
||||||
|
detail:
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/ValidationError'
|
||||||
|
type: array
|
||||||
|
title: Detail
|
||||||
type: object
|
type: object
|
||||||
additionalProperties: false
|
title: HTTPValidationError
|
||||||
|
KfoAnnotationsIn:
|
||||||
|
properties:
|
||||||
|
comments:
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/KfoCommentIn'
|
||||||
|
type: array
|
||||||
|
title: Comments
|
||||||
|
threshold_justification:
|
||||||
|
anyOf:
|
||||||
|
- type: string
|
||||||
|
maxLength: 4000
|
||||||
|
- type: 'null'
|
||||||
|
title: Threshold Justification
|
||||||
|
methodology_deviations:
|
||||||
|
anyOf:
|
||||||
|
- type: string
|
||||||
|
maxLength: 4000
|
||||||
|
- type: 'null'
|
||||||
|
title: Methodology Deviations
|
||||||
|
type: object
|
||||||
|
title: KfoAnnotationsIn
|
||||||
|
KfoCommentIn:
|
||||||
|
properties:
|
||||||
|
statement_type:
|
||||||
|
$ref: '#/components/schemas/StatementType'
|
||||||
|
line_code:
|
||||||
|
type: string
|
||||||
|
title: Line Code
|
||||||
|
comment:
|
||||||
|
anyOf:
|
||||||
|
- type: string
|
||||||
|
maxLength: 2000
|
||||||
|
- type: 'null'
|
||||||
|
title: Comment
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- statement_type
|
||||||
|
- line_code
|
||||||
|
- comment
|
||||||
|
title: KfoCommentIn
|
||||||
|
KfoCompany:
|
||||||
properties:
|
properties:
|
||||||
legal_entity_id:
|
legal_entity_id:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
client_amount:
|
title: Legal Entity Id
|
||||||
|
name:
|
||||||
type: string
|
type: string
|
||||||
pattern: ^-?\d{1,16}\.\d{2}$
|
title: Name
|
||||||
examples: &id002
|
inn:
|
||||||
- '588500.00'
|
anyOf:
|
||||||
description: «По данным клиента», тыс. руб.; строки расходов приведены к −|x| (§8 «КФО» п. 2)
|
- type: string
|
||||||
vgo_amount:
|
- type: 'null'
|
||||||
type: string
|
title: Inn
|
||||||
pattern: ^-?\d{1,16}\.\d{2}$
|
type: object
|
||||||
examples: *id002
|
|
||||||
description: «В т. ч. взаимные», тыс. руб. до целых, со знаком строки (п. 6)
|
|
||||||
cleaned_amount:
|
|
||||||
type: string
|
|
||||||
pattern: ^-?\d{1,16}\.\d{2}$
|
|
||||||
examples: *id002
|
|
||||||
description: «Очищенные показатели» = client_amount − vgo_amount
|
|
||||||
share_percent:
|
|
||||||
type:
|
|
||||||
- string
|
|
||||||
- 'null'
|
|
||||||
pattern: ^-?\d{1,3}\.\d{2}$
|
|
||||||
description: «Доля в показателе по группе, %» от bank_amount строки, ROUND_HALF_UP; null при нулевом итоге или |доля|
|
|
||||||
≥ 1000 %
|
|
||||||
required:
|
required:
|
||||||
- legal_entity_id
|
- legal_entity_id
|
||||||
- client_amount
|
- name
|
||||||
- vgo_amount
|
- inn
|
||||||
- cleaned_amount
|
title: KfoCompany
|
||||||
- share_percent
|
KfoCompanyCell:
|
||||||
KfoLineOut:
|
properties:
|
||||||
|
legal_entity_id:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
title: Legal Entity Id
|
||||||
|
client_amount:
|
||||||
|
type: string
|
||||||
|
pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
|
||||||
|
title: Client Amount
|
||||||
|
default: '0.00'
|
||||||
|
vgo_amount:
|
||||||
|
type: string
|
||||||
|
pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
|
||||||
|
title: Vgo Amount
|
||||||
|
default: '0.00'
|
||||||
|
cleaned_amount:
|
||||||
|
type: string
|
||||||
|
pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
|
||||||
|
title: Cleaned Amount
|
||||||
|
default: '0.00'
|
||||||
|
share_percent:
|
||||||
|
anyOf:
|
||||||
|
- type: string
|
||||||
|
pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
|
||||||
|
- type: 'null'
|
||||||
|
title: Share Percent
|
||||||
type: object
|
type: object
|
||||||
additionalProperties: false
|
required:
|
||||||
|
- legal_entity_id
|
||||||
|
title: KfoCompanyCell
|
||||||
|
KfoCorrectionsOut:
|
||||||
|
properties:
|
||||||
|
count:
|
||||||
|
type: integer
|
||||||
|
title: Count
|
||||||
|
amount:
|
||||||
|
type: string
|
||||||
|
title: Amount
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- count
|
||||||
|
- amount
|
||||||
|
title: KfoCorrectionsOut
|
||||||
|
KfoGoodwillOut:
|
||||||
|
properties:
|
||||||
|
enabled:
|
||||||
|
type: boolean
|
||||||
|
title: Enabled
|
||||||
|
total:
|
||||||
|
type: string
|
||||||
|
title: Total
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- enabled
|
||||||
|
- total
|
||||||
|
title: KfoGoodwillOut
|
||||||
|
KfoLine:
|
||||||
properties:
|
properties:
|
||||||
line_code:
|
line_code:
|
||||||
type: string
|
type: string
|
||||||
description: код строки бланка редакции на отчётную дату или GOODWILL
|
title: Line Code
|
||||||
line_name:
|
line_name:
|
||||||
type: string
|
anyOf:
|
||||||
|
- type: string
|
||||||
|
- type: 'null'
|
||||||
|
title: Line Name
|
||||||
ordinal:
|
ordinal:
|
||||||
type: integer
|
type: integer
|
||||||
description: порядок строки в бланке
|
title: Ordinal
|
||||||
is_total:
|
is_total:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: итоговая строка бланка (1100, 1600, 2100 …)
|
title: Is Total
|
||||||
is_threshold_base:
|
|
||||||
type: boolean
|
|
||||||
description: строка — база порога (1300, 1600, 2110 или 2200), подсветка при превышении
|
|
||||||
companies:
|
companies:
|
||||||
type: array
|
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/KfoLineCompanyOut'
|
$ref: '#/components/schemas/KfoCompanyCell'
|
||||||
description: по компаниям в порядке KfoResultOut.companies; у GOODWILL — пусто
|
type: array
|
||||||
|
title: Companies
|
||||||
sum_amount:
|
sum_amount:
|
||||||
type: string
|
type: string
|
||||||
pattern: ^-?\d{1,16}\.\d{2}$
|
pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
|
||||||
examples: *id002
|
title: Sum Amount
|
||||||
description: Σ client_amount
|
default: '0.00'
|
||||||
vgo_amount:
|
vgo_amount:
|
||||||
type: string
|
type: string
|
||||||
pattern: ^-?\d{1,16}\.\d{2}$
|
pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
|
||||||
examples: *id002
|
title: Vgo Amount
|
||||||
description: Σ vgo_amount = eliminated_auto + eliminated_manual
|
default: '0.00'
|
||||||
eliminated_auto: &id003
|
eliminated_auto:
|
||||||
type: string
|
type: string
|
||||||
pattern: ^-?\d{1,16}\.\d{2}$
|
pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
|
||||||
examples: *id002
|
title: Eliminated Auto
|
||||||
eliminated_manual: *id003
|
default: '0.00'
|
||||||
|
eliminated_manual:
|
||||||
|
type: string
|
||||||
|
pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
|
||||||
|
title: Eliminated Manual
|
||||||
|
default: '0.00'
|
||||||
goodwill_adjust:
|
goodwill_adjust:
|
||||||
type: string
|
type: string
|
||||||
pattern: ^-?\d{1,16}\.\d{2}$
|
pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
|
||||||
examples: *id002
|
title: Goodwill Adjust
|
||||||
description: Σ G — у GOODWILL и итогов 1100, 1600
|
default: '0.00'
|
||||||
bank_amount:
|
bank_amount:
|
||||||
type: string
|
type: string
|
||||||
pattern: ^-?\d{1,16}\.\d{2}$
|
pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
|
||||||
examples: *id002
|
title: Bank Amount
|
||||||
description: «КФО, подготовленная банком» = sum_amount − vgo_amount + goodwill_adjust
|
default: '0.00'
|
||||||
deviation_amount:
|
deviation_amount:
|
||||||
type:
|
anyOf:
|
||||||
- string
|
- type: string
|
||||||
- 'null'
|
pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
|
||||||
pattern: ^-?\d{1,16}\.\d{2}$
|
- type: 'null'
|
||||||
description: «Расхождения» (§8 «КФО» п. 9); у итогов — null
|
title: Deviation Amount
|
||||||
|
default: '0.00'
|
||||||
|
is_threshold_base:
|
||||||
|
type: boolean
|
||||||
|
title: Is Threshold Base
|
||||||
|
default: false
|
||||||
comment:
|
comment:
|
||||||
type:
|
anyOf:
|
||||||
- string
|
- type: string
|
||||||
- 'null'
|
- type: 'null'
|
||||||
maxLength: 2000
|
title: Comment
|
||||||
|
type: object
|
||||||
required:
|
required:
|
||||||
- line_code
|
- line_code
|
||||||
- line_name
|
- line_name
|
||||||
- ordinal
|
- ordinal
|
||||||
- is_total
|
- is_total
|
||||||
- is_threshold_base
|
title: KfoLine
|
||||||
- companies
|
|
||||||
- sum_amount
|
|
||||||
- vgo_amount
|
|
||||||
- eliminated_auto
|
|
||||||
- eliminated_manual
|
|
||||||
- goodwill_adjust
|
|
||||||
- bank_amount
|
|
||||||
- deviation_amount
|
|
||||||
- comment
|
|
||||||
KfoStatementOut:
|
|
||||||
type: object
|
|
||||||
additionalProperties: false
|
|
||||||
properties:
|
|
||||||
lines:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/KfoLineOut'
|
|
||||||
required:
|
|
||||||
- lines
|
|
||||||
KfoThresholdOut:
|
|
||||||
type: object
|
|
||||||
additionalProperties: false
|
|
||||||
properties:
|
|
||||||
deviation_total: *id003
|
|
||||||
base_kind:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- NET_ASSETS
|
|
||||||
- BALANCE_TOTAL
|
|
||||||
- SALES_PROFIT
|
|
||||||
- REVENUE
|
|
||||||
base_amount: *id003
|
|
||||||
limit_percent:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- '10.00'
|
|
||||||
- '1.00'
|
|
||||||
limit_amount: *id003
|
|
||||||
deviation_percent:
|
|
||||||
type:
|
|
||||||
- string
|
|
||||||
- 'null'
|
|
||||||
pattern: ^-?\d+\.\d{2}$
|
|
||||||
description: deviation_total / base_amount × 100; null при нулевой базе
|
|
||||||
exceeded:
|
|
||||||
type: boolean
|
|
||||||
description: deviation_total > limit_amount (равно — норма)
|
|
||||||
required:
|
|
||||||
- deviation_total
|
|
||||||
- base_kind
|
|
||||||
- base_amount
|
|
||||||
- limit_percent
|
|
||||||
- limit_amount
|
|
||||||
- deviation_percent
|
|
||||||
- exceeded
|
|
||||||
KfoSummaryOut:
|
|
||||||
type: object
|
|
||||||
additionalProperties: false
|
|
||||||
properties:
|
|
||||||
balance:
|
|
||||||
$ref: '#/components/schemas/KfoThresholdOut'
|
|
||||||
income:
|
|
||||||
$ref: '#/components/schemas/KfoThresholdOut'
|
|
||||||
required:
|
|
||||||
- balance
|
|
||||||
- income
|
|
||||||
KfoCompanyOut:
|
|
||||||
type: object
|
|
||||||
additionalProperties: false
|
|
||||||
properties:
|
|
||||||
legal_entity_id:
|
|
||||||
type: string
|
|
||||||
format: uuid
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
inn:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- legal_entity_id
|
|
||||||
- name
|
|
||||||
- inn
|
|
||||||
KfoCorrectionsOut:
|
|
||||||
type: object
|
|
||||||
additionalProperties: false
|
|
||||||
properties:
|
|
||||||
count:
|
|
||||||
type: integer
|
|
||||||
minimum: 0
|
|
||||||
amount: *id003
|
|
||||||
required:
|
|
||||||
- count
|
|
||||||
- amount
|
|
||||||
description: агрегаты с применённой корректировкой и Σ их исключений, тыс. руб.
|
|
||||||
KfoRequisitesOut:
|
KfoRequisitesOut:
|
||||||
type: object
|
|
||||||
additionalProperties: false
|
|
||||||
properties:
|
properties:
|
||||||
company_group_name:
|
company_group_name:
|
||||||
type: string
|
type: string
|
||||||
|
title: Company Group Name
|
||||||
related_group_name:
|
related_group_name:
|
||||||
type:
|
anyOf:
|
||||||
- string
|
- type: string
|
||||||
- 'null'
|
- type: 'null'
|
||||||
|
title: Related Group Name
|
||||||
reporting_date:
|
reporting_date:
|
||||||
type: string
|
type: string
|
||||||
format: date
|
format: date
|
||||||
|
title: Reporting Date
|
||||||
version_no:
|
version_no:
|
||||||
type: integer
|
type: integer
|
||||||
|
title: Version No
|
||||||
version_status:
|
version_status:
|
||||||
type: string
|
$ref: '#/components/schemas/ConsolidationStatus'
|
||||||
description: consolidation_version.status (enum consolidation_status DBML)
|
|
||||||
enum:
|
|
||||||
- INITIATED
|
|
||||||
- DOCUMENTS_PROCESSING
|
|
||||||
- DATA_CORRECTION
|
|
||||||
- CONSOLIDATION_RF
|
|
||||||
- ADJUSTMENT
|
|
||||||
- VERIFICATION_RF
|
|
||||||
- CONSOLIDATION_GO
|
|
||||||
- VERIFICATION_GO
|
|
||||||
- VERIFIED
|
|
||||||
- CANCELLED
|
|
||||||
- REJECTED
|
|
||||||
- ARCHIVED
|
|
||||||
scenario:
|
scenario:
|
||||||
type: string
|
$ref: '#/components/schemas/ConsolidationScenario'
|
||||||
enum:
|
|
||||||
- CREATE
|
|
||||||
- CONFIRM
|
|
||||||
approach:
|
approach:
|
||||||
type: string
|
$ref: '#/components/schemas/ConsolidationApproach'
|
||||||
enum:
|
|
||||||
- BASIC
|
|
||||||
- EXTENDED
|
|
||||||
methodology_deviations:
|
methodology_deviations:
|
||||||
type:
|
anyOf:
|
||||||
- string
|
- type: string
|
||||||
- 'null'
|
- type: 'null'
|
||||||
maxLength: 4000
|
title: Methodology Deviations
|
||||||
uob_decision_no:
|
uob_decision_no:
|
||||||
type:
|
anyOf:
|
||||||
- string
|
- type: string
|
||||||
- 'null'
|
- type: 'null'
|
||||||
|
title: Uob Decision No
|
||||||
uob_decision_date:
|
uob_decision_date:
|
||||||
type:
|
anyOf:
|
||||||
- string
|
- type: string
|
||||||
- 'null'
|
format: date
|
||||||
format: date
|
- type: 'null'
|
||||||
|
title: Uob Decision Date
|
||||||
corrections_balance:
|
corrections_balance:
|
||||||
$ref: '#/components/schemas/KfoCorrectionsOut'
|
$ref: '#/components/schemas/KfoCorrectionsOut'
|
||||||
corrections_income:
|
corrections_income:
|
||||||
$ref: '#/components/schemas/KfoCorrectionsOut'
|
$ref: '#/components/schemas/KfoCorrectionsOut'
|
||||||
|
type: object
|
||||||
required:
|
required:
|
||||||
- company_group_name
|
- company_group_name
|
||||||
- related_group_name
|
- related_group_name
|
||||||
@ -2358,190 +2354,201 @@ components:
|
|||||||
- uob_decision_date
|
- uob_decision_date
|
||||||
- corrections_balance
|
- corrections_balance
|
||||||
- corrections_income
|
- corrections_income
|
||||||
KfoGoodwillOut:
|
title: KfoRequisitesOut
|
||||||
type: object
|
KfoStatementOut:
|
||||||
additionalProperties: false
|
|
||||||
properties:
|
properties:
|
||||||
enabled:
|
lines:
|
||||||
type: boolean
|
items:
|
||||||
total: *id003
|
$ref: '#/components/schemas/KfoLine'
|
||||||
required:
|
type: array
|
||||||
- enabled
|
title: Lines
|
||||||
- total
|
|
||||||
KfoWarningOut:
|
|
||||||
type: object
|
type: object
|
||||||
additionalProperties: false
|
required:
|
||||||
|
- lines
|
||||||
|
title: KfoStatementOut
|
||||||
|
KfoSummaryOut:
|
||||||
properties:
|
properties:
|
||||||
code:
|
balance:
|
||||||
type: string
|
$ref: '#/components/schemas/KfoThresholdOut'
|
||||||
enum:
|
income:
|
||||||
- FORM_MISSING
|
$ref: '#/components/schemas/KfoThresholdOut'
|
||||||
- FORM_AMBIGUOUS
|
|
||||||
- FORM_UNITS_UNKNOWN
|
|
||||||
- LINE_OUTSIDE_BLANK
|
|
||||||
- UNALLOCATED_ROWS
|
|
||||||
- INCOME_RULES_MISSING
|
|
||||||
- GOODWILL_NOT_APPLIED
|
|
||||||
- GOODWILL_ROW_REASSIGNED
|
|
||||||
- CORRECTION_SUPERSEDED_BY_GOODWILL
|
|
||||||
message:
|
|
||||||
type: string
|
|
||||||
legal_entity_id:
|
|
||||||
type:
|
|
||||||
- string
|
|
||||||
- 'null'
|
|
||||||
format: uuid
|
|
||||||
statement_type:
|
|
||||||
type:
|
|
||||||
- string
|
|
||||||
- 'null'
|
|
||||||
enum:
|
|
||||||
- balance
|
|
||||||
- income
|
|
||||||
- null
|
|
||||||
count:
|
|
||||||
type:
|
|
||||||
- integer
|
|
||||||
- 'null'
|
|
||||||
required:
|
|
||||||
- code
|
|
||||||
- message
|
|
||||||
KfoResultOut:
|
|
||||||
type: object
|
type: object
|
||||||
additionalProperties: false
|
required:
|
||||||
|
- balance
|
||||||
|
- income
|
||||||
|
title: KfoSummaryOut
|
||||||
|
KfoTableOut:
|
||||||
properties:
|
properties:
|
||||||
version_id:
|
version_id:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
|
title: Version Id
|
||||||
computed_at:
|
computed_at:
|
||||||
type: string
|
type: string
|
||||||
format: date-time
|
format: date-time
|
||||||
|
title: Computed At
|
||||||
is_frozen:
|
is_frozen:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
title: Is Frozen
|
||||||
editable:
|
editable:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
title: Editable
|
||||||
read_only_reason:
|
read_only_reason:
|
||||||
type:
|
anyOf:
|
||||||
- string
|
- type: string
|
||||||
- 'null'
|
enum:
|
||||||
enum:
|
- VERSION_NOT_EDITABLE
|
||||||
- VERSION_NOT_EDITABLE
|
- LOCK_REQUIRED
|
||||||
- LOCK_REQUIRED
|
- LOCKED_BY_OTHER
|
||||||
- LOCKED_BY_OTHER
|
- type: 'null'
|
||||||
- null
|
title: Read Only Reason
|
||||||
units:
|
units:
|
||||||
type: string
|
type: string
|
||||||
const: thousand_rub
|
const: thousand_rub
|
||||||
|
title: Units
|
||||||
|
default: thousand_rub
|
||||||
companies:
|
companies:
|
||||||
type: array
|
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/KfoCompanyOut'
|
$ref: '#/components/schemas/KfoCompany'
|
||||||
|
type: array
|
||||||
|
title: Companies
|
||||||
requisites:
|
requisites:
|
||||||
$ref: '#/components/schemas/KfoRequisitesOut'
|
$ref: '#/components/schemas/KfoRequisitesOut'
|
||||||
summary:
|
summary:
|
||||||
$ref: '#/components/schemas/KfoSummaryOut'
|
$ref: '#/components/schemas/KfoSummaryOut'
|
||||||
justification_required:
|
justification_required:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
title: Justification Required
|
||||||
threshold_justification:
|
threshold_justification:
|
||||||
type:
|
anyOf:
|
||||||
- string
|
- type: string
|
||||||
- 'null'
|
- type: 'null'
|
||||||
maxLength: 4000
|
title: Threshold Justification
|
||||||
goodwill:
|
|
||||||
$ref: '#/components/schemas/KfoGoodwillOut'
|
|
||||||
balance:
|
balance:
|
||||||
$ref: '#/components/schemas/KfoStatementOut'
|
$ref: '#/components/schemas/KfoStatementOut'
|
||||||
income:
|
income:
|
||||||
$ref: '#/components/schemas/KfoStatementOut'
|
$ref: '#/components/schemas/KfoStatementOut'
|
||||||
warnings:
|
warnings:
|
||||||
type: array
|
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/KfoWarningOut'
|
$ref: '#/components/schemas/KfoWarningOut'
|
||||||
|
type: array
|
||||||
|
title: Warnings
|
||||||
|
goodwill:
|
||||||
|
$ref: '#/components/schemas/KfoGoodwillOut'
|
||||||
|
type: object
|
||||||
required:
|
required:
|
||||||
- version_id
|
- version_id
|
||||||
- computed_at
|
- computed_at
|
||||||
- is_frozen
|
- is_frozen
|
||||||
- editable
|
- editable
|
||||||
- read_only_reason
|
- read_only_reason
|
||||||
- units
|
|
||||||
- companies
|
- companies
|
||||||
- requisites
|
- requisites
|
||||||
- summary
|
- summary
|
||||||
- justification_required
|
- justification_required
|
||||||
- threshold_justification
|
- threshold_justification
|
||||||
- goodwill
|
|
||||||
- balance
|
- balance
|
||||||
- income
|
- income
|
||||||
- warnings
|
- goodwill
|
||||||
KfoCommentIn:
|
title: KfoTableOut
|
||||||
type: object
|
KfoThresholdOut:
|
||||||
additionalProperties: false
|
|
||||||
properties:
|
properties:
|
||||||
statement_type:
|
deviation_total:
|
||||||
|
type: string
|
||||||
|
title: Deviation Total
|
||||||
|
base_kind:
|
||||||
type: string
|
type: string
|
||||||
enum:
|
enum:
|
||||||
- balance
|
- NET_ASSETS
|
||||||
- income
|
- BALANCE_TOTAL
|
||||||
line_code:
|
- SALES_PROFIT
|
||||||
|
- REVENUE
|
||||||
|
title: Base Kind
|
||||||
|
base_amount:
|
||||||
type: string
|
type: string
|
||||||
comment:
|
title: Base Amount
|
||||||
type:
|
limit_percent:
|
||||||
- string
|
type: string
|
||||||
- 'null'
|
title: Limit Percent
|
||||||
maxLength: 2000
|
limit_amount:
|
||||||
|
type: string
|
||||||
|
title: Limit Amount
|
||||||
|
deviation_percent:
|
||||||
|
anyOf:
|
||||||
|
- type: string
|
||||||
|
- type: 'null'
|
||||||
|
title: Deviation Percent
|
||||||
|
exceeded:
|
||||||
|
type: boolean
|
||||||
|
title: Exceeded
|
||||||
|
type: object
|
||||||
required:
|
required:
|
||||||
- statement_type
|
- deviation_total
|
||||||
- line_code
|
- base_kind
|
||||||
- comment
|
- base_amount
|
||||||
KfoAnnotationsIn:
|
- limit_percent
|
||||||
type: object
|
- limit_amount
|
||||||
additionalProperties: false
|
- deviation_percent
|
||||||
properties:
|
- exceeded
|
||||||
comments:
|
title: KfoThresholdOut
|
||||||
type: array
|
KfoWarningOut:
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/KfoCommentIn'
|
|
||||||
threshold_justification:
|
|
||||||
type:
|
|
||||||
- string
|
|
||||||
- 'null'
|
|
||||||
maxLength: 4000
|
|
||||||
methodology_deviations:
|
|
||||||
type:
|
|
||||||
- string
|
|
||||||
- 'null'
|
|
||||||
maxLength: 4000
|
|
||||||
required: []
|
|
||||||
description: Отсутствующее поле не меняется, null — очищает
|
|
||||||
ErrorDetail:
|
|
||||||
type: object
|
|
||||||
additionalProperties: false
|
|
||||||
properties:
|
properties:
|
||||||
code:
|
code:
|
||||||
type: string
|
type: string
|
||||||
|
title: Code
|
||||||
message:
|
message:
|
||||||
type: string
|
type: string
|
||||||
line_code:
|
title: Message
|
||||||
type:
|
legal_entity_id:
|
||||||
- string
|
anyOf:
|
||||||
- 'null'
|
- type: string
|
||||||
|
format: uuid
|
||||||
|
- type: 'null'
|
||||||
|
title: Legal Entity Id
|
||||||
statement_type:
|
statement_type:
|
||||||
type:
|
anyOf:
|
||||||
- string
|
- $ref: '#/components/schemas/StatementType'
|
||||||
- 'null'
|
- type: 'null'
|
||||||
|
count:
|
||||||
|
anyOf:
|
||||||
|
- type: integer
|
||||||
|
- type: 'null'
|
||||||
|
title: Count
|
||||||
|
type: object
|
||||||
required:
|
required:
|
||||||
- code
|
- code
|
||||||
- message
|
- message
|
||||||
ErrorOut:
|
title: KfoWarningOut
|
||||||
type: object
|
StatementType:
|
||||||
additionalProperties: false
|
type: string
|
||||||
|
enum:
|
||||||
|
- balance
|
||||||
|
- income
|
||||||
|
title: StatementType
|
||||||
|
description: DBML `statement_type`.
|
||||||
|
ValidationError:
|
||||||
properties:
|
properties:
|
||||||
detail:
|
loc:
|
||||||
$ref: '#/components/schemas/ErrorDetail'
|
items:
|
||||||
|
anyOf:
|
||||||
|
- type: string
|
||||||
|
- type: integer
|
||||||
|
type: array
|
||||||
|
title: Location
|
||||||
|
msg:
|
||||||
|
type: string
|
||||||
|
title: Message
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
title: Error Type
|
||||||
|
input:
|
||||||
|
title: Input
|
||||||
|
ctx:
|
||||||
|
type: object
|
||||||
|
title: Context
|
||||||
|
type: object
|
||||||
required:
|
required:
|
||||||
- detail
|
- loc
|
||||||
securitySchemes:
|
- msg
|
||||||
bearerAuth:
|
- type
|
||||||
type: http
|
title: ValidationError
|
||||||
scheme: bearer
|
|
||||||
bearerFormat: JWT
|
|
||||||
|
|||||||
1772
model/data-model-v5.27.dbml
Normal file
|
Before Width: | Height: | Size: 522 KiB After Width: | Height: | Size: 507 KiB |
@ -4,9 +4,9 @@
|
|||||||
<!-- Generated by graphviz version 2.47.0 (20210316.0004)
|
<!-- Generated by graphviz version 2.47.0 (20210316.0004)
|
||||||
-->
|
-->
|
||||||
<!-- Title: dbml Pages: 1 -->
|
<!-- Title: dbml Pages: 1 -->
|
||||||
<svg width="3716pt" height="4991pt"
|
<svg width="3716pt" height="4369pt"
|
||||||
viewBox="0.00 0.00 3715.82 4991.21" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
viewBox="0.00 0.00 3715.82 4368.78" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 4987.21)">
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 4364.78)">
|
||||||
<title>dbml</title>
|
<title>dbml</title>
|
||||||
<!-- document_type -->
|
<!-- document_type -->
|
||||||
<g id="document_type" class="node">
|
<g id="document_type" class="node">
|
||||||
@ -35,44 +35,44 @@
|
|||||||
<!-- file_type -->
|
<!-- file_type -->
|
||||||
<g id="file_type" class="node">
|
<g id="file_type" class="node">
|
||||||
<title>file_type</title>
|
<title>file_type</title>
|
||||||
<ellipse fill="none" stroke="black" stroke-width="0" cx="2084.43" cy="-1067.1" rx="190.42" ry="299.63"/>
|
<ellipse fill="none" stroke="black" stroke-width="0" cx="2084.43" cy="-1260.1" rx="190.42" ry="299.63"/>
|
||||||
<polygon fill="#29235c" stroke="transparent" points="1952.43,-1217.1 1952.43,-1277.1 2217.43,-1277.1 2217.43,-1217.1 1952.43,-1217.1"/>
|
<polygon fill="#29235c" stroke="transparent" points="1952.43,-1410.1 1952.43,-1470.1 2217.43,-1470.1 2217.43,-1410.1 1952.43,-1410.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1952.43,-1217.1 1952.43,-1277.1 2217.43,-1277.1 2217.43,-1217.1 1952.43,-1217.1"/>
|
<polygon fill="none" stroke="#29235c" points="1952.43,-1410.1 1952.43,-1470.1 2217.43,-1470.1 2217.43,-1410.1 1952.43,-1410.1"/>
|
||||||
<text text-anchor="start" x="1963.11" y="-1238.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="32.00" fill="#ffffff">       file_type       </text>
|
<text text-anchor="start" x="1963.11" y="-1431.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="32.00" fill="#ffffff">       file_type       </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1952.43,-1157.1 1952.43,-1217.1 2217.43,-1217.1 2217.43,-1157.1 1952.43,-1157.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1952.43,-1350.1 1952.43,-1410.1 2217.43,-1410.1 2217.43,-1350.1 1952.43,-1350.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1952.43,-1157.1 1952.43,-1217.1 2217.43,-1217.1 2217.43,-1157.1 1952.43,-1157.1"/>
|
<polygon fill="none" stroke="#29235c" points="1952.43,-1350.1 1952.43,-1410.1 2217.43,-1410.1 2217.43,-1350.1 1952.43,-1350.1"/>
|
||||||
<text text-anchor="start" x="2019.12" y="-1178.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    XLS    </text>
|
<text text-anchor="start" x="2019.12" y="-1371.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    XLS    </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1952.43,-1097.1 1952.43,-1157.1 2217.43,-1157.1 2217.43,-1097.1 1952.43,-1097.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1952.43,-1290.1 1952.43,-1350.1 2217.43,-1350.1 2217.43,-1290.1 1952.43,-1290.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1952.43,-1097.1 1952.43,-1157.1 2217.43,-1157.1 2217.43,-1097.1 1952.43,-1097.1"/>
|
<polygon fill="none" stroke="#29235c" points="1952.43,-1290.1 1952.43,-1350.1 2217.43,-1350.1 2217.43,-1290.1 1952.43,-1290.1"/>
|
||||||
<text text-anchor="start" x="2008.45" y="-1118.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    XLSX    </text>
|
<text text-anchor="start" x="2008.45" y="-1311.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    XLSX    </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1952.43,-1037.1 1952.43,-1097.1 2217.43,-1097.1 2217.43,-1037.1 1952.43,-1037.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1952.43,-1230.1 1952.43,-1290.1 2217.43,-1290.1 2217.43,-1230.1 1952.43,-1230.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1952.43,-1037.1 1952.43,-1097.1 2217.43,-1097.1 2217.43,-1037.1 1952.43,-1037.1"/>
|
<polygon fill="none" stroke="#29235c" points="1952.43,-1230.1 1952.43,-1290.1 2217.43,-1290.1 2217.43,-1230.1 1952.43,-1230.1"/>
|
||||||
<text text-anchor="start" x="2008.45" y="-1058.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    XLSB    </text>
|
<text text-anchor="start" x="2008.45" y="-1251.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    XLSB    </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1952.43,-977.1 1952.43,-1037.1 2217.43,-1037.1 2217.43,-977.1 1952.43,-977.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1952.43,-1170.1 1952.43,-1230.1 2217.43,-1230.1 2217.43,-1170.1 1952.43,-1170.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1952.43,-977.1 1952.43,-1037.1 2217.43,-1037.1 2217.43,-977.1 1952.43,-977.1"/>
|
<polygon fill="none" stroke="#29235c" points="1952.43,-1170.1 1952.43,-1230.1 2217.43,-1230.1 2217.43,-1170.1 1952.43,-1170.1"/>
|
||||||
<text text-anchor="start" x="2017.36" y="-998.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    PDF    </text>
|
<text text-anchor="start" x="2017.36" y="-1191.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    PDF    </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1952.43,-917.1 1952.43,-977.1 2217.43,-977.1 2217.43,-917.1 1952.43,-917.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1952.43,-1110.1 1952.43,-1170.1 2217.43,-1170.1 2217.43,-1110.1 1952.43,-1110.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1952.43,-917.1 1952.43,-977.1 2217.43,-977.1 2217.43,-917.1 1952.43,-917.1"/>
|
<polygon fill="none" stroke="#29235c" points="1952.43,-1110.1 1952.43,-1170.1 2217.43,-1170.1 2217.43,-1110.1 1952.43,-1110.1"/>
|
||||||
<text text-anchor="start" x="2014.69" y="-938.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    PNG    </text>
|
<text text-anchor="start" x="2014.69" y="-1131.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    PNG    </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1952.43,-857.1 1952.43,-917.1 2217.43,-917.1 2217.43,-857.1 1952.43,-857.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1952.43,-1050.1 1952.43,-1110.1 2217.43,-1110.1 2217.43,-1050.1 1952.43,-1050.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1952.43,-857.1 1952.43,-917.1 2217.43,-917.1 2217.43,-857.1 1952.43,-857.1"/>
|
<polygon fill="none" stroke="#29235c" points="1952.43,-1050.1 1952.43,-1110.1 2217.43,-1110.1 2217.43,-1050.1 1952.43,-1050.1"/>
|
||||||
<text text-anchor="start" x="2018.24" y="-878.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    JPG    </text>
|
<text text-anchor="start" x="2018.24" y="-1071.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    JPG    </text>
|
||||||
<polygon fill="none" stroke="#29235c" stroke-width="2" points="1950.93,-856.1 1950.93,-1278.1 2217.93,-1278.1 2217.93,-856.1 1950.93,-856.1"/>
|
<polygon fill="none" stroke="#29235c" stroke-width="2" points="1950.93,-1049.1 1950.93,-1471.1 2217.93,-1471.1 2217.93,-1049.1 1950.93,-1049.1"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- recognition_pipeline -->
|
<!-- recognition_pipeline -->
|
||||||
<g id="recognition_pipeline" class="node">
|
<g id="recognition_pipeline" class="node">
|
||||||
<title>recognition_pipeline</title>
|
<title>recognition_pipeline</title>
|
||||||
<ellipse fill="none" stroke="black" stroke-width="0" cx="2811.98" cy="-4853.1" rx="307.68" ry="130.22"/>
|
<ellipse fill="none" stroke="black" stroke-width="0" cx="2811.98" cy="-4065.1" rx="307.68" ry="130.22"/>
|
||||||
<polygon fill="#29235c" stroke="transparent" points="2596.98,-4883.1 2596.98,-4943.1 3027.98,-4943.1 3027.98,-4883.1 2596.98,-4883.1"/>
|
<polygon fill="#29235c" stroke="transparent" points="2596.98,-4095.1 2596.98,-4155.1 3027.98,-4155.1 3027.98,-4095.1 2596.98,-4095.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="2596.98,-4883.1 2596.98,-4943.1 3027.98,-4943.1 3027.98,-4883.1 2596.98,-4883.1"/>
|
<polygon fill="none" stroke="#29235c" points="2596.98,-4095.1 2596.98,-4155.1 3027.98,-4155.1 3027.98,-4095.1 2596.98,-4095.1"/>
|
||||||
<text text-anchor="start" x="2607.97" y="-4904.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="32.00" fill="#ffffff">       recognition_pipeline       </text>
|
<text text-anchor="start" x="2607.97" y="-4116.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="32.00" fill="#ffffff">       recognition_pipeline       </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="2596.98,-4823.1 2596.98,-4883.1 3027.98,-4883.1 3027.98,-4823.1 2596.98,-4823.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="2596.98,-4035.1 2596.98,-4095.1 3027.98,-4095.1 3027.98,-4035.1 2596.98,-4035.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="2596.98,-4823.1 2596.98,-4883.1 3027.98,-4883.1 3027.98,-4823.1 2596.98,-4823.1"/>
|
<polygon fill="none" stroke="#29235c" points="2596.98,-4035.1 2596.98,-4095.1 3027.98,-4095.1 3027.98,-4035.1 2596.98,-4035.1"/>
|
||||||
<text text-anchor="start" x="2728" y="-4844.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    tabular    </text>
|
<text text-anchor="start" x="2728" y="-4056.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    tabular    </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="2596.98,-4763.1 2596.98,-4823.1 3027.98,-4823.1 3027.98,-4763.1 2596.98,-4763.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="2596.98,-3975.1 2596.98,-4035.1 3027.98,-4035.1 3027.98,-3975.1 2596.98,-3975.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="2596.98,-4763.1 2596.98,-4823.1 3027.98,-4823.1 3027.98,-4763.1 2596.98,-4763.1"/>
|
<polygon fill="none" stroke="#29235c" points="2596.98,-3975.1 2596.98,-4035.1 3027.98,-4035.1 3027.98,-3975.1 2596.98,-3975.1"/>
|
||||||
<text text-anchor="start" x="2733.35" y="-4784.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    image    </text>
|
<text text-anchor="start" x="2733.35" y="-3996.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    image    </text>
|
||||||
<polygon fill="none" stroke="#29235c" stroke-width="2" points="2595.48,-4762.1 2595.48,-4944.1 3028.48,-4944.1 3028.48,-4762.1 2595.48,-4762.1"/>
|
<polygon fill="none" stroke="#29235c" stroke-width="2" points="2595.48,-3974.1 2595.48,-4156.1 3028.48,-4156.1 3028.48,-3974.1 2595.48,-3974.1"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- period_quarter -->
|
<!-- period_quarter -->
|
||||||
<g id="period_quarter" class="node">
|
<g id="period_quarter" class="node">
|
||||||
@ -167,35 +167,35 @@
|
|||||||
<!-- recognition_status -->
|
<!-- recognition_status -->
|
||||||
<g id="recognition_status" class="node">
|
<g id="recognition_status" class="node">
|
||||||
<title>recognition_status</title>
|
<title>recognition_status</title>
|
||||||
<ellipse fill="none" stroke="black" stroke-width="0" cx="2811.98" cy="-4320.1" rx="289.83" ry="384.83"/>
|
<ellipse fill="none" stroke="black" stroke-width="0" cx="2811.98" cy="-2406.1" rx="289.83" ry="384.83"/>
|
||||||
<polygon fill="#29235c" stroke="transparent" points="2608.98,-4530.1 2608.98,-4590.1 3014.98,-4590.1 3014.98,-4530.1 2608.98,-4530.1"/>
|
<polygon fill="#29235c" stroke="transparent" points="2608.98,-2616.1 2608.98,-2676.1 3014.98,-2676.1 3014.98,-2616.1 2608.98,-2616.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="2608.98,-4530.1 2608.98,-4590.1 3014.98,-4590.1 3014.98,-4530.1 2608.98,-4530.1"/>
|
<polygon fill="none" stroke="#29235c" points="2608.98,-2616.1 2608.98,-2676.1 3014.98,-2676.1 3014.98,-2616.1 2608.98,-2616.1"/>
|
||||||
<text text-anchor="start" x="2619.91" y="-4551.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="32.00" fill="#ffffff">       recognition_status       </text>
|
<text text-anchor="start" x="2619.91" y="-2637.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="32.00" fill="#ffffff">       recognition_status       </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="2608.98,-4470.1 2608.98,-4530.1 3014.98,-4530.1 3014.98,-4470.1 2608.98,-4470.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="2608.98,-2556.1 2608.98,-2616.1 3014.98,-2616.1 3014.98,-2556.1 2608.98,-2556.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="2608.98,-4470.1 2608.98,-4530.1 3014.98,-4530.1 3014.98,-4470.1 2608.98,-4470.1"/>
|
<polygon fill="none" stroke="#29235c" points="2608.98,-2556.1 2608.98,-2616.1 3014.98,-2616.1 3014.98,-2556.1 2608.98,-2556.1"/>
|
||||||
<text text-anchor="start" x="2723.04" y="-4491.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    queued    </text>
|
<text text-anchor="start" x="2723.04" y="-2577.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    queued    </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="2608.98,-4410.1 2608.98,-4470.1 3014.98,-4470.1 3014.98,-4410.1 2608.98,-4410.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="2608.98,-2496.1 2608.98,-2556.1 3014.98,-2556.1 3014.98,-2496.1 2608.98,-2496.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="2608.98,-4410.1 2608.98,-4470.1 3014.98,-4470.1 3014.98,-4410.1 2608.98,-4410.1"/>
|
<polygon fill="none" stroke="#29235c" points="2608.98,-2496.1 2608.98,-2556.1 3014.98,-2556.1 3014.98,-2496.1 2608.98,-2496.1"/>
|
||||||
<text text-anchor="start" x="2707.94" y="-4431.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    published    </text>
|
<text text-anchor="start" x="2707.94" y="-2517.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    published    </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="2608.98,-4350.1 2608.98,-4410.1 3014.98,-4410.1 3014.98,-4350.1 2608.98,-4350.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="2608.98,-2436.1 2608.98,-2496.1 3014.98,-2496.1 3014.98,-2436.1 2608.98,-2436.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="2608.98,-4350.1 2608.98,-4410.1 3014.98,-4410.1 3014.98,-4350.1 2608.98,-4350.1"/>
|
<polygon fill="none" stroke="#29235c" points="2608.98,-2436.1 2608.98,-2496.1 3014.98,-2496.1 3014.98,-2436.1 2608.98,-2436.1"/>
|
||||||
<text text-anchor="start" x="2699.06" y="-4371.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    processing    </text>
|
<text text-anchor="start" x="2699.06" y="-2457.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    processing    </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="2608.98,-4290.1 2608.98,-4350.1 3014.98,-4350.1 3014.98,-4290.1 2608.98,-4290.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="2608.98,-2376.1 2608.98,-2436.1 3014.98,-2436.1 3014.98,-2376.1 2608.98,-2376.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="2608.98,-4290.1 2608.98,-4350.1 3014.98,-4350.1 3014.98,-4290.1 2608.98,-4290.1"/>
|
<polygon fill="none" stroke="#29235c" points="2608.98,-2376.1 2608.98,-2436.1 3014.98,-2436.1 3014.98,-2376.1 2608.98,-2376.1"/>
|
||||||
<text text-anchor="start" x="2740.83" y="-4311.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    done    </text>
|
<text text-anchor="start" x="2740.83" y="-2397.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    done    </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="2608.98,-4230.1 2608.98,-4290.1 3014.98,-4290.1 3014.98,-4230.1 2608.98,-4230.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="2608.98,-2316.1 2608.98,-2376.1 3014.98,-2376.1 3014.98,-2316.1 2608.98,-2316.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="2608.98,-4230.1 2608.98,-4290.1 3014.98,-4290.1 3014.98,-4230.1 2608.98,-4230.1"/>
|
<polygon fill="none" stroke="#29235c" points="2608.98,-2316.1 2608.98,-2376.1 3014.98,-2376.1 3014.98,-2316.1 2608.98,-2316.1"/>
|
||||||
<text text-anchor="start" x="2682.14" y="-4251.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    needs_check    </text>
|
<text text-anchor="start" x="2682.14" y="-2337.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    needs_check    </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="2608.98,-4170.1 2608.98,-4230.1 3014.98,-4230.1 3014.98,-4170.1 2608.98,-4170.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="2608.98,-2256.1 2608.98,-2316.1 3014.98,-2316.1 3014.98,-2256.1 2608.98,-2256.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="2608.98,-4170.1 2608.98,-4230.1 3014.98,-4230.1 3014.98,-4170.1 2608.98,-4170.1"/>
|
<polygon fill="none" stroke="#29235c" points="2608.98,-2256.1 2608.98,-2316.1 3014.98,-2316.1 3014.98,-2256.1 2608.98,-2256.1"/>
|
||||||
<text text-anchor="start" x="2742.64" y="-4191.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    error    </text>
|
<text text-anchor="start" x="2742.64" y="-2277.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    error    </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="2608.98,-4110.1 2608.98,-4170.1 3014.98,-4170.1 3014.98,-4110.1 2608.98,-4110.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="2608.98,-2196.1 2608.98,-2256.1 3014.98,-2256.1 3014.98,-2196.1 2608.98,-2196.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="2608.98,-4110.1 2608.98,-4170.1 3014.98,-4170.1 3014.98,-4110.1 2608.98,-4110.1"/>
|
<polygon fill="none" stroke="#29235c" points="2608.98,-2196.1 2608.98,-2256.1 3014.98,-2256.1 3014.98,-2196.1 2608.98,-2196.1"/>
|
||||||
<text text-anchor="start" x="2723.95" y="-4131.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    timeout    </text>
|
<text text-anchor="start" x="2723.95" y="-2217.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    timeout    </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="2608.98,-4050.1 2608.98,-4110.1 3014.98,-4110.1 3014.98,-4050.1 2608.98,-4050.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="2608.98,-2136.1 2608.98,-2196.1 3014.98,-2196.1 3014.98,-2136.1 2608.98,-2136.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="2608.98,-4050.1 2608.98,-4110.1 3014.98,-4110.1 3014.98,-4050.1 2608.98,-4050.1"/>
|
<polygon fill="none" stroke="#29235c" points="2608.98,-2136.1 2608.98,-2196.1 3014.98,-2196.1 3014.98,-2136.1 2608.98,-2136.1"/>
|
||||||
<text text-anchor="start" x="2755.07" y="-4071.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    dlq    </text>
|
<text text-anchor="start" x="2755.07" y="-2157.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#1d71b8">    dlq    </text>
|
||||||
<polygon fill="none" stroke="#29235c" stroke-width="2" points="2607.98,-4049.1 2607.98,-4591.1 3015.98,-4591.1 3015.98,-4049.1 2607.98,-4049.1"/>
|
<polygon fill="none" stroke="#29235c" stroke-width="2" points="2607.98,-2135.1 2607.98,-2677.1 3015.98,-2677.1 3015.98,-2135.1 2607.98,-2135.1"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- document_check_result -->
|
<!-- document_check_result -->
|
||||||
<g id="document_check_result" class="node">
|
<g id="document_check_result" class="node">
|
||||||
@ -236,16 +236,16 @@
|
|||||||
<g id="consolidation" class="node">
|
<g id="consolidation" class="node">
|
||||||
<title>consolidation</title>
|
<title>consolidation</title>
|
||||||
<g id="a_consolidation"><a xlink:title="consolidation STUB — полное определение в part07_consolidation">
|
<g id="a_consolidation"><a xlink:title="consolidation STUB — полное определение в part07_consolidation">
|
||||||
<ellipse fill="none" stroke="black" stroke-width="0" cx="2084.43" cy="-1472.1" rx="238.09" ry="87.86"/>
|
<ellipse fill="none" stroke="black" stroke-width="0" cx="2084.43" cy="-855.1" rx="238.09" ry="87.86"/>
|
||||||
<polygon fill="#1d71b8" stroke="transparent" points="1918.43,-1472.1 1918.43,-1532.1 2251.43,-1532.1 2251.43,-1472.1 1918.43,-1472.1"/>
|
<polygon fill="#1d71b8" stroke="transparent" points="1918.43,-855.1 1918.43,-915.1 2251.43,-915.1 2251.43,-855.1 1918.43,-855.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1918.43,-1472.1 1918.43,-1532.1 2251.43,-1532.1 2251.43,-1472.1 1918.43,-1472.1"/>
|
<polygon fill="none" stroke="#29235c" points="1918.43,-855.1 1918.43,-915.1 2251.43,-915.1 2251.43,-855.1 1918.43,-855.1"/>
|
||||||
<text text-anchor="start" x="1929.32" y="-1493.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="32.00" fill="#ffffff">       consolidation       </text>
|
<text text-anchor="start" x="1929.32" y="-876.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="32.00" fill="#ffffff">       consolidation       </text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1918.43,-1412.1 1918.43,-1472.1 2251.43,-1472.1 2251.43,-1412.1 1918.43,-1412.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1918.43,-795.1 1918.43,-855.1 2251.43,-855.1 2251.43,-795.1 1918.43,-795.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1918.43,-1412.1 1918.43,-1472.1 2251.43,-1472.1 2251.43,-1412.1 1918.43,-1412.1"/>
|
<polygon fill="none" stroke="#29235c" points="1918.43,-795.1 1918.43,-855.1 2251.43,-855.1 2251.43,-795.1 1918.43,-795.1"/>
|
||||||
<text text-anchor="start" x="1929.43" y="-1433.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="32.00" fill="#29235c">id</text>
|
<text text-anchor="start" x="1929.43" y="-816.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="32.00" fill="#29235c">id</text>
|
||||||
<text text-anchor="start" x="1954.32" y="-1433.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">    </text>
|
<text text-anchor="start" x="1954.32" y="-816.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">    </text>
|
||||||
<text text-anchor="start" x="2179.96" y="-1433.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">uuid</text>
|
<text text-anchor="start" x="2179.96" y="-816.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">uuid</text>
|
||||||
<polygon fill="none" stroke="#29235c" stroke-width="2" points="1916.93,-1411.1 1916.93,-1533.1 2251.93,-1533.1 2251.93,-1411.1 1916.93,-1411.1"/>
|
<polygon fill="none" stroke="#29235c" stroke-width="2" points="1916.93,-794.1 1916.93,-916.1 2251.93,-916.1 2251.93,-794.1 1916.93,-794.1"/>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
@ -401,28 +401,28 @@
|
|||||||
<text text-anchor="start" x="1521.09" y="-3114.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">uuid</text>
|
<text text-anchor="start" x="1521.09" y="-3114.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">uuid</text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1098.56,-3033.1 1098.56,-3093.1 1592.56,-3093.1 1592.56,-3033.1 1098.56,-3033.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1098.56,-3033.1 1098.56,-3093.1 1592.56,-3093.1 1592.56,-3033.1 1098.56,-3033.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1098.56,-3033.1 1098.56,-3093.1 1592.56,-3093.1 1592.56,-3033.1 1098.56,-3033.1"/>
|
<polygon fill="none" stroke="#29235c" points="1098.56,-3033.1 1098.56,-3093.1 1592.56,-3093.1 1592.56,-3033.1 1098.56,-3033.1"/>
|
||||||
<text text-anchor="start" x="1109.56" y="-3053.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">is_scan    </text>
|
<text text-anchor="start" x="1109.29" y="-3053.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">current_recognition_job_id    </text>
|
||||||
<text text-anchor="start" x="1467.73" y="-3054.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">boolean</text>
|
<text text-anchor="start" x="1521.33" y="-3054.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">uuid</text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1098.56,-2973.1 1098.56,-3033.1 1592.56,-3033.1 1592.56,-2973.1 1098.56,-2973.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1098.56,-2973.1 1098.56,-3033.1 1592.56,-3033.1 1592.56,-2973.1 1098.56,-2973.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1098.56,-2973.1 1098.56,-3033.1 1592.56,-3033.1 1592.56,-2973.1 1098.56,-2973.1"/>
|
<polygon fill="none" stroke="#29235c" points="1098.56,-2973.1 1098.56,-3033.1 1592.56,-3033.1 1592.56,-2973.1 1098.56,-2973.1"/>
|
||||||
<text text-anchor="start" x="1109.29" y="-2993.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">current_recognition_job_id    </text>
|
<text text-anchor="start" x="1109.56" y="-2993.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">uploaded_by    </text>
|
||||||
<text text-anchor="start" x="1521.33" y="-2994.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">uuid</text>
|
<text text-anchor="start" x="1521.09" y="-2994.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">uuid</text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1098.56,-2913.1 1098.56,-2973.1 1592.56,-2973.1 1592.56,-2913.1 1098.56,-2913.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1098.56,-2913.1 1098.56,-2973.1 1592.56,-2973.1 1592.56,-2913.1 1098.56,-2913.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1098.56,-2913.1 1098.56,-2973.1 1592.56,-2973.1 1592.56,-2913.1 1098.56,-2913.1"/>
|
<polygon fill="none" stroke="#29235c" points="1098.56,-2913.1 1098.56,-2973.1 1592.56,-2973.1 1592.56,-2913.1 1098.56,-2913.1"/>
|
||||||
<text text-anchor="start" x="1109.56" y="-2933.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">uploaded_by    </text>
|
<text text-anchor="start" x="1109.56" y="-2933.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">uploaded_at    </text>
|
||||||
<text text-anchor="start" x="1521.09" y="-2934.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">uuid</text>
|
<text text-anchor="start" x="1409.11" y="-2934.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">timestamptz</text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1098.56,-2853.1 1098.56,-2913.1 1592.56,-2913.1 1592.56,-2853.1 1098.56,-2853.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1098.56,-2853.1 1098.56,-2913.1 1592.56,-2913.1 1592.56,-2853.1 1098.56,-2853.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1098.56,-2853.1 1098.56,-2913.1 1592.56,-2913.1 1592.56,-2853.1 1098.56,-2853.1"/>
|
<polygon fill="none" stroke="#29235c" points="1098.56,-2853.1 1098.56,-2913.1 1592.56,-2913.1 1592.56,-2853.1 1098.56,-2853.1"/>
|
||||||
<text text-anchor="start" x="1109.56" y="-2873.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">uploaded_at    </text>
|
<text text-anchor="start" x="1109.56" y="-2873.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">updated_at    </text>
|
||||||
<text text-anchor="start" x="1409.11" y="-2874.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">timestamptz</text>
|
<text text-anchor="start" x="1409.11" y="-2874.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">timestamptz</text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1098.56,-2793.1 1098.56,-2853.1 1592.56,-2853.1 1592.56,-2793.1 1098.56,-2793.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1098.56,-2793.1 1098.56,-2853.1 1592.56,-2853.1 1592.56,-2793.1 1098.56,-2793.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1098.56,-2793.1 1098.56,-2853.1 1592.56,-2853.1 1592.56,-2793.1 1098.56,-2793.1"/>
|
<polygon fill="none" stroke="#29235c" points="1098.56,-2793.1 1098.56,-2853.1 1592.56,-2853.1 1592.56,-2793.1 1098.56,-2793.1"/>
|
||||||
<text text-anchor="start" x="1109.56" y="-2813.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">updated_at    </text>
|
<text text-anchor="start" x="1109.56" y="-2813.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">consolidation_id    </text>
|
||||||
<text text-anchor="start" x="1409.11" y="-2814.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">timestamptz</text>
|
<text text-anchor="start" x="1521.09" y="-2814.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">uuid</text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1098.56,-2733.1 1098.56,-2793.1 1592.56,-2793.1 1592.56,-2733.1 1098.56,-2733.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1098.56,-2733.1 1098.56,-2793.1 1592.56,-2793.1 1592.56,-2733.1 1098.56,-2733.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1098.56,-2733.1 1098.56,-2793.1 1592.56,-2793.1 1592.56,-2733.1 1098.56,-2733.1"/>
|
<polygon fill="none" stroke="#29235c" points="1098.56,-2733.1 1098.56,-2793.1 1592.56,-2793.1 1592.56,-2733.1 1098.56,-2733.1"/>
|
||||||
<text text-anchor="start" x="1109.56" y="-2753.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">consolidation_id    </text>
|
<text text-anchor="start" x="1109.56" y="-2753.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">is_scan    </text>
|
||||||
<text text-anchor="start" x="1521.09" y="-2754.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">uuid</text>
|
<text text-anchor="start" x="1467.73" y="-2754.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">boolean</text>
|
||||||
<polygon fill="none" stroke="#29235c" stroke-width="2" points="1097.56,-2732.1 1097.56,-3754.1 1593.56,-3754.1 1593.56,-2732.1 1097.56,-2732.1"/>
|
<polygon fill="none" stroke="#29235c" stroke-width="2" points="1097.56,-2732.1 1097.56,-3754.1 1593.56,-3754.1 1593.56,-2732.1 1097.56,-2732.1"/>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
@ -430,7 +430,7 @@
|
|||||||
<!-- stored_file->file_type -->
|
<!-- stored_file->file_type -->
|
||||||
<g id="edge28" class="edge">
|
<g id="edge28" class="edge">
|
||||||
<title>stored_file:e->file_type:w</title>
|
<title>stored_file:e->file_type:w</title>
|
||||||
<path fill="none" stroke="#29235c" stroke-width="3" d="M1593.56,-3543.1C1839.98,-3543.1 1681.96,-2685.02 1697.7,-2439.1 1701.48,-2380.08 1703.47,-1425.94 1733.7,-1375.1 1791.08,-1278.63 1839.18,-1247.1 1951.43,-1247.1"/>
|
<path fill="none" stroke="#29235c" stroke-width="3" d="M1593.56,-3543.1C1839.98,-3543.1 1681.04,-2684.96 1697.7,-2439.1 1704.25,-2342.46 1683.88,-1651.17 1733.7,-1568.1 1791.44,-1471.84 1839.18,-1440.1 1951.43,-1440.1"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- stored_file->file_status -->
|
<!-- stored_file->file_status -->
|
||||||
<g id="edge29" class="edge">
|
<g id="edge29" class="edge">
|
||||||
@ -441,19 +441,19 @@
|
|||||||
<!-- stored_file->app_user -->
|
<!-- stored_file->app_user -->
|
||||||
<g id="edge10" class="edge">
|
<g id="edge10" class="edge">
|
||||||
<title>stored_file:e->app_user:w</title>
|
<title>stored_file:e->app_user:w</title>
|
||||||
<path fill="none" stroke="#29235c" stroke-width="3" d="M1593.56,-2943.1C1822.29,-2943.1 1672.62,-2666.46 1697.7,-2439.1 1704.56,-2376.94 1702.51,-242.3 1733.7,-188.1 1786.54,-96.29 1832.14,-63.18 1934.36,-61.2"/>
|
<path fill="none" stroke="#29235c" stroke-width="3" d="M1593.56,-3003.1C1848.47,-3003.1 1672.43,-2692.75 1697.7,-2439.1 1703.9,-2376.88 1702.51,-242.3 1733.7,-188.1 1786.54,-96.29 1832.14,-63.18 1934.36,-61.2"/>
|
||||||
<polygon fill="#29235c" stroke="#29235c" stroke-width="3" points="1934.46,-64.7 1944.43,-61.1 1934.39,-57.7 1934.46,-64.7"/>
|
<polygon fill="#29235c" stroke="#29235c" stroke-width="3" points="1934.46,-64.7 1944.43,-61.1 1934.39,-57.7 1934.46,-64.7"/>
|
||||||
<text text-anchor="middle" x="1935.53" y="-32.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">1</text>
|
<text text-anchor="middle" x="1935.53" y="-32.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">1</text>
|
||||||
<text text-anchor="middle" x="1587.34" y="-2952.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">*</text>
|
<text text-anchor="middle" x="1587.34" y="-3012.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">*</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- stored_file->consolidation -->
|
<!-- stored_file->consolidation -->
|
||||||
<!-- stored_file->consolidation -->
|
<!-- stored_file->consolidation -->
|
||||||
<g id="edge12" class="edge">
|
<g id="edge12" class="edge">
|
||||||
<title>stored_file:e->consolidation:w</title>
|
<title>stored_file:e->consolidation:w</title>
|
||||||
<path fill="none" stroke="#29235c" stroke-width="3" d="M1593.56,-2763.1C1744.82,-2763.1 1671.2,-2588.02 1697.7,-2439.1 1714.67,-2343.74 1686.8,-1652.85 1733.7,-1568.1 1779.96,-1484.52 1815.81,-1444.93 1907.21,-1442.25"/>
|
<path fill="none" stroke="#29235c" stroke-width="3" d="M1593.56,-2823.1C1770.39,-2823.1 1672.24,-2614.09 1697.7,-2439.1 1709.61,-2357.27 1694.28,-1023.79 1733.7,-951.1 1779.24,-867.13 1815.76,-827.9 1907.21,-825.25"/>
|
||||||
<polygon fill="#29235c" stroke="#29235c" stroke-width="3" points="1907.48,-1445.75 1917.43,-1442.1 1907.38,-1438.75 1907.48,-1445.75"/>
|
<polygon fill="#29235c" stroke="#29235c" stroke-width="3" points="1907.48,-828.74 1917.43,-825.1 1907.38,-821.75 1907.48,-828.74"/>
|
||||||
<text text-anchor="middle" x="1908.53" y="-1451.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">1</text>
|
<text text-anchor="middle" x="1908.53" y="-834.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">1</text>
|
||||||
<text text-anchor="middle" x="1587.34" y="-2772.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">*</text>
|
<text text-anchor="middle" x="1587.34" y="-2832.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">*</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- stored_file->legal_entity -->
|
<!-- stored_file->legal_entity -->
|
||||||
<!-- stored_file->legal_entity -->
|
<!-- stored_file->legal_entity -->
|
||||||
@ -468,8 +468,8 @@
|
|||||||
<!-- stored_file->s3_object -->
|
<!-- stored_file->s3_object -->
|
||||||
<g id="edge4" class="edge">
|
<g id="edge4" class="edge">
|
||||||
<title>stored_file:e->s3_object:w</title>
|
<title>stored_file:e->s3_object:w</title>
|
||||||
<path fill="none" stroke="#29235c" stroke-width="3" d="M1593.56,-3423.1C1813.45,-3423.1 1683.76,-2658.55 1697.7,-2439.1 1700.66,-2392.49 1700.32,-790.77 1733.7,-758.1 1761.55,-730.84 2406.95,-731.2 2435.15,-758.1 2666.44,-978.76 2257.79,-3605.77 2561.82,-3662.18"/>
|
<path fill="none" stroke="#29235c" stroke-width="3" d="M1593.56,-3423.1C1813.45,-3423.1 1683.76,-2658.55 1697.7,-2439.1 1700.66,-2392.49 1700.32,-790.77 1733.7,-758.1 1761.55,-730.84 2407.35,-730.79 2435.15,-758.1 2475.62,-797.86 2467.35,-2743.5 2471.15,-2800.1 2483.84,-2989.27 2382.66,-3639.04 2561.8,-3662.45"/>
|
||||||
<polygon fill="#29235c" stroke="#29235c" stroke-width="3" points="2561.7,-3665.68 2571.98,-3663.1 2562.33,-3658.71 2561.7,-3665.68"/>
|
<polygon fill="#29235c" stroke="#29235c" stroke-width="3" points="2561.77,-3665.96 2571.98,-3663.1 2562.22,-3658.97 2561.77,-3665.96"/>
|
||||||
<text text-anchor="middle" x="2580.87" y="-3672.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">1</text>
|
<text text-anchor="middle" x="2580.87" y="-3672.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">1</text>
|
||||||
<text text-anchor="middle" x="1587.34" y="-3432.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">*</text>
|
<text text-anchor="middle" x="1587.34" y="-3432.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">*</text>
|
||||||
</g>
|
</g>
|
||||||
@ -591,36 +591,36 @@
|
|||||||
<text text-anchor="start" x="2258.96" y="-2454.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">uuid</text>
|
<text text-anchor="start" x="2258.96" y="-2454.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">uuid</text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1838.43,-2373.1 1838.43,-2433.1 2330.43,-2433.1 2330.43,-2373.1 1838.43,-2373.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1838.43,-2373.1 1838.43,-2433.1 2330.43,-2433.1 2330.43,-2373.1 1838.43,-2373.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1838.43,-2373.1 1838.43,-2433.1 2330.43,-2433.1 2330.43,-2373.1 1838.43,-2373.1"/>
|
<polygon fill="none" stroke="#29235c" points="1838.43,-2373.1 1838.43,-2433.1 2330.43,-2433.1 2330.43,-2373.1 1838.43,-2373.1"/>
|
||||||
<text text-anchor="start" x="1849.43" y="-2393.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">raw_s3_object_id    </text>
|
<text text-anchor="start" x="1849.17" y="-2393.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">result_schema_version    </text>
|
||||||
<text text-anchor="start" x="2258.96" y="-2394.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">uuid</text>
|
<text text-anchor="start" x="2213.09" y="-2394.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">varchar</text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1838.43,-2313.1 1838.43,-2373.1 2330.43,-2373.1 2330.43,-2313.1 1838.43,-2313.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1838.43,-2313.1 1838.43,-2373.1 2330.43,-2373.1 2330.43,-2313.1 1838.43,-2313.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1838.43,-2313.1 1838.43,-2373.1 2330.43,-2373.1 2330.43,-2313.1 1838.43,-2313.1"/>
|
<polygon fill="none" stroke="#29235c" points="1838.43,-2313.1 1838.43,-2373.1 2330.43,-2373.1 2330.43,-2313.1 1838.43,-2313.1"/>
|
||||||
<text text-anchor="start" x="1849.17" y="-2333.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">result_schema_version    </text>
|
<text text-anchor="start" x="1849.43" y="-2333.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">group_schema    </text>
|
||||||
<text text-anchor="start" x="2213.09" y="-2334.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">varchar</text>
|
<text text-anchor="start" x="2242.96" y="-2334.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">jsonb</text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1838.43,-2253.1 1838.43,-2313.1 2330.43,-2313.1 2330.43,-2253.1 1838.43,-2253.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1838.43,-2253.1 1838.43,-2313.1 2330.43,-2313.1 2330.43,-2253.1 1838.43,-2253.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1838.43,-2253.1 1838.43,-2313.1 2330.43,-2313.1 2330.43,-2253.1 1838.43,-2253.1"/>
|
<polygon fill="none" stroke="#29235c" points="1838.43,-2253.1 1838.43,-2313.1 2330.43,-2313.1 2330.43,-2253.1 1838.43,-2253.1"/>
|
||||||
<text text-anchor="start" x="1849.43" y="-2273.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">group_schema    </text>
|
<text text-anchor="start" x="1849.43" y="-2273.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">metrics    </text>
|
||||||
<text text-anchor="start" x="2242.96" y="-2274.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">jsonb</text>
|
<text text-anchor="start" x="2242.96" y="-2274.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">jsonb</text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1838.43,-2193.1 1838.43,-2253.1 2330.43,-2253.1 2330.43,-2193.1 1838.43,-2193.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1838.43,-2193.1 1838.43,-2253.1 2330.43,-2253.1 2330.43,-2193.1 1838.43,-2193.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1838.43,-2193.1 1838.43,-2253.1 2330.43,-2253.1 2330.43,-2193.1 1838.43,-2193.1"/>
|
<polygon fill="none" stroke="#29235c" points="1838.43,-2193.1 1838.43,-2253.1 2330.43,-2253.1 2330.43,-2193.1 1838.43,-2193.1"/>
|
||||||
<text text-anchor="start" x="1849.43" y="-2213.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">metrics    </text>
|
<text text-anchor="start" x="1849.43" y="-2213.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">fields_total    </text>
|
||||||
<text text-anchor="start" x="2242.96" y="-2214.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">jsonb</text>
|
<text text-anchor="start" x="2285.64" y="-2214.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">int</text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1838.43,-2133.1 1838.43,-2193.1 2330.43,-2193.1 2330.43,-2133.1 1838.43,-2133.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1838.43,-2133.1 1838.43,-2193.1 2330.43,-2193.1 2330.43,-2133.1 1838.43,-2133.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1838.43,-2133.1 1838.43,-2193.1 2330.43,-2193.1 2330.43,-2133.1 1838.43,-2133.1"/>
|
<polygon fill="none" stroke="#29235c" points="1838.43,-2133.1 1838.43,-2193.1 2330.43,-2193.1 2330.43,-2133.1 1838.43,-2133.1"/>
|
||||||
<text text-anchor="start" x="1849.43" y="-2153.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">fields_total    </text>
|
<text text-anchor="start" x="1849.43" y="-2153.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">fields_low_confidence    </text>
|
||||||
<text text-anchor="start" x="2285.64" y="-2154.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">int</text>
|
<text text-anchor="start" x="2285.64" y="-2154.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">int</text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1838.43,-2073.1 1838.43,-2133.1 2330.43,-2133.1 2330.43,-2073.1 1838.43,-2073.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1838.43,-2073.1 1838.43,-2133.1 2330.43,-2133.1 2330.43,-2073.1 1838.43,-2073.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1838.43,-2073.1 1838.43,-2133.1 2330.43,-2133.1 2330.43,-2073.1 1838.43,-2073.1"/>
|
<polygon fill="none" stroke="#29235c" points="1838.43,-2073.1 1838.43,-2133.1 2330.43,-2133.1 2330.43,-2073.1 1838.43,-2073.1"/>
|
||||||
<text text-anchor="start" x="1849.43" y="-2093.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">fields_low_confidence    </text>
|
<text text-anchor="start" x="1849.43" y="-2093.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">fields_unrecognized    </text>
|
||||||
<text text-anchor="start" x="2285.64" y="-2094.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">int</text>
|
<text text-anchor="start" x="2285.64" y="-2094.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">int</text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1838.43,-2013.1 1838.43,-2073.1 2330.43,-2073.1 2330.43,-2013.1 1838.43,-2013.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1838.43,-2013.1 1838.43,-2073.1 2330.43,-2073.1 2330.43,-2013.1 1838.43,-2013.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1838.43,-2013.1 1838.43,-2073.1 2330.43,-2073.1 2330.43,-2013.1 1838.43,-2013.1"/>
|
<polygon fill="none" stroke="#29235c" points="1838.43,-2013.1 1838.43,-2073.1 2330.43,-2073.1 2330.43,-2013.1 1838.43,-2013.1"/>
|
||||||
<text text-anchor="start" x="1849.43" y="-2033.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">fields_unrecognized    </text>
|
<text text-anchor="start" x="1849.43" y="-2033.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">statements_version    </text>
|
||||||
<text text-anchor="start" x="2285.64" y="-2034.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">int</text>
|
<text text-anchor="start" x="2212.75" y="-2034.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">varchar</text>
|
||||||
<polygon fill="#e7e2dd" stroke="transparent" points="1838.43,-1953.1 1838.43,-2013.1 2330.43,-2013.1 2330.43,-1953.1 1838.43,-1953.1"/>
|
<polygon fill="#e7e2dd" stroke="transparent" points="1838.43,-1953.1 1838.43,-2013.1 2330.43,-2013.1 2330.43,-1953.1 1838.43,-1953.1"/>
|
||||||
<polygon fill="none" stroke="#29235c" points="1838.43,-1953.1 1838.43,-2013.1 2330.43,-2013.1 2330.43,-1953.1 1838.43,-1953.1"/>
|
<polygon fill="none" stroke="#29235c" points="1838.43,-1953.1 1838.43,-2013.1 2330.43,-2013.1 2330.43,-1953.1 1838.43,-1953.1"/>
|
||||||
<text text-anchor="start" x="1849.43" y="-1973.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">statements_version    </text>
|
<text text-anchor="start" x="1849.43" y="-1973.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">raw_s3_object_id    </text>
|
||||||
<text text-anchor="start" x="2212.75" y="-1974.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">varchar</text>
|
<text text-anchor="start" x="2258.96" y="-1974.3" font-family="Helvetica,sans-Serif" font-style="italic" font-size="32.00" fill="#29235c">uuid</text>
|
||||||
<polygon fill="none" stroke="#29235c" stroke-width="2" points="1837.43,-1952.1 1837.43,-3754.1 2331.43,-3754.1 2331.43,-1952.1 1837.43,-1952.1"/>
|
<polygon fill="none" stroke="#29235c" stroke-width="2" points="1837.43,-1952.1 1837.43,-3754.1 2331.43,-3754.1 2331.43,-1952.1 1837.43,-1952.1"/>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
@ -629,10 +629,10 @@
|
|||||||
<!-- stored_file->recognition_job -->
|
<!-- stored_file->recognition_job -->
|
||||||
<g id="edge8" class="edge">
|
<g id="edge8" class="edge">
|
||||||
<title>stored_file:e->recognition_job:w</title>
|
<title>stored_file:e->recognition_job:w</title>
|
||||||
<path fill="none" stroke="#29235c" stroke-width="3" d="M1593.56,-3003.1C1902.77,-3003.1 1533.19,-3648.36 1827.15,-3662.86"/>
|
<path fill="none" stroke="#29235c" stroke-width="3" d="M1593.56,-3063.1C1877.9,-3063.1 1557.58,-3648.54 1827.16,-3662.84"/>
|
||||||
<polygon fill="#29235c" stroke="#29235c" stroke-width="3" points="1827.34,-3666.36 1837.43,-3663.1 1827.51,-3659.36 1827.34,-3666.36"/>
|
<polygon fill="#29235c" stroke="#29235c" stroke-width="3" points="1827.34,-3666.34 1837.43,-3663.1 1827.52,-3659.35 1827.34,-3666.34"/>
|
||||||
<text text-anchor="middle" x="1828.53" y="-3672.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">1</text>
|
<text text-anchor="middle" x="1828.53" y="-3672.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">1</text>
|
||||||
<text text-anchor="middle" x="1587.34" y="-3012.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">*</text>
|
<text text-anchor="middle" x="1587.34" y="-3072.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">*</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- document -->
|
<!-- document -->
|
||||||
<g id="document" class="node">
|
<g id="document" class="node">
|
||||||
@ -811,19 +811,19 @@
|
|||||||
<!-- recognition_job->recognition_pipeline -->
|
<!-- recognition_job->recognition_pipeline -->
|
||||||
<g id="edge35" class="edge">
|
<g id="edge35" class="edge">
|
||||||
<title>recognition_job:e->recognition_pipeline:w</title>
|
<title>recognition_job:e->recognition_pipeline:w</title>
|
||||||
<path fill="none" stroke="#29235c" stroke-width="3" d="M2331.43,-3543.1C2641.49,-3543.1 2285.91,-4913.1 2595.98,-4913.1"/>
|
<path fill="none" stroke="#29235c" stroke-width="3" d="M2331.43,-3543.1C2615.56,-3543.1 2311.84,-4125.1 2595.98,-4125.1"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- recognition_job->recognition_status -->
|
<!-- recognition_job->recognition_status -->
|
||||||
<g id="edge36" class="edge">
|
<g id="edge36" class="edge">
|
||||||
<title>recognition_job:e->recognition_status:w</title>
|
<title>recognition_job:e->recognition_status:w</title>
|
||||||
<path fill="none" stroke="#29235c" stroke-width="3" d="M2331.43,-3123.1C2512.55,-3123.1 2436.51,-3748.32 2471.15,-3926.1 2526.28,-4209.05 2319.71,-4560.1 2607.98,-4560.1"/>
|
<path fill="none" stroke="#29235c" stroke-width="3" d="M2331.43,-3123.1C2487.84,-3123.1 2387.1,-2932.01 2471.15,-2800.1 2520.35,-2722.89 2516.42,-2646.1 2607.98,-2646.1"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- recognition_job->s3_object -->
|
<!-- recognition_job->s3_object -->
|
||||||
<!-- recognition_job->s3_object -->
|
<!-- recognition_job->s3_object -->
|
||||||
<g id="edge24" class="edge">
|
<g id="edge24" class="edge">
|
||||||
<title>recognition_job:e->s3_object:w</title>
|
<title>recognition_job:e->s3_object:w</title>
|
||||||
<path fill="none" stroke="#29235c" stroke-width="3" d="M2331.43,-2463.1C2871.92,-2463.1 2038.73,-3647.92 2561.79,-3662.96"/>
|
<path fill="none" stroke="#29235c" stroke-width="3" d="M2331.43,-2463.1C2599.94,-2463.1 2307.62,-3632.83 2561.89,-3662.53"/>
|
||||||
<polygon fill="#29235c" stroke="#29235c" stroke-width="3" points="2561.93,-3666.46 2571.98,-3663.1 2562.03,-3659.46 2561.93,-3666.46"/>
|
<polygon fill="#29235c" stroke="#29235c" stroke-width="3" points="2561.79,-3666.03 2571.98,-3663.1 2562.19,-3659.04 2561.79,-3666.03"/>
|
||||||
<text text-anchor="middle" x="2580.87" y="-3634.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">1</text>
|
<text text-anchor="middle" x="2580.87" y="-3634.3" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">1</text>
|
||||||
<text text-anchor="middle" x="2325.2" y="-2472.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">*</text>
|
<text text-anchor="middle" x="2325.2" y="-2472.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">*</text>
|
||||||
</g>
|
</g>
|
||||||
@ -831,10 +831,10 @@
|
|||||||
<!-- recognition_job->s3_object -->
|
<!-- recognition_job->s3_object -->
|
||||||
<g id="edge26" class="edge">
|
<g id="edge26" class="edge">
|
||||||
<title>recognition_job:e->s3_object:w</title>
|
<title>recognition_job:e->s3_object:w</title>
|
||||||
<path fill="none" stroke="#29235c" stroke-width="3" d="M2331.43,-2403.1C2898.06,-2403.1 2012.79,-3647.77 2561.7,-3662.96"/>
|
<path fill="none" stroke="#29235c" stroke-width="3" d="M2331.43,-1983.1C2516.59,-1983.1 2388.24,-3602.95 2562.07,-3661.48"/>
|
||||||
<polygon fill="#29235c" stroke="#29235c" stroke-width="3" points="2561.93,-3666.47 2571.98,-3663.1 2562.03,-3659.47 2561.93,-3666.47"/>
|
<polygon fill="#29235c" stroke="#29235c" stroke-width="3" points="2561.54,-3664.94 2571.98,-3663.1 2562.67,-3658.03 2561.54,-3664.94"/>
|
||||||
<text text-anchor="middle" x="2563.08" y="-3672.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">1</text>
|
<text text-anchor="middle" x="2563.08" y="-3672.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">1</text>
|
||||||
<text text-anchor="middle" x="2325.2" y="-2412.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">*</text>
|
<text text-anchor="middle" x="2325.2" y="-1992.7" font-family="Helvetica,sans-Serif" font-size="32.00" fill="#29235c">*</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- recognition_job->stored_file -->
|
<!-- recognition_job->stored_file -->
|
||||||
<!-- recognition_job->stored_file -->
|
<!-- recognition_job->stored_file -->
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 737 KiB After Width: | Height: | Size: 743 KiB |
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 108 KiB |
301
model/entities-v5.27.md
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
# АРМ КА — описание сущностей модели данных v5.27
|
||||||
|
|
||||||
|
Источник истины по структуре — `data-model-v5.27.dbml` (полный). Диаграммы по частям — `diagrams/` (part01…10 svg/png; перерисовываются `make diagrams` из текущего DBML). Здесь — что каждая таблица значит для бизнеса, как связана с соседями и откуда взялась.
|
||||||
|
|
||||||
|
## Что изменилось в v5.27 (KFO: ОФР и хранение; arm-core PR #251, миграция `0014_dbml_v5_27` после `0013_dbml_v5_26`)
|
||||||
|
|
||||||
|
| № | Изменение | Решение |
|
||||||
|
|---|---|---|
|
||||||
|
| 1 | `vgo_assignment.side` (D/K) | Разнесение ОФР по позициям «строка ОСВ + сторона» (DOC-277424 §3.4): `NULL` для ББ, `D`/`K` для ОФР. Уникальность: ББ — версия/тип/строка, ОФР — версия/тип/строка/сторона. Старые назначения ASSIGN переносятся по счетам правил, неоднозначные блокируют миграцию; UNASSIGNED переносится на D и K. Это отменяет пункт 2 v5.24 «поле `side` не добавлено» только для ОФР |
|
||||||
|
| 2 | `kfo_result.snapshot` не вводится | Незамороженный результат КФО не хранится (решение владельца 13.11.2026, OQ-192): каждый GET считает по текущим данным. До заморозки сохраняются только ручные поля: обоснование порога (`kfo_result`), отклонения от Методики (`consolidation_version`) и строки `kfo_result_line` лишь с комментарием (`consolidated_amount = 0`, суммы пусты, строк компаний нет). Полный снимок пишет переход версии в «Верифицирован», в одной транзакции с `is_frozen = true`; миграция удаляет прежний расчётный кэш незамороженных таблиц, замороженные суммы не меняются |
|
||||||
|
| 3 | `correction.ordinal` не вводится | Основная строка корректировки задаётся `parent_correction_id`, дополнительные упорядочены по ID; порядок ввода не хранится |
|
||||||
|
|
||||||
|
`GET …/kfo/state` и поле `data_changed` не вводятся: при пересчёте на каждом чтении отдельного состояния «расчёт неактуален» нет. Остальные таблицы и enum — как в v5.26.
|
||||||
|
|
||||||
|
## Что изменилось в v5.26 (расчёт КФО, AURORA-1546/1547; RSHB/arm-ka-docs#206; миграция — в AURORA-1546)
|
||||||
|
|
||||||
|
| № | Изменение | Решение |
|
||||||
|
|---|---|---|
|
||||||
|
| 1 | `kfo_result_line_company` + `client_amount`, `vgo_amount` | «По данным клиента» и «в т. ч. взаимные» по компании (тыс. руб.); `amount` — «очищенные» = `client_amount − vgo_amount`. Без них колонки экрана КФО `[31-04]` из сохранённого результата не восстановить. Разреза «расхождение по компании» нет: на экране «Расхождения» — общая колонка строки |
|
||||||
|
| 2 | `kfo_result` + `warnings`, `corrections_count_bb/_ofr`, `corrections_amount_bb/_ofr` | Предупреждения расчёта и сводка корректировок для реквизитов формы хранятся с результатом: замороженная версия отдаёт то, что видели при верификации (`context/05-domain-rules.md` §8 «КФО» п. 11–12) |
|
||||||
|
| 3 | `audit_action` + `KFO_EDIT` | Сохранение ручных полей КФО (комментарии строк, обоснование порога, причины отклонений от Методики) — раздел `KFO`; подходящего действия не было |
|
||||||
|
| 4 | `elimination_rule.elimination_mode` — значение `min_or_full` | Правило ББ 2 по DOC-274230: `min` при обеих сторонах, сторона 1 при пустой стороне 2, без порога 5 %; строки ДО — каскадом 1310 → 1350 → 1370. Поле varchar — схема не меняется; seed v1 правится на месте в AURORA-1546 |
|
||||||
|
| 5 | Пояснения `kfo_result_line`, `kfo_result` | Приведены к §8 «КФО»: всё в тыс. руб.; корректировка агрегата заменяет его автосумму (`eliminated_auto` и `eliminated_manual` по одному агрегату не складываются); `GOODWILL` — служебная строка раздела I, входит в 1100/1600 |
|
||||||
|
| 6 | `ex_snapshot_item.item_type` + `version_card`; payload — по `contracts/ex-payload-v1.schema.json` | Карточка версии (участники маршрута с ФИО, решение УОБ, обоснования, состав) — элементом среза, а не колонками `ex_snapshot`: версия КФО удаляется раньше среза, а схему таблицы не трогаем. Схема payload — конверт и данные по каждому типу (`context/05-domain-rules.md` §15; docs #208) |
|
||||||
|
| 7 | `audit_action` + `EX_SNAPSHOT_WRITE` | Запись среза при «Верифицирован» — раздел `KFO` (раздела `EX` нет) |
|
||||||
|
| 8 | Пояснение `ex_snapshot.status` | Архив прежнего среза ручной (решение 27.10.2026): `ACTUAL` — «не архивирован», а не «последняя верифицированная» |
|
||||||
|
|
||||||
|
Остальные таблицы и enum — как в v5.25.
|
||||||
|
|
||||||
|
## Что изменилось в v5.25 (AURORA-1759; RSHB/arm-ka-docs#202; миграция — отдельный change arm-core#190)
|
||||||
|
|
||||||
|
| № | Изменение | Решение |
|
||||||
|
|---|---|---|
|
||||||
|
| 1 | Три новые таблицы `quality_intake_fact`, `quality_outcome_fact`, `quality_failure_fact` | Append-only факты качества распознавания первички (документ «как распознано», его исход, технический отказ задания), без FK на рабочие таблицы — переживают удаление/перераспознавание. Полное WHY и решения владельца — `../arm-core/openspec/changes/quality-metrics/design.md` §1-3, §10; состав столбцов — `openspec/changes/quality-metrics/design.md` §1.4-1.6 этого репозитория. Часть 10 ниже |
|
||||||
|
| 2 | `s3_bucket_role.raw` | Сырой ответ ИС Сканирование (`raw/{job_id}.json`) теперь регистрируется в `s3_object`; не экспирится с удалением файла — вход для будущего эталонного прогона перенормализации |
|
||||||
|
| 3 | `stored_file.is_scan` | Признак скан/цифровой PDF по текстовому слою при загрузке; NULL для не-PDF |
|
||||||
|
| 4 | `recognition_job.raw_s3_object_id` | Ссылка на зарегистрированный сырой ответ (image pipeline) — отменяет решение v5.13 «сырой ответ в БД не регистрируется» |
|
||||||
|
| 5 | `permission_object.QUALITY_METRICS` | Объект права экрана «Качество первички» (действие `VIEW`); право `QUALITY_METRICS_VIEW` — seed в arm-core, не в DBML |
|
||||||
|
|
||||||
|
Остальные таблицы и enum — как в v5.24.
|
||||||
|
|
||||||
|
## Что изменилось в v5.24 (AURORA-1751/1540/1541; RSHB/arm-ka-docs#196; миграция уже слита в arm-core main)
|
||||||
|
|
||||||
|
| № | Изменение | Решение |
|
||||||
|
|---|---|---|
|
||||||
|
| 1 | Новая таблица `vgo_assignment` | Ручное решение аналитика по строке сводной ОСВ сверх автоматического разнесения по правилам ВГО (`context/05-domain-rules.md` §5): привязка к правилу, снятие привязки, «не учитывать в КФО» у нераспределённой строки. Само разнесение остаётся чистой функцией и не хранится (DECISION-5) — таблица только перекрывает его решением аналитика. Одна действующая запись на строку ОСВ в версии и типе отчётности |
|
||||||
|
| 2 | Поле `side` не добавлено | Черновик контракта (`dev/api-contract-corrections.md` §5) предполагал отдельную позицию для строки с одновременно дебетовым и кредитовым сальдо; в уже слитой миграции 0011 решение одно на обе позиции строки, не по стороне |
|
||||||
|
|
||||||
|
Остальные таблицы и enum — как в v5.23.
|
||||||
|
|
||||||
|
## Что изменилось в 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`. Замена — файл целиком со всеми документами. **v5.25:** `is_scan` — скан/цифровой PDF по текстовому слою при загрузке. | → `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` — версия копии общего кода нормализации, которой посчитан результат форм. **v5.25:** сырой ответ ИС Сканирование теперь регистрируется в `s3_object` (роль `raw`) через `raw_s3_object_id` — решение v5.13 «не регистрируется» отменено. | → `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 |
|
||||||
|
| `vgo_assignment` | Ручное решение аналитика по строке сводной ОСВ сверх автоматического разнесения по правилам ВГО: привязка к правилу / снятие привязки, «не учитывать в КФО» у нераспределённой строки; для ОФР — по стороне позиции (`side` D/K, v5.27). Разнесение само по себе не хранится — только это решение поверх него. | → `consolidation_version`, `osv_entry` (ON DELETE CASCADE), `elimination_rule`, `app_user` ×2 | DOC-272613 §5, AURORA-1751 |
|
||||||
|
| `goodwill` | Строка расчёта гудвилла: головная × дочерняя, доля владения, ФВ по 58.01, УК (1310) и добавочный капитал (1350 — вопрос методологам), гудвилл, «включить в КФО», комментарий. | → `consolidation_version`, `legal_entity` ×2, `app_user` | ТЗ 6.7, Прил. 3 п.2, Прил. 8 |
|
||||||
|
| `kfo_result` | Шапка результата КФО (тыс. руб.): когда посчитан, заморожен ли, ЧА и ВБ, выручка, прибыль, расхождения, пороги, обоснование, итог гудвилла, предупреждения расчёта, сводка корректировок. Одна запись на версию; пока не заморожена — не хранит расчётные суммы (только ручные поля), таблица считается при каждом чтении; полный результат пишется при «Верифицирован» (§8 «КФО» п. 12). | → `consolidation_version` (1:1); ← `kfo_result_line` | ТЗ 6.4, 6.8, Прил. 10 |
|
||||||
|
| `kfo_result_line` | До заморозки — только строка с комментарием (суммы пусты, `consolidated_amount = 0`). Строка консолидированного ББ/ОФР по коду бланка редакции на отчётную дату (66н / ФСБУ 4/2023) и служебная `GOODWILL`: Σ по данным клиента − в т. ч. взаимные (авто или корректировка — не обе по одному агрегату) + гудвилл = КФО банка; расхождение, комментарий. | → `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 |
|
||||||
|
|
||||||
|
## Часть 10 — Метрики качества первички
|
||||||
|
|
||||||
|
| Сущность | Что это | Ключевые связи | Откуда |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `quality_intake_fact` | Документ «как распознано»: снимок на момент приёма результата (до авто/ручного подтверждения) — счётчики строк/значений/предупреждений, `payload` со строками и значениями. **Для ОСВ — без построчного снимка**: только счётчики и предупреждения `OSV_*` (правок сумм ОСВ в ядре нет). Пишется один раз на документ BALANCE/INCOME/OSV, в транзакции маппинга, до `auto_confirm`; `DISCLOSURE`/`OTHER` факт не получают. Append-only, без FK — переживает удаление/перераспознавание документа. | `document_id`/`file_id`/`job_id`/`legal_entity_id`/`group_id` — без FK, по значению | AURORA-1759; arm-core#190 |
|
||||||
|
| `quality_outcome_fact` | Исход документа: автоподтверждён / подтверждён / удалён / заменён (в т. ч. после подтверждения — отдельные значения), с атрибуцией правок по источнику (сервис / наш разбор) и причиной попадания в ячейку матрицы (`primary_cause`). **Не один факт на документ**: повторное подтверждение ОСВ и исход после подтверждения пишут новый факт — метрики берут последний по `outcome_at`. | `document_id` — связь с `quality_intake_fact` по значению, без FK | AURORA-1759; arm-core#190 |
|
||||||
|
| `quality_failure_fact` | Технический отказ задания распознавания (ошибка сервиса, таймаут, DLQ) или неповторяемая ошибка маппинга. Считается по файлам, не по документам (у отказавшего файла документов нет). Плоская таблица, без `payload`. | `job_id`/`file_id`/`legal_entity_id`/`group_id` — без FK, по значению | AURORA-1759; arm-core#190 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Как читать модель по сценарию «сформировать КФО»
|
||||||
|
|
||||||
|
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`.
|
||||||
@ -1,12 +1,12 @@
|
|||||||
schema: spec-driven
|
schema: spec-driven
|
||||||
|
|
||||||
context: |
|
context: |
|
||||||
Репозиторий arm-ka-docs — контекст, модель данных (DBML v5.26), правила домена, контракты между сервисами
|
Репозиторий arm-ka-docs — контекст, модель данных (DBML v5.27), правила домена, контракты между сервисами
|
||||||
(docs/contracts/*.schema.json), макет UI и экспорт ТЗ системы АРМ КА (ДКБ, Россельхозбанк).
|
(docs/contracts/*.schema.json), макет UI и экспорт ТЗ системы АРМ КА (ДКБ, Россельхозбанк).
|
||||||
Здесь оформляются СКВОЗНЫЕ изменения: контракт + окружение разработки (docs/dev) + проверки качества (make check) + изменения
|
Здесь оформляются СКВОЗНЫЕ изменения: контракт + окружение разработки (docs/dev) + проверки качества (make check) + изменения
|
||||||
документов контекста. Код сервисов живёт в соседних репозиториях (../arm-core, ../tabular-parser, ../scan-gateway),
|
документов контекста. Код сервисов живёт в соседних репозиториях (../arm-core, ../tabular-parser, ../scan-gateway),
|
||||||
у каждого свой openspec/ и свой change; сквозной change ссылается на них.
|
у каждого свой openspec/ и свой change; сквозной change ссылается на них.
|
||||||
Источники истины по приоритету: docs/model/data-model-v5.26.dbml → docs/model/entities-v5.26.md →
|
Источники истины по приоритету: docs/model/data-model-v5.27.dbml → docs/model/entities-v5.27.md →
|
||||||
docs/context/05-domain-rules.md → docs/source/tz (черновик, имена v4). Открытые вопросы — docs/context/07-open-questions.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.
|
план срезов — docs/context/09-delivery-plan.md; соглашения шаблона команды — docs/context/03-architecture.md.
|
||||||
Язык документов и коммитов — русский, идентификаторы — английские, как в DBML. docs/source/** не редактируется.
|
Язык документов и коммитов — русский, идентификаторы — английские, как в DBML. docs/source/** не редактируется.
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
- NATS subjects и схема ключей S3 — `../docs/context/03-architecture.md`.
|
- NATS subjects и схема ключей S3 — `../docs/context/03-architecture.md`.
|
||||||
|
|
||||||
## Правила репозитория
|
## Правила репозитория
|
||||||
- ORM 1:1 с `../docs/model/data-model-v5.26.dbml`; `scripts/check_dbml_vs_orm.py` — обязательная проверка CI.
|
- ORM 1:1 с `../docs/model/data-model-v5.27.dbml`; `scripts/check_dbml_vs_orm.py` — обязательная проверка CI.
|
||||||
- Алгоритмы — только из `../docs/context/05-domain-rules.md`; номер § — в docstring.
|
- Алгоритмы — только из `../docs/context/05-domain-rules.md`; номер § — в docstring.
|
||||||
- Вычисляемые объекты консолидации — `backend/app/domain/`, без ORM-таблиц.
|
- Вычисляемые объекты консолидации — `backend/app/domain/`, без ORM-таблиц.
|
||||||
- Фронт: пользователь слаб во фронте — для TS/React изменений делай ревью сам и объясняй решения в PR.
|
- Фронт: пользователь слаб во фронте — для TS/React изменений делай ревью сам и объясняй решения в PR.
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
"""Генерирует dev/api-contract-kfo.openapi.yaml: пути, схемы и examples из kfo_example.py (docs #206).
|
"""Схемы КФО и examples из kfo_example.py (docs #206) для gen_ex_payload.py (схема payload ЕХ).
|
||||||
|
|
||||||
uv run --with pyyaml --with jsonschema --with openapi-spec-validator python -I gen_kfo_openapi.py <out.yaml>
|
ВНИМАНИЕ: dev/api-contract-kfo.openapi.yaml этим скриптом больше не генерируется — он выгружается из app.openapi() arm-core
|
||||||
|
(`python -m scripts.export_kfo_contract`, сверка — arm-core `api/tests/test_kfo_contract.py`); схемы ниже — прежний черновик
|
||||||
|
контракта (имена KfoResultOut/KfoLineOut), используются только в gen_ex_payload.py.
|
||||||
|
|
||||||
|
Не запускать для выгрузки контракта: результат (черновик) не совпадёт с кодом.
|
||||||
"""
|
"""
|
||||||
import copy
|
import copy
|
||||||
import json
|
import json
|
||||||
|
|||||||