# Архитектура идентификаторов пользователей ## Общая структура ### Таблицы для хранения данных пользователей Система идентификации пользователей построена на следующих таблицах: 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` - количество дублирующихся идентификаторов