Files
DLE/backend/docs/identity_architecture.md

138 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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