// ДКБ · Модель данных: файлы, справочники, консолидации // Формат: DBML (dbdiagram.io). Вставить на https://dbdiagram.io/d // >>> Источник истины по модели данных. .md — пояснительный, может отставать. // // Ключи: у ВСЕХ сущностей суррогатный PK (uuid). Натуральные ключи // (ИНН, код счёта, CRM ID, код ГСК/ГСЗ) — UNIQUE-колонки, не PK. FK ссылаются на id. // (Для высокообъёмных таблиц — osv_entry и т.п. — uuid можно заменить на bigint identity.) // ЮЛ и ГК — SCD Type 4: живая таблица (текущее) + *_history (прошлые снимки). // Членство в ГСК/ГСЗ — SCD Type 2 (одна таблица, флаг is_current). // Разбор файла берём через stored_file.current_recognition_job_id (авторитетный прогон). // Распознавание: XLS/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 { XLS // машиночитаемые -> табличный сервис XLSX // машиночитаемые -> табличный сервис PDF // изображения -> сервис изображений PNG JPG } Enum recognition_pipeline { tabular // XLS/XLSX-сервис (машиночитаемые данные) image // PDF/PNG/JPG-сервис (распознавание изображений) } Enum period_quarter { Q1 Q2 Q3 Q4 } Enum file_status { "Загружен" "Обработка" "Требуется проверка" "Ошибка" } Enum recognition_status { queued processing done error } Enum statement_type { balance income } Enum fsl_row_kind { row header total balance } Enum osv_group_type { ACCOUNT DEPARTMENT COUNTERPARTY CONTRACT OTHER } Enum osv_data_type { BU CURRENCY QUANTITY SUM } Enum vgo_match_method { exact_1_1 min_deviation_1_1 } // ============ СПРАВОЧНИКИ ============ Table regional_office { id uuid [pk] name varchar [not null, unique] 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 uuid [ref: > app_user.id] created_at timestamptz Note: 'ГК — ТЕКУЩЕЕ состояние (SCD4). Одна строка на группу. История — company_group_history' } // ============ ПОЛЬЗОВАТЕЛИ И ДОСТУП ============ Table app_user { id uuid [pk] external_id varchar [unique, note: 'субъект из SSO/AD банка; аутентификация внешняя'] full_name varchar [not null, note: 'ФИО, напр. Соколов А. В.'] email varchar [unique] regional_office_id uuid [ref: > regional_office.id, note: 'РФ пользователя; NULL = ГО'] is_active boolean created_at timestamptz Note: 'Пользователь системы. Аутентификация внешняя (SSO/AD); тут идентичность и атрибуция' } Table role { id uuid [pk] code varchar [not null, unique, note: 'credit_analyst | dkb_analyst | admin | observer'] name varchar [not null, note: 'Кредитный аналитик | Аналитик ДКБ | Администратор | Наблюдатель'] } Table user_role { id uuid [pk] user_id uuid [not null, ref: > app_user.id] role_id uuid [not null, ref: > role.id] Indexes { (user_id, role_id) [unique] } Note: 'Роли пользователя (M:N, current-state). История назначений — в журнале аудита' }