ваше сообщение коммита

This commit is contained in:
2025-04-15 19:30:56 +03:00
parent 25baf18187
commit 9a93e7bbcb
14 changed files with 3234 additions and 1529 deletions

View File

@@ -0,0 +1,130 @@
# Архитектура идентификаторов пользователей
## Общая структура
### Таблицы для хранения данных пользователей
Система идентификации пользователей построена на следующих таблицах:
1. **users** - Основная таблица пользователей
- `id SERIAL PRIMARY KEY` - Основной идентификатор пользователя
- `status` - Статус пользователя (active, blocked)
- `role` - Роль пользователя (user, admin)
- `created_at`, `updated_at` - Временные метки
- Поля `username`, `email` и `address` являются устаревшими и должны быть NULL
2. **user_identities** - Таблица идентификаторов пользователей
- `id SERIAL PRIMARY KEY` - Идентификатор записи
- `user_id INTEGER REFERENCES users(id)` - Ссылка на пользователя
- `provider VARCHAR(50)` - Тип идентификатора (email, wallet, telegram, username)
- `provider_id VARCHAR(255)` - Значение идентификатора (должно быть в нижнем регистре для email и wallet)
- Уникальный составной ключ `(provider, provider_id)`
- Ограничение `CHECK (provider IN ('email', 'wallet', 'telegram', 'username'))` - запрещает тип 'guest'
3. **guest_user_mapping** - Таблица связи гостевых идентификаторов с пользователями
- `id SERIAL PRIMARY KEY` - Идентификатор записи
- `user_id INTEGER REFERENCES users(id)` - Ссылка на пользователя
- `guest_id VARCHAR(255)` - Гостевой идентификатор
- `processed BOOLEAN` - Флаг обработки гостевых сообщений
- Уникальный ключ `guest_id`
4. **messages** - Таблица сообщений
- `id SERIAL PRIMARY KEY` - Идентификатор сообщения
- `conversation_id INTEGER REFERENCES conversations(id)` - Ссылка на диалог
- `user_id INTEGER REFERENCES users(id)` - Прямая ссылка на пользователя
- `content TEXT` - Содержание сообщения
- `sender_type`, `role` - Тип отправителя и роль (user/assistant)
5. **guest_messages** - Таблица гостевых сообщений
- `id SERIAL PRIMARY KEY` - Идентификатор гостевого сообщения
- `guest_id VARCHAR(255)` - Идентификатор гостя
- `content TEXT` - Содержание сообщения
- `is_ai BOOLEAN` - Флаг, указывающий на сообщение от AI
## Процесс аутентификации и работа с гостевыми сообщениями
### Гостевой доступ
1. Гость (неаутентифицированный пользователь) начинает взаимодействие с системой
2. Для гостя генерируется уникальный `guest_id`, который сохраняется в localStorage браузера
3. Гостевые сообщения сохраняются в таблице `guest_messages` с привязкой к `guest_id`
4. Локально сообщения также хранятся в localStorage
### Аутентификация пользователя
1. Когда гость аутентифицируется (через email, wallet или telegram):
- Создается запись в таблице `users`
- Создается запись в таблице `user_identities` с соответствующим провайдером
- Гостевой ID сохраняется в таблице `guest_user_mapping` (не в user_identities)
2. После аутентификации система автоматически обрабатывает гостевые сообщения:
- Вызывается метод `linkGuestMessages`
- Создается новый диалог для гостевых сообщений
- Гостевые сообщения переносятся в таблицу `messages` с привязкой к пользователю
- Обработанные гостевые сообщения удаляются из `guest_messages`
- Запись в `guest_user_mapping` помечается как `processed = true`
### Объединение пользователей
Если пользователь аутентифицируется разными способами, система может объединить его данные:
1. Система проверяет связанных пользователей через `user_identities`
2. Если находятся связанные пользователи, вызывается метод `migrateUserData`
3. Данные от вторичных аккаунтов мигрируют к основному:
- Идентификаторы в таблице `user_identities`
- Гостевые связи в таблице `guest_user_mapping`
- Сообщения с прямым указанием `user_id`
- Диалоги
- Настройки
## Ограничения и правила
1. Тип провайдера `guest` запрещен в таблице `user_identities` (проверяется ограничением CHECK)
2. Гостевые идентификаторы хранятся только в таблице `guest_user_mapping`
3. Все идентификаторы email и wallet должны храниться в нижнем регистре
4. Таблица `messages` имеет прямую связь с пользователем через поле `user_id`
5. Сообщения всегда связаны с конкретным пользователем и диалогом
6. В таблице `users` поля `username`, `email` и `address` должны быть NULL
## Обработка ошибок
1. Если возникает ошибка при обработке гостевых сообщений, система:
- Логирует ошибку
- Продолжает попытки обработки при следующих авторизациях
- Не удаляет гостевые сообщения до успешной обработки
2. Если гостевые сообщения уже обработаны, повторная обработка пропускается
## Оптимизации
1. Индексы созданы для всех полей, используемых в запросах:
- `user_identities(user_id)`
- `user_identities(provider, provider_id)`
- `guest_user_mapping(guest_id)`
- `guest_user_mapping(user_id)`
- `messages(user_id)`
- `messages(conversation_id)`
2. Триггеры автоматически поддерживают целостность данных:
- Автоматическое заполнение `user_id` в таблице `messages`
- Очистка неиспользуемых полей в таблице `users`
3. Ограничения предотвращают некорректные данные:
- Запрет на использование провайдера `guest` в таблице `user_identities`
- Уникальность `guest_id` в таблице `guest_user_mapping`
- Ограничение допустимых значений для поля `provider`
## Функции для диагностики
1. **verify_migration_017()** - проверяет состояние гостевых идентификаторов
- `guest_identities_count` - количество гостевых идентификаторов в таблице user_identities
- `guest_mapping_count` - количество записей в таблице guest_user_mapping
- `missing_mappings` - количество гостевых ID, которые отсутствуют в guest_user_mapping
2. **verify_identity_data()** - проверяет общее состояние данных идентификаторов
- `users_with_address` - количество пользователей с заполненным полем address
- `users_with_email` - количество пользователей с заполненным полем email
- `wallet_identities` - количество идентификаторов wallet
- `email_identities` - количество идентификаторов email
- `telegram_identities` - количество идентификаторов telegram
- `duplicate_provider_ids` - количество дублирующихся идентификаторов

View File

@@ -0,0 +1,74 @@
# Руководство по миграциям базы данных
## Общая информация
Система миграций базы данных предназначена для поддержания структуры базы данных в актуальном состоянии и обеспечения возможности обновления между версиями приложения.
## Структура миграций
Миграции размещены в папке `backend/db/migrations/` и именуются по схеме `XXX_descriptive_name.sql`, где XXX - порядковый номер миграции.
### Категории миграций
1. **Основные структурные миграции** (001-013) - создание базовых таблиц и первоначальной структуры
2. **Функциональные миграции** - изменения, связанные с конкретными функциями
3. **Рефакторинг и оптимизация** (019+) - улучшение существующей структуры
## Важные миграции
### 019_identity_system_refactor.sql
Комплексная миграция, объединяющая несколько предыдущих миграций (014-018) для улучшения системы идентификации пользователей:
- Создание таблицы `guest_user_mapping` для связи гостевых идентификаторов с пользователями
- Добавление прямой связи между сообщениями и пользователями через поле `user_id`
- Очистка дублирующихся данных между таблицами `users` и `user_identities`
- Нормализация формата идентификаторов (приведение к нижнему регистру)
- Добавление ограничений и триггеров для поддержания целостности данных
## Применение миграций
При развертывании новой версии приложения миграции применяются автоматически через скрипт `backend/db/run-migrations.js`. Порядок применения определяется порядковым номером в имени файла.
## Создание новых миграций
1. **Именование**: Используйте следующий свободный порядковый номер и описательное имя
2. **Идемпотентность**: Миграции должны быть безопасны для повторного выполнения
3. **Проверки**: Добавляйте проверки существования объектов перед их созданием
4. **Тестирование**: Проверяйте миграцию на тестовой базе данных перед применением
Пример правильной идемпотентной миграции:
```sql
-- Создание таблицы, если она не существует
CREATE TABLE IF NOT EXISTS example_table (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL
);
-- Добавление колонки, если она отсутствует
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'example_table' AND column_name = 'new_column'
) THEN
ALTER TABLE example_table ADD COLUMN new_column INTEGER;
END IF;
END $$;
```
## Архивация устаревших миграций
Устаревшие миграции, объединенные в более новые версии, перемещаются в папку `backend/db/migrations/archive/`. Для архивации используйте скрипт `backend/scripts/cleanup_migrations.sh`.
## Диагностические функции
Для проверки состояния базы данных и корректности миграций созданы следующие диагностические функции SQL:
- `verify_identity_system()` - проверка состояния системы идентификации пользователей
Пример использования:
```sql
SELECT * FROM verify_identity_system();
```