ваше сообщение коммита
This commit is contained in:
130
backend/docs/identity_architecture.md
Normal file
130
backend/docs/identity_architecture.md
Normal 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` - количество дублирующихся идентификаторов
|
||||
74
backend/docs/migration_guide.md
Normal file
74
backend/docs/migration_guide.md
Normal 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();
|
||||
```
|
||||
Reference in New Issue
Block a user