arm-ka-docs/source/tz/АРМ КА.Техническое задание - 01_2. Модель данных (сущности).md

465 lines
29 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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 - значение не распознано |