11 KiB
04. Как читать модель данных v5.18
Файлы: docs/model/data-model-v5.18.dbml (источник истины), docs/model/entities-v5.18.md (смысл таблиц; предыдущие
версии data-model-v5.13…v5.17.dbml и entities-v5.13…v5.17.md остаются как история),
docs/model/diagrams/part01…09.{svg,png} (диаграммы v5.18 по частям из таблицы ниже; перерисовываются из DBML командой
make diagrams в корне репозитория docs — скрипт scripts/gen_model_diagrams.py, нужен npx; при новой версии DBML
обновить DBML в Makefile, а новую таблицу — добавить в раскладку частей скрипта и в эту таблицу).
Девять частей модели
| Часть | Таблицы | Что это |
|---|---|---|
| 01 Группы и организации | regional_office, company_group(+_history), legal_entity(+_history), legal_entity_alias, related_group, related_group_member |
справочник клиентов; SCD4 для ГК/ЮЛ, SCD2 для членства |
| 02 Пользователи и права | app_user, role, permission, role_permission, user_role |
матрица прав как данные |
| 03 Бухгалтерские справочники | chart_of_account, elimination_rule, elimination_rule_account, required_document_rule |
план счетов (seed из 1С), правила элиминации Прил. 3/4 (версионируются), чек-лист по подходу |
| 04 Файлы и распознавание | s3_object, stored_file, document, recognition_job |
физический файл → задание → логические документы |
| 05 Разобранные ОСВ | osv_entry |
строка ОСВ с шестью суммами, сырым контрагентом и резолвом |
| 06 Формы ББ/ОФР | financial_statement_meta, _column, _line, _value |
шапка, колонки-даты, строки с кодами, значения с confidence |
| 07 Консолидация | consolidation, consolidation_version, _status_history, _lock, _member, _document |
логическая консолидация (ГК × период) и её версии с периметром |
| 08 Корректировки и КФО | correction, goodwill, kfo_result, kfo_result_line, kfo_result_line_company, client_kfo_line |
ручные решения и результат |
| 09 Комментарии, аудит, ЕХ | comment, audit_event, ex_snapshot, ex_snapshot_member, ex_snapshot_item |
полиморфные комментарии, append-only журнал, замороженные срезы |
v5.18: stored_file.consolidation_id — в какую консолидацию (период ГК) загружен файл; это рабочий стол консоли, общий для её версий. Что использует версия — consolidation_document.
Соглашения
- PK везде
uuid; натуральные ключи —UNIQUE(ИНН, код счёта, crm_id, код ГСК). Дляosv_entryиaudit_eventдопустима замена наbigint identityпри объёмах. - Денежные поля
numeric(18,2), процентыnumeric(7,4)/numeric(9,4), confidencenumeric(5,2)(0–100). - Временные метки
timestamptz; отчётные датыdate. - Партиальные уникальные индексы (помечены в notes):
related_group_member (legal_entity_id, kind) WHERE is_current(v5.14: ЮЛ — не более одной текущей группы каждого вида, т.е. одна ГСК и одна ГСЗ одновременно;kind— денормализацияrelated_group.kind),consolidation_lock.consolidation_version_id WHERE released_at IS NULL,document (stored_file_id, document_type, osv_account_code) NULLS NOT DISTINCT. - Enum'ы PostgreSQL — ровно как в DBML (
consolidation_status,document_status,audit_action…). Добавление значения — миграция + версия DBML. - История:
*_history— снимки предыдущего состояния (SCD4);related_group_member— версии строк (SCD2); остальное —audit_event(before_value, after_value). - Поля
*_by→app_user.id;NULL— системное действие.
Что намеренно НЕ хранится (DECISION-5) и как это вычислять
Способ сопоставления контрагента хранится (osv_entry.counterparty_match_kind, v5.16); пробелы квартальной склейки и сам свод — нет.
| Объект | Вычисление |
|---|---|
| Сводная ОСВ | osv_entry актуальных document (OSV, CONFIRMED, период версии) всех consolidation_member версии; только строки group_type = COUNTERPARTY и data_type IN (BU, SUM); строки не агрегируются |
| Признак контрагента | counterparty_id ∈ member(version) → ГСК; иначе legal_entity.company_group_id = consolidation.company_group_id → ГК; иначе Внешний |
| Пары ВГО | по elimination_rule(_account) версии правил consolidation_version.elimination_rules_version — §5 правил |
| Шахматка | агрегат пар по компаниям и выбранным наборам счетов — §6 |
| Логические проверки форм | формулы §7 по financial_statement_value |
| Чек-лист документов | required_document_rule(approach) × consolidation_member − document(CONFIRMED) |
| «Исправлено полей» | COUNT(*) WHERE is_modified |
| «Требует проверки» ячейка | confidence < порог OR NOT is_recognized |
Всё это — чистые функции от consolidation_version_id; результат кэшируется только в памяти запроса.
При VERIFIED единственный раз сериализуется в ex_snapshot_item.payload.
v4 → v5.13: таблица переименований (обязательна при чтении ТЗ)
v5.14 имена таблиц и полей не менял (добавлены related_group_member.kind и два значения audit_action), v5.15 — тоже
(добавлено значение osv_data_type.NU), v5.16 — тоже (колонка osv_entry.counterparty_match_kind), v5.17 — тоже (колонка legal_entity.kpp), v5.18 — тоже (колонка stored_file.consolidation_id), поэтому таблица справедлива и для v5.14…v5.18.
| В страницах ТЗ (модель v4 и старше) | В v5.13 / v5.14 / v5.15 / v5.16 / v5.17 / v5.18 |
|---|---|
stored_file.period_year / period_quarter / document_type / osv_account |
document.period_year / period_quarter / document_type / osv_account_code / is_cumulative |
stored_file.status «Загружен / Обработка / Требуется проверка / Ошибка» |
техника: stored_file.status UPLOADED/PROCESSING/PROCESSED/ERROR/SUPERSEDED; проверка: document.status RECOGNIZED/NEEDS_CHECK/CONFIRMED/ERROR |
stored_file.current_recognition_job_id как источник строк |
osv_entry.document_id / financial_statement_meta.document_id; current_recognition_job_id остаётся как «авторитетный прогон» файла |
osv_entry.legal_entity_id |
osv_entry.owner_legal_entity_id |
osv_entry.stored_file_id |
osv_entry.document_id (файл — через document.stored_file_id) |
osv_entry.group_schema_id → osv_group_schema / osv_grouping_schema |
osv_entry.group_type (enum) + recognition_job.group_schema jsonb |
osv_entry.counterparty_type (ГК/ГСК/Внешний) |
не хранится, вычисляется |
fin_report_header, Fin_report_rows, report_id, row_code, value_current/prior/prior2, needs_review |
financial_statement_meta / _column (period_date, is_current) / _line.line_code / _value.amount, confidence, is_recognized |
financial_statement_line.amount |
financial_statement_value.amount (строка × колонка) |
Consolidation_package, Consolidation_template, Company_data, Intercompany_reconciliation, vgo_pair_match, chess_cell, consolidated_osv_line |
consolidation/consolidation_version/consolidation_member; КФО — kfo_result(_line); остальное вычисляется |
Company, Organizations, Organization_aliases, ref_crm_region, consolidation_group, group_membership |
legal_entity, legal_entity_alias, regional_office, company_group, related_group(_member) |
users (email, role) |
app_user + user_role + role_permission |
raw_result_s3_key, queue_msg_id |
recognition_job.result_s3_object_id (единственная ссылка на результат), request_msg_id / result_msg_id |
chart_of_account.account_code |
chart_of_account.code |
role.code KA_HEAD / KA_GO_DM |
KA_RF, KA_GO, RKA, CLIENT_MANAGER, CURATOR_GO, EXPERT, ADMIN (seed) |
статус документа MANUAL_CHECK |
document.status = NEEDS_CHECK |
статус консолидации CREATED (черновик) |
INITIATED |
Открытые места модели (не придумывать, спросить)
-
Закрыто в v5.14: OQ-32 (членство в ГСК и ГСЗ одновременно) — решение владельца 04.10.2026: ЮЛ в одной ГК и одновременно в одной ГСК и одной ГСЗ (ANL-030 отменён); OQ-31 (КПП) — v5.14 не вводил, введён в v5.17 (
legal_entity.kpp, решение владельца 07.10.2026). -
№2
osv_entry.parent_entry_id: хранить ли все строки ОСВ (п. 11 «Парсинг ОСВ» — да) или только контрагентские; нужно ли дерево. Рекомендация для среза 2: хранить все строки сlevelиparent_entry_id— это дёшево и позволяет сверять «Σ контрагентов = итог счёта»; вопрос закрывать с аналитиками. -
document.RECOGNIZED— нужен ли статус «проверка не требуется», или всё идёт черезNEEDS_CHECK → CONFIRMED. -
Замена по-документно (одна ОСВ из файла с пятью листами) — сейчас только файлом целиком.
-
goodwill.participation_amount— входит ли стр. 1350 в базу (вопрос методологам). -
user_roleM:N vs 1:1 — если ТЗ строго «одна роль», заменить наapp_user.role_id. -
consolidation_statusREJECTED/ARCHIVED — из макета, не из ТЗ (ANL-035).