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