feat: новая функция

This commit is contained in:
2025-10-08 18:01:14 +03:00
parent 2c53bce32a
commit 725e7fd5a2
60 changed files with 5427 additions and 3921 deletions

View File

@@ -0,0 +1,911 @@
# Структура базы данных для AI Ассистента
**Дата проверки:** 2025-10-08
**Метод:** Прямая проверка через PostgreSQL
**Статус:** ✅ ПРОВЕРКА ЗАВЕРШЕНА
---
## 📊 Список AI таблиц
Найдено таблиц: **27 таблиц** (25 связаны с AI, 2 CMS)
---
## 1. `ai_assistant_settings` ⭐ КЛЮЧЕВАЯ
**Назначение:** Основные настройки AI ассистента
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор
- `selected_rag_tables` - INTEGER[] - массив ID RAG таблиц для использования
- `languages` - TEXT[] - массив поддерживаемых языков
- `updated_at` - TIMESTAMP - время последнего обновления (default: now())
- `updated_by` - INTEGER - кто обновил (user_id)
- `rules_id` - INTEGER (FK → ai_assistant_rules) - ID правил для AI
- `telegram_settings_id` - INTEGER (FK → telegram_settings) - ID настроек Telegram
- `email_settings_id` - INTEGER (FK → email_settings) - ID настроек Email
- `system_prompt_encrypted` - TEXT - зашифрованный системный промпт
- `model_encrypted` - TEXT - зашифрованное название модели
- `system_message_encrypted` - TEXT - зашифрованное системное сообщение
- `embedding_model_encrypted` - TEXT - зашифрованное название embedding модели
- `system_message` - TEXT - системное сообщение (расшифрованное)
- `embedding_model` - VARCHAR(128) - embedding модель (расшифрованное)
**Связи:**
-`ai_assistant_rules` (через rules_id)
-`telegram_settings` (через telegram_settings_id)
-`email_settings` (через email_settings_id)
**Используется в:**
- aiAssistantSettingsService.js (getSettings, updateSettings)
- conversationService.js (getRagTableId)
- ai-assistant.js (generateResponse)
- routes/settings.js (API)
---
## 2. `ai_assistant_rules` ✅ АКТИВНАЯ
**Назначение:** Правила и инструкции для AI ассистента
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор
- `created_at` - TIMESTAMP - дата создания (default: now())
- `updated_at` - TIMESTAMP - дата обновления (default: now())
- `name_encrypted` - TEXT - зашифрованное название правила
- `description_encrypted` - TEXT - зашифрованное описание правила
- `rules_encrypted` - TEXT - зашифрованные правила (JSON) ✅ ДОБАВЛЕНО
**Связи:**
-`ai_assistant_settings.rules_id` ссылается на эту таблицу
**Используется в:**
- aiAssistantRulesService.js (getAllRules, getRuleById, createRule)
- ai-assistant.js (получение правил)
- routes/settings.js (CRUD API)
---
## 3. `ai_providers_settings` ⭐ КЛЮЧЕВАЯ
**Назначение:** Настройки AI провайдеров (Ollama, OpenAI, Anthropic, Google)
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор
- `created_at` - TIMESTAMP NOT NULL - дата создания (default: now())
- `updated_at` - TIMESTAMP NOT NULL - дата обновления (default: now())
- `provider_encrypted` - TEXT - зашифрованное название провайдера ('ollama', 'openai', etc.)
- `api_key_encrypted` - TEXT - зашифрованный API ключ
- `base_url_encrypted` - TEXT - зашифрованный базовый URL
- `selected_model_encrypted` - TEXT - зашифрованное название выбранной модели
- `embedding_model_encrypted` - TEXT - зашифрованное название embedding модели
- `embedding_model` - VARCHAR(128) - embedding модель (незашифрованное, дублирует?)
**Связи:**
- Нет внешних ключей
**Используется в:**
- aiProviderSettingsService.js (getProviderSettings, upsertProviderSettings)
- ollamaConfig.js (loadSettingsFromDb - загружает настройки Ollama)
- ragService.js (getProviderSettings для вызова разных AI)
- routes/settings.js (CRUD API)
---
## 4. `messages` ⭐ КЛЮЧЕВАЯ
**Назначение:** Все сообщения пользователей и AI ответы
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор
- `conversation_id` - INTEGER (FK → conversations) - ID беседы
- `sender_id` - INTEGER - ID отправителя (для админских сообщений)
- `created_at` - TIMESTAMP - дата создания (default: CURRENT_TIMESTAMP)
- `user_id` - INTEGER (FK → users) - ID пользователя-владельца беседы
- `tokens_used` - INTEGER - количество токенов (default: 0)
- `is_processed` - BOOLEAN - обработано ли (default: false)
- `attachment_size` - BIGINT - размер вложения в байтах
- `attachment_data` - BYTEA - бинарные данные вложения
- `sender_type_encrypted` - TEXT - тип отправителя ('user', 'assistant', 'editor')
- `content_encrypted` - TEXT - текст сообщения
- `channel_encrypted` - TEXT - канал ('web', 'telegram', 'email')
- `role_encrypted` - TEXT - роль
- `attachment_filename_encrypted` - TEXT - имя файла
- `attachment_mimetype_encrypted` - TEXT - MIME тип
- `direction_encrypted` - TEXT - направление ('in', 'out')
- `message_id_encrypted` - TEXT - ID сообщения для дедупликации
- `message_type` - VARCHAR(20) NOT NULL - тип ('user_chat', 'admin_chat')
**Индексы:**
- idx_messages_conversation_id
- idx_messages_created_at
- idx_messages_message_type
- idx_messages_user_id
**Связи:**
-`conversations` (ON DELETE CASCADE)
-`users` (ON DELETE CASCADE)
**Триггеры:**
- `trg_set_message_user_id` - автоустановка user_id
**Используется в:**
- unifiedMessageProcessor.js (saveUserMessage)
- messageDeduplicationService.js (сохранение)
- conversationService.js (история)
- routes/messages.js, routes/chat.js
---
## 5. `conversations` ⭐ КЛЮЧЕВАЯ
**Назначение:** Беседы (диалоги) пользователей с AI
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор беседы
- `user_id` - INTEGER (FK → users) - ID пользователя-владельца
- `created_at` - TIMESTAMP - дата создания (default: CURRENT_TIMESTAMP)
- `updated_at` - TIMESTAMP - дата обновления (default: CURRENT_TIMESTAMP)
- `title_encrypted` - TEXT - зашифрованный заголовок беседы
- `conversation_type` - VARCHAR(50) - тип беседы (default: 'user_chat')
- `'user_chat'` - обычный чат пользователя
- `'admin_chat'` - приватный чат между админами
**Индексы:**
- idx_conversations_conversation_type
- idx_conversations_created_at
- idx_conversations_user_id
**Связи:**
-`users` (user_id, ON DELETE CASCADE)
-`conversation_participants` (для многопользовательских чатов)
-`messages` (все сообщения беседы)
**Используется в:**
- conversationService.js (findOrCreateConversation, getConversationHistory)
- unifiedMessageProcessor.js (создание беседы)
- guestMessageService.js (перенос гостевых сообщений)
- routes/messages.js (CRUD беседы)
---
## 6. `message_deduplication` ⭐ КЛЮЧЕВАЯ
**Назначение:** Предотвращение дублирования сообщений (дедупликация)
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор
- `channel` - VARCHAR(20) NOT NULL - канал ('web', 'telegram', 'email')
- `message_id_hash` - VARCHAR(64) NOT NULL - SHA-256 хеш ID
- `user_id` - INTEGER NOT NULL (FK → users) - ID пользователя
- `sender_type` - VARCHAR(20) NOT NULL - тип отправителя ('user', 'assistant')
- `original_message_id_encrypted` - TEXT - оригинальный ID
- `processed_at` - TIMESTAMP WITH TIME ZONE - время обработки (default: now())
- `expires_at` - TIMESTAMP WITH TIME ZONE - время истечения
**Индексы:**
- idx_message_dedup_expires
- idx_message_dedup_lookup (channel, hash, user_id, sender_type)
- idx_message_dedup_user_channel
- UNIQUE (channel, hash, user_id, sender_type)
**Связи:**
-`users` (ON DELETE CASCADE)
**Используется в:**
- messageDeduplicationService.js
- unifiedMessageProcessor.js
- ai-assistant.js
---
## 7. `guest_messages` ✅ АКТИВНАЯ
**Назначение:** Временное хранение сообщений гостей
**Столбцы:**
- `id` - INTEGER (PK)
- `is_ai` - BOOLEAN - от AI? (default: false)
- `created_at` - TIMESTAMP WITH TIME ZONE (default: now())
- `attachment_size` - BIGINT
- `attachment_data` - BYTEA
- `guest_id_encrypted` - TEXT - ID гостя (sessionID)
- `content_encrypted` - TEXT
- `language_encrypted` - TEXT
- `attachment_filename_encrypted` - TEXT
- `attachment_mimetype_encrypted` - TEXT
- `attachment_filename` - TEXT (дубль?)
- `attachment_mimetype` - TEXT (дубль?)
**Связи:**
- Нет FK (временная)
**Используется в:**
- guestService.js
- guestMessageService.js (перенос после auth)
**Цикл:**
1. Гость пишет → сохраняется
2. Авторизация → перенос в messages
3. Удаление из guest_messages
---
## 8. `guest_user_mapping` ✅ АКТИВНАЯ
**Назначение:** Связь между гостями и зарегистрированными пользователями
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор
- `user_id` - INTEGER NOT NULL (FK → users) - ID пользователя
- `processed` - BOOLEAN - обработаны ли сообщения (default: false)
- `created_at` - TIMESTAMP - дата создания (default: CURRENT_TIMESTAMP)
- `guest_id_encrypted` - TEXT - зашифрованный ID гостя (sessionID)
**Индексы:**
- idx_guest_user_mapping_guest_id_encrypted - UNIQUE
- idx_guest_user_mapping_user_id
**Связи:**
-`users` (user_id, ON DELETE CASCADE)
**Используется в:**
- guestMessageService.js (processGuestMessages - проверка и создание mapping)
**Логика:**
- При аутентификации гостя создается запись
- `processed = false` → сообщения еще не перенесены
- `processed = true` → сообщения уже перенесены в messages
---
## 9. `telegram_settings` ✅ АКТИВНАЯ
**Назначение:** Настройки Telegram бота
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор
- `created_at` - TIMESTAMP NOT NULL - дата создания (default: now())
- `updated_at` - TIMESTAMP NOT NULL - дата обновления (default: now())
- `bot_token_encrypted` - TEXT - зашифрованный токен Telegram бота
- `bot_username_encrypted` - TEXT - зашифрованное имя бота
**Индексы:**
- PRIMARY KEY: id
**Связи:**
-`ai_assistant_settings.telegram_settings_id` ссылается на эту таблицу
**Используется в:**
- telegramBot.js (loadSettings - загрузка токена)
- botsSettings.js (getTelegramSettings, saveTelegramSettings, testConnection)
- routes/admin (API для настройки Telegram)
---
## 10. `email_settings` ✅ АКТИВНАЯ
**Назначение:** Настройки Email бота (SMTP + IMAP)
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор
- `smtp_port` - INTEGER NOT NULL - порт SMTP (обычно 465)
- `imap_port` - INTEGER - порт IMAP (обычно 993)
- `created_at` - TIMESTAMP NOT NULL - дата создания (default: now())
- `updated_at` - TIMESTAMP NOT NULL - дата обновления (default: now())
- `smtp_host_encrypted` - TEXT - зашифрованный хост SMTP
- `smtp_user_encrypted` - TEXT - зашифрованный пользователь SMTP
- `smtp_password_encrypted` - TEXT - зашифрованный пароль SMTP
- `imap_host_encrypted` - TEXT - зашифрованный хост IMAP
- `from_email_encrypted` - TEXT - зашифрованный email отправителя
- `imap_user_encrypted` - TEXT - зашифрованный пользователь IMAP
- `imap_password_encrypted` - TEXT - зашифрованный пароль IMAP
**Индексы:**
- PRIMARY KEY: id
**Связи:**
-`ai_assistant_settings.email_settings_id` ссылается на эту таблицу
**Используется в:**
- emailBot.js (loadSettings - создание SMTP транспортера и IMAP соединения)
- botsSettings.js (getEmailSettings, saveEmailSettings, testEmailSMTP, testEmailIMAP)
- routes/admin (API для настройки Email)
---
## 11. `is_rag_source` ✅ АКТИВНАЯ
**Назначение:** Источники данных для RAG (справочник)
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор источника
- `name_encrypted` - TEXT - зашифрованное название источника
**Индексы:**
- PRIMARY KEY: id
**Связи:**
-`user_tables.is_rag_source_id` ссылается на эту таблицу
**Используется в:**
- Связывает RAG таблицы с типом источника данных
- user_tables имеет default: is_rag_source_id = 2
**Примеры источников:**
- ID 1: "FAQ"
- ID 2: "База знаний"
- ID 3: "Документация"
(зависит от данных в БД)
---
## 12. `user_tables` ⭐ КЛЮЧЕВАЯ (RAG)
**Назначение:** Пользовательские таблицы с данными для RAG базы знаний
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор таблицы
- `created_at` - TIMESTAMP - дата создания (default: CURRENT_TIMESTAMP)
- `updated_at` - TIMESTAMP - дата обновления (default: CURRENT_TIMESTAMP)
- `is_rag_source_id` - INTEGER (FK → is_rag_source) - тип источника (default: 2)
- `name_encrypted` - TEXT - зашифрованное название таблицы
- `description_encrypted` - TEXT - зашифрованное описание
**Индексы:**
- PRIMARY KEY: id
**Связи:**
-`is_rag_source` (is_rag_source_id)
-`user_columns` (table_id, ON DELETE CASCADE)
-`user_rows` (table_id, ON DELETE CASCADE)
-`user_table_relations` (to_table_id, ON DELETE CASCADE)
**Используется в:**
- ragService.js (getTableData - получение данных для RAG)
- routes/tables.js (CRUD таблиц)
- routes/rag.js (выбор таблицы для RAG запроса)
**Структура RAG:**
```
user_tables (таблица)
└─ user_columns (колонки с purpose)
└─ user_rows (строки)
└─ user_cell_values (значения ячеек)
```
---
## 13. `user_columns` ⭐ КЛЮЧЕВАЯ (RAG)
**Назначение:** Колонки пользовательских таблиц с метаданными для RAG
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор колонки
- `table_id` - INTEGER NOT NULL (FK → user_tables) - ID таблицы
- `order` - INTEGER - порядок отображения (default: 0)
- `created_at` - TIMESTAMP - дата создания (default: CURRENT_TIMESTAMP)
- `updated_at` - TIMESTAMP - дата обновления (default: CURRENT_TIMESTAMP)
- `name_encrypted` - TEXT - зашифрованное название колонки
- `type_encrypted` - TEXT - зашифрованный тип ('text', 'number', 'date', etc.)
- `placeholder_encrypted` - TEXT - зашифрованный плейсхолдер
- `placeholder` - VARCHAR(255) - плейсхолдер для RAG (UNIQUE)
- `options` - JSONB - дополнительные опции (default: '{}')
- `purpose` - назначение колонки ('question', 'answer', 'context', 'product', 'priority', 'date')
**Индексы:**
- PRIMARY KEY: id
- idx_user_columns_options (GIN) - для быстрого поиска по JSONB
- user_columns_placeholder_key (UNIQUE) - уникальность плейсхолдеров
**Связи:**
-`user_tables` (table_id, ON DELETE CASCADE)
-`user_table_relations` (column_id, ON DELETE CASCADE)
**Используется в:**
- ragService.js (getTableData - определение колонок по purpose)
- routes/tables.js (CRUD колонок)
**Важно для RAG:**
- `options.purpose` определяет роль колонки:
- 'question' - вопрос для поиска
- 'answer' - ответ
- 'context' - контекст
- 'product', 'priority', 'date' - метаданные
---
## 14. `user_rows` ⭐ КЛЮЧЕВАЯ (RAG)
**Назначение:** Строки данных в пользовательских таблицах (записи для RAG)
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор строки
- `table_id` - INTEGER NOT NULL (FK → user_tables) - ID таблицы
- `created_at` - TIMESTAMP - дата создания (default: CURRENT_TIMESTAMP)
- `updated_at` - TIMESTAMP - дата обновления (default: CURRENT_TIMESTAMP)
- `order` - INTEGER - порядок отображения (default: 0)
**Индексы:**
- PRIMARY KEY: id
**Связи:**
-`user_tables` (table_id, ON DELETE CASCADE)
-`user_cell_values` (row_id, ON DELETE CASCADE)
-`user_table_relations` (from_row_id, to_row_id, ON DELETE CASCADE)
-`user_tag_links` (tag_id, ON DELETE CASCADE)
**Используется в:**
- ragService.js (getTableData - получение всех строк таблицы)
- routes/tables.js (CRUD строк)
**Важно:**
- Каждая строка = одна запись в RAG (например, один вопрос-ответ)
- Значения хранятся в `user_cell_values`
---
## 15. `user_cell_values` ⭐ КЛЮЧЕВАЯ (RAG)
**Назначение:** Значения ячеек в пользовательских таблицах (данные для RAG)
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор значения
- `row_id` - INTEGER NOT NULL (FK → user_rows) - ID строки
- `column_id` - INTEGER NOT NULL (FK → user_columns) - ID колонки ✅ ИСПРАВЛЕНО
- `created_at` - TIMESTAMP - дата создания (default: CURRENT_TIMESTAMP)
- `updated_at` - TIMESTAMP - дата обновления (default: CURRENT_TIMESTAMP)
- `value_encrypted` - TEXT - зашифрованное значение ячейки
**Индексы:**
- PRIMARY KEY: id
- user_cell_values_row_id_column_id_key (UNIQUE) - уникальная пара (row_id, column_id)
**Связи:**
-`user_rows` (row_id, ON DELETE CASCADE)
-`user_columns` (column_id, ON DELETE CASCADE) ✅ ДОБАВЛЕНО
**Используется в:**
- ragService.js (getTableData - получение всех значений для построения RAG данных)
- routes/tables.js (CRUD значений ячеек)
**Как работает RAG:**
1. ragService получает все cell_values для строк таблицы
2. Группирует по row_id
3. Находит значения по column_id с нужным purpose (question/answer/context)
4. Формирует данные для векторного поиска
---
## 16. `conversation_participants` ✅ АКТИВНАЯ
**Назначение:** Участники многопользовательских бесед (для admin_chat)
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор
- `conversation_id` - INTEGER (FK → conversations) - ID беседы
- `user_id` - INTEGER (FK → users) - ID участника
- `created_at` - TIMESTAMP - дата добавления (default: CURRENT_TIMESTAMP)
**Индексы:**
- PRIMARY KEY: id
- conversation_participants_conversation_id_user_id_key (UNIQUE) - пара (conversation_id, user_id)
- idx_conversation_participants_conversation_id
- idx_conversation_participants_user_id
**Связи:**
-`conversations` (conversation_id, ON DELETE CASCADE)
-`users` (user_id, ON DELETE CASCADE)
**Используется в:**
- routes/messages.js (создание admin_chat бесед между админами)
- routes/chat.js (поиск приватных бесед)
**Логика:**
- Для обычных чатов (`user_chat`) - НЕ используется (один владелец)
- Для админских чатов (`admin_chat`) - хранит всех участников беседы
---
## 17. `users` ⭐ КРИТИЧЕСКАЯ
**Назначение:** Пользователи системы (основа для всех AI взаимодействий)
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор пользователя
- `created_at` - TIMESTAMP - дата создания (default: CURRENT_TIMESTAMP)
- `updated_at` - TIMESTAMP - дата обновления (default: CURRENT_TIMESTAMP)
- `role` - user_role ENUM - роль пользователя (default: 'user')
- 'user' - обычный пользователь
- 'editor' - администратор-редактор
- 'readonly' - администратор только для чтения
- `is_blocked` - BOOLEAN NOT NULL - заблокирован ли (default: false)
- `blocked_at` - TIMESTAMP - время блокировки
- `username_encrypted` - TEXT - зашифрованное имя пользователя
- `status_encrypted` - TEXT - зашифрованный статус
- `first_name_encrypted` - TEXT - зашифрованное имя
- `last_name_encrypted` - TEXT - зашифрованная фамилия
- `preferred_language` - JSONB - предпочитаемый язык
**Индексы:**
- PRIMARY KEY: id
- idx_users_role
**Связи (Referenced by):**
- ← conversation_participants (9 таблиц ссылаются!)
- ← conversations
- ← message_deduplication
- ← global_read_status
- ← guest_user_mapping
- ← messages
- ← user_identities
- ← user_preferences
- ← user_tag_links
- ← verification_codes
**Используется в:**
- identity-service.js (создание пользователей)
- auth-service.js (проверка ролей)
- userUtils.js (isUserBlocked)
- ВСЕ AI сервисы (через связи)
---
## 18. `user_identities` ⭐ КРИТИЧЕСКАЯ
**Назначение:** Идентификаторы пользователей (wallet, email, telegram)
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор
- `user_id` - INTEGER (FK → users) - ID пользователя
- `created_at` - TIMESTAMP - дата создания (default: CURRENT_TIMESTAMP)
- `provider_encrypted` - TEXT - зашифрованный провайдер ('wallet', 'email', 'telegram')
- `provider_id_encrypted` - TEXT - зашифрованный идентификатор (адрес, email, telegram ID)
**Индексы:**
- PRIMARY KEY: id
- idx_user_identities_user_id
**Связи:**
-`users` (user_id, ON DELETE CASCADE)
**Используется в:**
- identity-service.js (findUserByIdentity, saveIdentity, linkWalletToUser)
- unifiedMessageProcessor.js (authenticateUser - поиск пользователя по Telegram/Email)
- telegramBot.js, emailBot.js (связь external ID с user_id)
- routes/identities.js (управление идентификаторами)
- routes/messages.js (broadcast - поиск каналов пользователя)
**Логика:**
- Один пользователь может иметь несколько идентификаторов (wallet + email + telegram)
- При входе через любой канал - система находит или создает пользователя
---
## 19. `global_read_status` ✅ АКТИВНАЯ
**Назначение:** Глобальный статус прочтения сообщений для user_chat
**Столбцы:**
- `user_id` - INTEGER (PK, FK → users) - ID пользователя
- `last_read_at` - TIMESTAMP NOT NULL - время последнего прочитанного сообщения
- `updated_by_admin_id` - INTEGER NOT NULL - ID админа, который обновил статус
- `created_at` - TIMESTAMP - дата создания (default: CURRENT_TIMESTAMP)
- `updated_at` - TIMESTAMP - дата обновления (default: CURRENT_TIMESTAMP)
**Индексы:**
- PRIMARY KEY: user_id
- idx_global_read_status_last_read_at
- idx_global_read_status_user_id
**Связи:**
-`users` (user_id, ON DELETE CASCADE)
**Используется в:**
- routes/messages.js (mark-read, read-status для user_chat)
**Логика:**
- Один статус на пользователя (общий для всех админов)
- Для обычных чатов (`user_chat`)
- Для админских чатов используется `admin_read_messages`
---
## 20. `admin_read_messages` ✅ АКТИВНАЯ
**Назначение:** Персональный статус прочтения для admin_chat
**Столбцы:**
- `admin_id` - INTEGER NOT NULL (PK, FK → users) - ID администратора
- `user_id` - INTEGER NOT NULL (PK, FK → users) - ID пользователя/другого админа
- `last_read_at` - TIMESTAMP NOT NULL - время последнего прочитанного сообщения
**Индексы:**
- PRIMARY KEY: (admin_id, user_id) - составной ключ
**Связи:**
-`users` (admin_id, ON DELETE CASCADE) ✅ ДОБАВЛЕНО
-`users` (user_id, ON DELETE CASCADE) ✅ ДОБАВЛЕНО
**Используется в:**
- routes/messages.js (mark-read, read-status для admin_chat)
**Логика:**
- Персональный статус для каждого админа
- Для приватных чатов между админами (`admin_chat`)
- Каждый админ имеет свой статус прочтения
**Отличие от global_read_status:**
- global_read_status - общий для всех админов (user_chat)
- admin_read_messages - персональный для каждого админа (admin_chat)
---
## 21. `user_tag_links` ✅ АКТИВНАЯ
**Назначение:** Связь пользователей с тегами (для RAG фильтрации)
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор
- `user_id` - INTEGER NOT NULL (FK → users) - ID пользователя
- `tag_id` - INTEGER NOT NULL (FK → user_rows) - ID тега (строка из таблицы тегов)
- `created_at` - TIMESTAMP - дата создания (default: CURRENT_TIMESTAMP)
**Индексы:**
- PRIMARY KEY: id
- idx_user_tag_links_tag_id
- idx_user_tag_links_user_id
- user_tag_links_user_id_tag_id_key (UNIQUE) - уникальная пара (user_id, tag_id)
**Связи:**
-`users` (user_id, ON DELETE CASCADE)
-`user_rows` (tag_id, ON DELETE CASCADE) - теги хранятся как строки в RAG таблицах
**Используется в:**
- ragService.js (фильтрация данных по пользовательским тегам)
- routes/tables.js (управление тегами пользователей)
**Логика:**
- Теги позволяют фильтровать RAG данные по пользователю
- Один пользователь может иметь несколько тегов
- Используется для персонализации AI ответов
---
## 22. `roles` ⚠️ ВОЗМОЖНО УСТАРЕВШАЯ
**Назначение:** Роли пользователей (возможно старая таблица)
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор
- `created_at` - TIMESTAMP - дата создания (default: CURRENT_TIMESTAMP)
- `name_encrypted` - TEXT - зашифрованное название роли
**Индексы:**
- PRIMARY KEY: id
**Связи:**
- Нет внешних ключей
- Нет Referenced by (никто не ссылается!)
**⚠️ ПРОБЛЕМА:**
- Таблица существует, но НЕ используется
- В `users` роль хранится как ENUM `user_role`, а не FK
- Возможно старая таблица, которую можно удалить
**Используется в:**
-НЕ найдено использования в коде
---
## 23. `admin_pages` ⚠️ НЕ СВЯЗАНА С AI
**Назначение:** Страницы контента (CMS), НЕ связана с AI напрямую
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор
- `author_address_encrypted` - TEXT NOT NULL - зашифрованный адрес автора
- `created_at` - TIMESTAMP - дата создания (default: now())
- `updated_at` - TIMESTAMP - дата обновления (default: now())
- `title_encrypted` - TEXT - зашифрованный заголовок
- `summary_encrypted` - TEXT - зашифрованное краткое описание
- `content_encrypted` - TEXT - зашифрованное содержимое
- `seo_encrypted` - TEXT - зашифрованные SEO данные
- `status_encrypted` - TEXT - зашифрованный статус
- `settings_encrypted` - TEXT - зашифрованные настройки
**Индексы:**
- PRIMARY KEY: id
**Связи:**
- Нет внешних ключей
**Используется в:**
- routes/pages.js (CMS система)
-НЕ используется в AI сервисах
**Примечание:**
- Это таблица для CMS (система управления контентом)
- НЕ связана с AI ассистентом
- Упомянута в вашем списке, но к AI не относится
---
## 24. `admin_pages_simple` ⚠️ НЕ СВЯЗАНА С AI
**Назначение:** Упрощенные страницы контента БЕЗ шифрования, НЕ связана с AI
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор
- `author_address` - TEXT NOT NULL - адрес автора (НЕ зашифрован!)
- `created_at` - TIMESTAMP - дата создания (default: now())
- `updated_at` - TIMESTAMP - дата обновления (default: now())
- `title` - TEXT - заголовок (НЕ зашифрован!)
- `summary` - TEXT - краткое описание
- `content` - TEXT - содержимое
- `seo` - TEXT - SEO данные
- `status` - TEXT - статус
- `settings` - TEXT - настройки
**Индексы:**
- PRIMARY KEY: id
**Связи:**
- Нет внешних ключей
**Используется в:**
- routes/pages.js (CMS система)
-НЕ используется в AI сервисах
**Примечание:**
- Это таблица для CMS (система управления контентом)
- В отличие от `admin_pages`, данные НЕ зашифрованы
- НЕ связана с AI ассистентом
- Упомянута в вашем списке, но к AI не относится
---
## 25. `user_table_relations` ⭐ КЛЮЧЕВАЯ (RAG)
**Назначение:** Связи между строками в разных RAG таблицах (реляционная модель данных)
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор связи
- `from_row_id` - INTEGER NOT NULL (FK → user_rows) - исходная строка
- `column_id` - INTEGER NOT NULL (FK → user_columns) - колонка со связью
- `to_table_id` - INTEGER NOT NULL (FK → user_tables) - целевая таблица
- `to_row_id` - INTEGER NOT NULL (FK → user_rows) - целевая строка
- `created_at` - TIMESTAMP - дата создания (default: CURRENT_TIMESTAMP)
- `updated_at` - TIMESTAMP - дата обновления (default: CURRENT_TIMESTAMP)
**Индексы:**
- PRIMARY KEY: id
- idx_user_table_relations_column
- idx_user_table_relations_from_row
- idx_user_table_relations_to_row
- idx_user_table_relations_to_table
**Связи:**
-`user_columns` (column_id, ON DELETE CASCADE)
-`user_rows` (from_row_id, ON DELETE CASCADE)
-`user_rows` (to_row_id, ON DELETE CASCADE)
-`user_tables` (to_table_id, ON DELETE CASCADE)
**Используется в:**
- routes/tables.js (создание связей между данными)
- ragService.js (получение связанных данных для контекста)
**Логика:**
- Позволяет создавать связи "один-ко-многим" и "многие-ко-многим" между RAG данными
- Пример: FAQ вопрос → связанные продукты, документы → связанные разделы
- Используется для обогащения контекста AI ответов
**Структура связи:**
```
user_rows[from_row_id]
→ user_columns[column_id] (тип: "relation")
→ user_tables[to_table_id]
→ user_rows[to_row_id]
```
---
## 26. `admin_read_contacts` ✅ АКТИВНАЯ
**Назначение:** Статус прочтения контактов админами (для UI непрочитанных пользователей)
**Столбцы:**
- `admin_id` - INTEGER NOT NULL (PK, FK → users) - ID администратора
- `contact_id` - INTEGER NOT NULL (PK, FK → users) - ID контакта (user_id)
- `read_at` - TIMESTAMP NOT NULL - время прочтения (default: now())
**Индексы:**
- PRIMARY KEY: (admin_id, contact_id) - составной ключ
**Связи:**
-`users` (admin_id, ON DELETE CASCADE) ✅ ДОБАВЛЕНО
-`users` (contact_id, ON DELETE CASCADE) ✅ ДОБАВЛЕНО
**Используется в:**
- routes/messages.js (mark-contact-read - отметить контакт как прочитанный)
- adminLogicService.js (управление непрочитанными контактами)
**Логика:**
- Отслеживает, когда админ последний раз просматривал чат пользователя
- Используется для отображения непрочитанных контактов в списке
- Отличается от `global_read_status` (статус сообщений) и `admin_read_messages` (приватные чаты)
**Применение:**
- UI показывает список пользователей с новыми сообщениями
- Когда админ открывает чат → обновляется `read_at`
- Новые сообщения после `read_at` = непрочитанные
---
## 27. `user_preferences` ✅ АКТИВНАЯ
**Назначение:** Пользовательские настройки и предпочтения (может влиять на AI)
**Столбцы:**
- `id` - INTEGER (PK) - уникальный идентификатор
- `user_id` - INTEGER NOT NULL (FK → users) - ID пользователя
- `created_at` - TIMESTAMP NOT NULL - дата создания (default: now())
- `updated_at` - TIMESTAMP NOT NULL - дата обновления (default: now())
- `preference_key_encrypted` - TEXT - зашифрованный ключ настройки
- `preference_value_encrypted` - TEXT - зашифрованное значение настройки
- `metadata` - JSONB - дополнительные метаданные (default: '{}')
**Индексы:**
- PRIMARY KEY: id
- idx_user_preferences_user_id
**Связи:**
-`users` (user_id, ON DELETE CASCADE) ✅ ИСПРАВЛЕНО
**Используется в:**
- routes/preferences.js (CRUD настроек)
- Может использоваться для персонализации AI ответов
**Возможные настройки:**
- Язык интерфейса
- Тема оформления
- Уведомления
- Персональные предпочтения для AI (стиль общения, детальность ответов)
**Примечание:**
- В таблице `users` уже есть `preferred_language` (JSONB)
- `user_preferences` - более гибкая система для любых настроек
- Может расширяться для AI-специфичных настроек
---
## 📊 ИТОГОВАЯ СТАТИСТИКА
**Всего проверено:** 27 таблиц
**По категориям:**
- ⭐ КРИТИЧЕСКИЕ: 4 (users, user_identities, messages, conversations)
- ⭐ КЛЮЧЕВЫЕ: 10 (ai_assistant_settings, ai_providers_settings, message_deduplication, user_tables, user_columns, user_rows, user_cell_values, user_table_relations)
- ✅ АКТИВНЫЕ: 10 (ai_assistant_rules, telegram_settings, email_settings, is_rag_source, conversation_participants, global_read_status, admin_read_messages, user_tag_links, admin_read_contacts, user_preferences)
- ⚠️ ПРОБЛЕМНЫЕ: 1 (roles - не используется)
- ⚠️ НЕ СВЯЗАНЫ С AI: 2 (admin_pages, admin_pages_simple)
**Обнаруженные проблемы:**
- ~~1. `ai_assistant_rules` - отсутствует столбец `rules_encrypted`~~ ✅ ИСПРАВЛЕНО (миграция 064)
- ~~2. `user_cell_values` - нет FK на `user_columns` (column_id)~~ ✅ ИСПРАВЛЕНО (миграция 065)
- 3. `roles` - таблица существует, но не используется ⚠️ НИЗКИЙ ПРИОРИТЕТ
- ~~4. `admin_read_messages` - нет FK на users~~ ✅ ИСПРАВЛЕНО (миграция 066)
- ~~5. `admin_read_contacts` - нет FK на users~~ ✅ ИСПРАВЛЕНО (миграция 066)
- ~~6. `user_preferences` - нет ON DELETE CASCADE для user_id~~ ✅ ИСПРАВЛЕНО (миграция 067)
**Применённые миграции:**
- 064_add_rules_encrypted_to_ai_assistant_rules.sql
- 065_add_fk_user_cell_values_column_id.sql
- 066_add_fk_admin_read_tables.sql
- 067_add_cascade_user_preferences.sql
**Дата проверки:** 2025-10-08
**Дата исправлений:** 2025-10-08
**Статус:** ✅ ПРОВЕРКА ЗАВЕРШЕНА + КРИТИЧНЫЕ ПРОБЛЕМЫ ИСПРАВЛЕНЫ