--- code: DOC-019834 title: "2. Модель данных (сущности)" --- # 2. Модель данных (сущности) 1 ![attachment](/files/obj/CmfDocument/CmfDocument%3A78b/CmfDocument%3A78b1ca82-3483-11f1-8855-56dc18ba196d/%D0%A1%D0%BE%D1%81%D1%82%D0%B0%D0%B2%20%D0%93%D0%9A_%D0%93%D0%A1%D0%9A_%D0%93%D0%A1%D0%97_%D0%B8%D0%B7%20%D0%B2%D1%8B%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D0%BD%D0%B0%201%20%D0%BA%D0%B2.%202026_%20%282%29.xlsx.meta/thumbnail.jpg?version=1) ![](static/attach-file.png) Состав ГК\\_ГСК\\_ГСЗ\\_из выписок\\_на 1 кв. 2026\\_ (2).xlsx 17 апр. 2026 г., 10:39 ![](/files/obj/CmfDocument/CmfDocument%3A78b/CmfDocument%3A78b1ca82-3483-11f1-8855-56dc18ba196d/data-model-part1_4.dbml.meta/thumbnail.jpg?version=1) ![](static/attach-file.png) data-model-part1 \\_4.dbml 21 сент. 2026 г., 15:02 Файлы, справочники, пользователи ![](/files/obj/CmfDocument/CmfDocument%3A78b/CmfDocument%3A78b1ca82-3483-11f1-8855-56dc18ba196d/Untitled.png?version=1) Все сущности ``` // ДКБ · Модель данных · Часть 1: файлы и справочники // Формат: DBML (dbdiagram.io). Вставить на https://dbdiagram.io/d // // Ключи: у ВСЕХ сущностей суррогатный PK (uuid). Натуральные ключи // (ИНН, код счёта, CRM ID, код ГСК/ГСЗ) - UNIQUE-колонки, не PK. FK ссылаются на id. // (Для высокообъёмных таблиц - osv_entry и т.п. - uuid можно заменить на bigint identity.) // ЮЛ и ГК - SCD Type 4: живая таблица (текущее) + *_history (прошлые снимки). // Членство в ГСК/ГСЗ - SCD Type 2 (одна таблица, флаг is_current). // Пользователи: филиал = regional_office (ГО + РФ), отдельная ssp не заводится. // Разбор файла берём через stored_file.current_recognition_job_id (авторитетный прогон). // Распознавание: XLSX -> табличный сервис, PDF/PNG/JPG -> сервис изображений (pipeline). // Результаты обоих сервисов приходят одним потоком NATS (JSON), коррелируются по recognition_job.id. // ============ ENUMS ============ Enum entity_type { "ЮЛ" "ИП" } Enum related_group_kind { gsk gsz } Enum account_kind { A [note: 'актив'] P [note: 'пассив'] AP [note: 'активно-пассивный'] } Enum document_type { "Бухгалтерская отчётность" "ОСВ" "ОФР" "Прочий документ" } Enum file_type { XLSX // машиночитаемые -> табличный сервис PDF // изображения -> сервис изображений PNG JPG } Enum recognition_pipeline { tabular // XLSX-сервис (машиночитаемые данные) image // PDF/PNG/JPG-сервис (распознавание изображений) } Enum period_quarter { Q1 Q2 Q3 Q4 } Enum file_status { "Загружен" "Обработка" "Требуется проверка" "Ошибка" } Enum recognition_status { queued processing done error } Enum counterparty_type { "ГК" "ГСК" "Внешний" } Enum statement_type { balance income } Enum fsl_row_kind { section row sub total balance } // ============ СПРАВОЧНИКИ ============ Table regional_office { id uuid [pk] name varchar [not null, unique] is_active boolean [not null, default: true] Note: 'Филиал: ГО и региональные филиалы (РФ)' } // --- ГК: SCD4 (живая таблица + история) --- Table company_group { id uuid [pk] crm_id varchar [not null, unique, note: 'натуральный ключ из CRM'] name varchar [not null] base_regional_office_id uuid [ref: > regional_office.id] valid_from timestamptz [not null, note: 'действует с'] updated_by varchar created_at timestamptz Note: 'ГК - ТЕКУЩЕЕ состояние (SCD4). Одна строка на группу. История - company_group_history' } Table company_group_history { id uuid [pk] company_group_id uuid [not null, ref: > company_group.id] crm_id varchar [not null] name varchar [not null] base_regional_office_id uuid valid_from timestamptz [not null] valid_to timestamptz [note: 'когда снимок перестал действовать'] changed_by varchar Indexes { (company_group_id, valid_from) [unique] } Note: 'Прошлые снимки ГК (пишутся при каждом изменении company_group)' } // --- ЮЛ: SCD4 (живая таблица + история) --- Table legal_entity { id uuid [pk] inn varchar [not null, unique, note: 'натуральный ключ'] entity_type entity_type [note: 'ЮЛ/ИП'] name varchar [not null] company_group_id uuid [not null, ref: > company_group.id, note: 'текущая ГК (меняется событием «Переход в ГК»)'] regional_office_id uuid [ref: > regional_office.id] close_date date [note: 'NULL = активна; дата = архивирована/закрыта'] valid_from timestamptz [not null, note: 'действует с'] updated_by varchar created_at timestamptz Note: 'Организация (ЮЛ/ИП) - ТЕКУЩЕЕ состояние (SCD4). История - legal_entity_history' } Table legal_entity_history { id uuid [pk] legal_entity_id uuid [not null, ref: > legal_entity.id] inn varchar [not null] entity_type entity_type name varchar [not null] company_group_id uuid [not null] regional_office_id uuid close_date date valid_from timestamptz [not null] valid_to timestamptz [note: 'когда снимок перестал действовать'] changed_by varchar Indexes { (legal_entity_id, valid_from) [unique] } Note: 'Прошлые снимки организации (пишутся при каждом изменении legal_entity)' } Table related_group { id uuid [pk] code varchar [not null, unique, note: 'человеко-код, напр. GSK-001'] company_group_id uuid [not null, ref: > company_group.id] kind related_group_kind name varchar [not null] created_date date Indexes { (id, kind) [unique, note: 'нужно для composite FK из related_group_member'] } Note: 'Группа связанных компаний/заёмщиков (ГСК/ГСЗ) - current-state' } // --- Членство: SCD2 (одна таблица + is_current) --- Table related_group_member { id uuid [pk] related_group_id uuid [not null, ref: > related_group.id] legal_entity_id uuid [not null, ref: > legal_entity.id] kind related_group_kind [not null, note: 'копия из related_group; composite FK (related_group_id, kind) > related_group(id, kind)'] valid_from timestamptz [not null] valid_to timestamptz [note: 'NULL = текущая'] is_current boolean [not null] created_by varchar Indexes { (related_group_id, legal_entity_id) [note: 'partial UNIQUE WHERE is_current - одна текущая версия на пару'] legal_entity_id [note: 'ВРЕМЕННО: partial UNIQUE WHERE is_current AND kind = gsk - одна ГСК на организацию'] } Note: 'Состав ГСК/ГСЗ (M:N) - SCD2. Исключение = закрытие версии (is_current=false), не DELETE' } Table chart_of_account { id uuid [pk] code varchar [not null, unique, note: 'натуральный код счёта, напр. 60.01'] parent_id uuid [ref: > chart_of_account.id, note: 'иерархия счетов'] name varchar [not null] kind account_kind Note: 'План счетов' } // ============ ПОЛЬЗОВАТЕЛИ И РОЛИ ============ Table role { id uuid [pk] code varchar [not null, unique, note: 'машинный код: KA_RF, KA_GO, KA_GO_DM, CURATOR_GO, ADMIN'] name varchar [not null, note: 'отображаемое название роли'] Note: 'Справочник ролей. Матрица прав (создание ГК, правка состава ГСК, утверждение КФО)' } Table app_user { id uuid [pk] email varchar [not null, unique] username varchar [not null, unique] hashed_password varchar full_name varchar role_id uuid [not null, ref: > role.id] regional_office_id uuid [not null, ref: > regional_office.id, note: 'филиал пользователя: ГО или РФ'] created_at timestamptz updated_at timestamptz is_active boolean [not null, default: true] Note: 'Пользователь системы. Видимость данных = роль + филиал' } // ============ ФАЙЛЫ / РАСПОЗНАВАНИЕ ============ Table stored_file { id uuid [pk] legal_entity_id uuid [not null, ref: > legal_entity.id] document_type document_type file_type file_type original_name varchar s3_key varchar [unique, note: 'ключ объекта; бакет из конфига (uploads)'] content_hash varchar [note: 'sha256, дедуп'] size_bytes bigint period_year smallint [note: 'отчётный период сдачи документа'] period_quarter period_quarter status file_status current_recognition_job_id uuid [ref: > recognition_job.id, note: 'авторитетный прогон: чьи строки показываем'] uploaded_by varchar uploaded_at timestamptz Note: 'Загруженный файл (в S3 - только ссылка). Строки разбора берём через current_recognition_job_id' } Table recognition_job { id uuid [pk] file_id uuid [not null, ref: > stored_file.id] pipeline recognition_pipeline [not null, note: 'tabular=XLSX-сервис, image=PDF/PNG/JPG-сервис'] service_version varchar [note: 'версия сервиса/модели, для диагностики'] status recognition_status attempt smallint queue_msg_id varchar [note: 'id сообщения NATS для дедупа при redelivery'] requested_at timestamptz [note: 'опубликовано в очередь'] started_at timestamptz [note: 'сервис взял в работу'] finished_at timestamptz error_message text raw_result_s3_key varchar [note: 'ключ JSON-результата; бакет из конфига (results)'] Note: 'Задание на распознавание. Роутинг по pipeline; результат приходит по NATS, коррелируется по id' } Table osv_entry { id uuid [pk] recognition_job_id uuid [not null, ref: > recognition_job.id, note: 'файл достаётся через задание'] account_code varchar [note: 'сырой код счёта из разбора'] account_id uuid [ref: > chart_of_account.id, note: 'резолвнутая ссылка на план счетов (nullable)'] account_root varchar counterparty_name varchar counterparty_inn varchar [note: 'просто данные; внешний контрагент, без FK'] counterparty_type counterparty_type opening_debit numeric opening_credit numeric turnover_debit numeric turnover_credit numeric closing_debit numeric closing_credit numeric Note: 'Строка ОСВ (разобрано из XLSX)' } Table financial_statement_line { id uuid [pk] recognition_job_id uuid [not null, ref: > recognition_job.id, note: 'файл достаётся через задание'] statement_type statement_type [note: 'balance | income (ОФР)'] line_code varchar [note: 'код строки формы, напр. 1230'] line_name varchar row_kind fsl_row_kind ordinal int Note: 'Строка баланса/ОФР (распознано из изображения: PDF/PNG/JPG)' } Table financial_statement_value { id uuid [pk] line_id uuid [not null, ref: > financial_statement_line.id] period_label varchar [note: 'колонка-компаратор внутри формы (2-3 сравнительные даты), не период файла'] amount numeric is_recognized boolean [note: 'false = не распознано'] Note: 'Значение строки по колонке-периоду (сравнительные колонки баланса/ОФР)' } ``` Табличная форма | **Сущность** | **Наименование атрибута** | **Тип данных** | **Обязательность** | **Ограничения** | **Комментарии** | | --- | --- | --- | --- | --- | --- | | **regional\\_office** | **id** | **uuid** | **+** | **PK** | **Идентификатор филиала** | | | name | varchar | + | UNIQUE | Наименование филиала | | | is\\_active | boolean | + | DEFAULT true | Признак активности филиала | | **company\\_group** | **id** | **uuid** | **+** | **PK** | **Идентификатор группы компаний** | | | crm\\_id | varchar | + | UNIQUE | Ключ из CRM | | | name | varchar | + | | Наименование ГК | | | base\\_regional\\_office\\_id | uuid | - | FK regional\\_office(id) | Региональный филиал группы | | | valid\\_from | timestamptz | + | | Дата начала действия текущего состояния (SCD4) | | | updated\\_by | varchar | - | | Кто последним изменил запись | | | created\\_at | timestamptz | - | | Дата создания записи | | **company\\_group\\_history** | **id** | **uuid** | **+** | **PK** | **Идентификатор снимка** | | | company\\_group\\_id | uuid | + | FK company\\_group(id) | Группа компаний, к которой относится снимок | | | crm\\_id | varchar | + | | Ключ из CRM | | | name | varchar | + | | Наименование ГК | | | base\\_regional\\_office\\_id | uuid | - | | Региональный филиал группы | | | valid\\_from | timestamptz | + | | Начало действия снимка | | | valid\\_to | timestamptz | - | | Окончание действия снимка | | | changed\\_by | varchar | - | | Кто изменил запись | | | - | - | | UNIQUE (company\\_group\\_id, valid\\_from) | Уникальность снимка группы на дату | | **legal\\_entity** | **id** | **uuid** | **+** | **PK** | **Идентификатор организации** | | | inn | varchar | + | UNIQUE | ИНН | | | entity\\_type | entity\\_type | - | ENUM | Тип субъекта. Возможные значения: * ЮЛ (юридическое лицо) * ИП (индивидуальный предприниматель) | | | name | varchar | + | | Наименование организации | | | company\\_group\\_id | uuid | + | FK company\\_group(id) | Текущая группа компаний | | | regional\\_office\\_id | uuid | - | FK regional\\_office(id) | Филиал, за которым закреплена организация | | | close\\_date | date | - | | NULL - организация активна; дата - архивирована или закрыта | | | valid\\_from | timestamptz | + | | Дата начала действия текущего состояния (SCD4) | | | updated\\_by | varchar | - | | Кто последним изменил запись | | | created\\_at | timestamptz | - | | Дата создания записи | | **legal\\_entity\\_history** | **id** | **uuid** | **+** | **PK** | **Идентификатор снимка** | | | legal\\_entity\\_id | uuid | + | FK legal\\_entity(id) | Организация, к которой относится снимок | | | inn | varchar | + | | ИНН на момент снимка | | | entity\\_type | entity\\_type | - | ENUM | Тип субъекта на момент снимка (ЮЛ / ИП) | | | name | varchar | + | | Наименование организации на момент снимка | | | company\\_group\\_id | uuid | + | | Группа компаний на момент снимка | | | regional\\_office\\_id | uuid | - | | Филиал на момент снимка | | | close\\_date | date | - | | Дата архивирования на момент снимка | | | valid\\_from | timestamptz | - | | Начало действия снимка | | | valid\\_to | timestamptz | - | | Окончание действия снимка | | | changed\\_by | varchar | - | | Кто изменил запись | | | - | - | | UNIQUE (legal\\_entity\\_id, valid\\_from) | Уникальность снимка организации на дату | | **related\\_group** | **id** | **uuid** | **+** | **PK** | **Идентификатор группы связанных компаний / заёмщиков** | | | code | varchar | + | UNIQUE | Код группы (например, GSK-001) | | | company\\_group\\_id | uuid | + | FK company\\_group(id) | Группа компаний, в рамках которой создана ГСК/ГСЗ | | | kind | related\\_group\\_kind | - | ENUM | Вид группы. Возможные значения: * gsk (группа связанных компаний) * gsz (группа связанных заёмщиков) | | | name | varchar | + | | Наименование группы | | | created\\_date | date | - | | Дата создания группы | | | - | - | | UNIQUE (id, kind) | Ограничение для составного внешнего ключа из related\\_group\\_member | | **related\\_group\\_member** | **id** | **uuid** | **+** | **PK** | **Идентификатор записи о членстве** | | | related\\_group\\_id | uuid | + | FK related\\_group(id) | Группа, в состав которой входит организация | | | legal\\_entity\\_id | uuid | + | FK legal\\_entity(id) | Организация - участник группы | | | kind | related\\_group\\_kind | + | составной FK (related\\_group\\_id, kind) related\\_group(id, kind) | Копия вида группы из related\\_group | | | valid\\_from | timestamptz | + | | Дата включения в состав группы | | | valid\\_to | timestamptz | - | | Дата исключения. NULL - действующая версия | | | is\\_current | boolean | + | | Признак действующей версии (SCD2) | | | created\\_by | varchar | - | | Кто включил организацию в состав | | | - | - | | partial UNIQUE (related\\_group\\_id, legal\\_entity\\_id) WHERE is\\_current | Одна текущая версия на пару группа - организация | | | - | - | | partial UNIQUE (legal\\_entity\\_id) WHERE is\\_current AND kind = gsk | Организация одновременно входит только в одну ГСК | | **chart\\_of\\_account** | **id** | **uuid** | **+** | **PK** | **Идентификатор счёта** | | | code | varchar | + | UNIQUE | Натуральный код счёта или субсчёта (например, 60.01) | | | parent\\_id | uuid | - | FK chart\\_of\\_account(id) | Родительский счёт | | | name | varchar | + | | Наименование счёта | | | kind | account\\_kind | - | ENUM | Тип счёта. Возможные значения: * A (активный) * P (пассивный) * AP (активно-пассивный) | | **role** | **id** | **uuid** | **+** | **PK** | **Идентификатор роли** | | | code | varchar | + | UNIQUE | Код роли. Возможные значения: * ADMIN (администратор) * KA\\_RF (кредитный аналитик РФ) * KA\\_GO (кредитный аналитик ГО) * KA\\_HEAD (руководитель КА) * CLIENT\\_MANAGER (клиентский менеджер) * CURATOR\\_GO (куратор ГО) * EXPERT (Эксперт) | | | name | varchar | + | | Отображаемое название роли. Отделено от кода, чтобы права проверялись по коду, а не по русской строке | | **app\\_user** | **id** | **uuid** | **+** | **PK** | **Идентификатор пользователя** | | | email | varchar | + | UNIQUE | Электронная почта пользователя | | | username | varchar | + | UNIQUE | Логин пользователя | | | hashed\\_password | varchar | - | | Хеш пароля | | | full\\_name | varchar | - | | ФИО пользователя | | | role\\_id | uuid | + | FK role(id) | Роль пользователя | | | regional\\_office\\_id | uuid | + | FK regional\\_office(id) | Филиал пользователя | | | created\\_at | timestamptz | - | | Дата создания учётной записи | | | updated\\_at | timestamptz | - | | Дата изменения учётной записи | | | is\\_active | boolean | + | DEFAULT true | Признак активности учётной записи | | **stored\\_file** | **id** | **uuid** | **+** | **PK** | **Идентификатор загруженного файла** | | | legal\\_entity\\_id | uuid | + | FK legal\\_entity(id) | Организация - владелец документа | | | document\\_type | document\\_type | - | ENUM | Тип документа. Возможные значения: * Бухгалтерская отчётность * ОСВ * ОФР * Прочий документ | | | file\\_type | file\\_type | - | ENUM | Формат файла. Определяет маршрут распознавания: * XLSX - табличный сервис * PDF, PNG, JPG - сервис изображений | | | original\\_name | varchar | - | | Исходное имя файла при загрузке | | | s3\\_key | varchar | - | UNIQUE | Ключ объекта в хранилище S3 | | | content\\_hash | varchar | - | | SHA-256 содержимого для дедупликации | | | size\\_bytes | bigint | - | | Размер файла в байтах | | | period\\_year | smallint | - | | Год отчётного периода | | | period\\_quarter | period\\_quarter | - | ENUM | Квартал отчётного периода - Q1, Q2, Q3, Q4 | | | status | file\\_status | - | ENUM | Статус обработки файла. Возможные значения: * Загружен * Обработка * Требуется проверка * Ошибка | | | current\\_recognition\\_job\\_id | uuid | - | FK recognition\\_job(id) | Авторитетный прогон распознавания. Определяет, чьи строки отображаются | | | uploaded\\_by | varchar | - | | Кто загрузил файл | | | uploaded\\_at | timestamptz | - | | Дата и время загрузки | | **recognition\\_job** | **id** | **uuid** | **+** | **PK** | **Идентификатор задания на распознавание** | | | file\\_id | uuid | + | FK stored\\_file(id) | Файл, который распознаётся | | | pipeline | recognition\\_pipeline | + | ENUM | Маршрут обработки. Возможные значения: * tabular (сервис разбора XLSX) * image (сервис распознавания PDF/PNG/JPG) | | | service\\_version | varchar | - | | Версия сервиса или модели распознавания | | | status | recognition\\_status | - | ENUM | Статус задания. Возможные значения: * queued (в очереди) * processing (в обработке) * done (завершено) * error (ошибка) | | | attempt | smallint | - | | Номер попытки | | | queue\\_msg\\_id | varchar | - | | Идентификатор сообщения NATS для дедупликации при повторной доставке | | | requested\\_at | timestamptz | - | | Дата и время публикации задания в очередь | | | started\\_at | timestamptz | - | | Когда сервис взял задание в работу | | | finished\\_at | timestamptz | - | | Когда задание завершено | | | error\\_message | text | - | | Текст ошибки распознавания | | | raw\\_result\\_s3\\_key | varchar | - | | Ключ JSON-результата в хранилище (бакет results) | | **osv\\_entry** | **id** | **uuid** | **+** | **PK** | **Идентификатор строки ОСВ** | | | recognition\\_job\\_id | uuid | + | FK recognition\\_job(id) | Задание распознавания | | | account\\_code | varchar | - | | Код счёта в исходном виде из документа | | | account\\_id | uuid | - | FK chart\\_of\\_account(id) | Ссылка на план счетов | | | account\\_root | varchar | - | | Корневой счёт | | | counterparty\\_name | varchar | - | | Наименование контрагента | | | counterparty\\_inn | varchar | - | | ИНН контрагента | | | counterparty\\_type | counterparty\\_type | - | ENUM | Признак контрагента. Возможные значения: * ГК (в группе компаний) * ГСК (в периметре) * Внешний | | | opening\\_debit | numeric | - | | Сальдо на начало периода, дебет | | | opening\\_credit | numeric | - | | Сальдо на начало периода, кредит | | | turnover\\_debit | numeric | - | | Оборот за период, дебет | | | turnover\\_credit | numeric | - | | Оборот за период, кредит | | | closing\\_debit | numeric | - | | Сальдо на конец периода, дебет | | | closing\\_credit | numeric | - | | Сальдо на конец периода, кредит | | **financial\\_statement\\_line** | **id** | **uuid** | **+** | **PK** | **Идентификатор строки формы отчётности** | | | recognition\\_job\\_id | uuid | + | FK recognition\\_job(id) | Задание распознавания, из которого получена строка | | | statement\\_type | statement\\_type | - | ENUM | Тип формы. Возможные значения: * balance (бухгалтерский баланс) * income (ОФР) | | | line\\_code | varchar | - | | Код строки формы (например, 1230) | | | line\\_name | varchar | - | | Наименование показателя | | | row\\_kind | fsl\\_row\\_kind | - | ENUM | Вид строки. Возможные значения: * section (раздел) * row (показатель) * sub (подстрока) * total (итог раздела) * balance (валюта баланса) | | | ordinal | int | - | | Порядок строки в форме | | **financial\\_statement\\_value** | **id** | **uuid** | **+** | **PK** | **Идентификатор значения** | | | line\\_id | uuid | + | FK financial\\_statement\\_line(id) | Строка формы, к которой относится значение | | | period\\_label | varchar | - | | Колонка-компаратор внутри формы (сравнительные даты) | | | amount | numeric | - | | Значение показателя | | | is\\_recognized | boolean | - | | false - значение не распознано |