249 lines
8.7 KiB
Markdown
249 lines
8.7 KiB
Markdown
# Проверка схемы базы данных
|
||
|
||
## Таблица `users`
|
||
```sql
|
||
CREATE TABLE users (
|
||
id SERIAL PRIMARY KEY,
|
||
username VARCHAR(255),
|
||
email VARCHAR(255) UNIQUE,
|
||
address VARCHAR(255) UNIQUE,
|
||
first_name_encrypted TEXT,
|
||
last_name_encrypted TEXT,
|
||
status VARCHAR(50) DEFAULT 'active',
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
role user_role DEFAULT 'user',
|
||
first_name VARCHAR(255),
|
||
last_name VARCHAR(255),
|
||
preferred_language JSONB,
|
||
is_blocked BOOLEAN DEFAULT false,
|
||
blocked_at TIMESTAMP
|
||
);
|
||
```
|
||
|
||
**Колонки:**
|
||
- `id` - SERIAL PRIMARY KEY
|
||
- `username` - VARCHAR(255)
|
||
- `email` - VARCHAR(255) UNIQUE
|
||
- `address` - VARCHAR(255) UNIQUE
|
||
- `first_name_encrypted` - TEXT (зашифрованное)
|
||
- `last_name_encrypted` - TEXT (зашифрованное)
|
||
- `status` - VARCHAR(50) DEFAULT 'active'
|
||
- `created_at` - TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
- `updated_at` - TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
- `role` - user_role DEFAULT 'user'
|
||
- `first_name` - VARCHAR(255) (незашифрованное)
|
||
- `last_name` - VARCHAR(255) (незашифрованное)
|
||
- `preferred_language` - JSONB
|
||
- `is_blocked` - BOOLEAN DEFAULT false
|
||
- `blocked_at` - TIMESTAMP
|
||
|
||
## Таблица `conversations`
|
||
```sql
|
||
CREATE TABLE conversations (
|
||
id SERIAL PRIMARY KEY,
|
||
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
||
title VARCHAR(255),
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
conversation_type VARCHAR(50) DEFAULT 'user_chat'
|
||
);
|
||
```
|
||
|
||
**Колонки:**
|
||
- `id` - SERIAL PRIMARY KEY
|
||
- `user_id` - INTEGER REFERENCES users(id)
|
||
- `title` - VARCHAR(255) (НЕ зашифрованное!)
|
||
- `created_at` - TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
- `updated_at` - TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
- `conversation_type` - VARCHAR(50) DEFAULT 'user_chat'
|
||
|
||
## Таблица `messages`
|
||
```sql
|
||
CREATE TABLE messages (
|
||
id SERIAL PRIMARY KEY,
|
||
conversation_id INTEGER REFERENCES conversations(id) ON DELETE CASCADE,
|
||
sender_type_encrypted TEXT NOT NULL,
|
||
sender_id INTEGER,
|
||
content_encrypted TEXT,
|
||
channel_encrypted TEXT NOT NULL,
|
||
role_encrypted TEXT NOT NULL DEFAULT 'user',
|
||
direction_encrypted TEXT,
|
||
metadata JSONB,
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
||
tokens_used INTEGER DEFAULT 0,
|
||
is_processed BOOLEAN DEFAULT false,
|
||
role VARCHAR(20) NOT NULL DEFAULT 'user',
|
||
attachment_filename TEXT,
|
||
attachment_mimetype TEXT,
|
||
attachment_size BIGINT,
|
||
attachment_data BYTEA,
|
||
direction VARCHAR(8),
|
||
message_type VARCHAR(20) DEFAULT 'public'
|
||
);
|
||
```
|
||
|
||
**Колонки:**
|
||
- `id` - SERIAL PRIMARY KEY
|
||
- `conversation_id` - INTEGER REFERENCES conversations(id)
|
||
- `sender_type_encrypted` - TEXT NOT NULL (зашифрованное)
|
||
- `sender_id` - INTEGER
|
||
- `content_encrypted` - TEXT (зашифрованное)
|
||
- `channel_encrypted` - TEXT NOT NULL (зашифрованное)
|
||
- `role_encrypted` - TEXT NOT NULL DEFAULT 'user' (зашифрованное)
|
||
- `direction_encrypted` - TEXT (зашифрованное)
|
||
- `metadata` - JSONB
|
||
- `created_at` - TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
- `user_id` - INTEGER REFERENCES users(id)
|
||
- `tokens_used` - INTEGER DEFAULT 0
|
||
- `is_processed` - BOOLEAN DEFAULT false
|
||
- `role` - VARCHAR(20) NOT NULL DEFAULT 'user' (НЕ зашифрованное!)
|
||
- `attachment_filename` - TEXT
|
||
- `attachment_mimetype` - TEXT
|
||
- `attachment_size` - BIGINT
|
||
- `attachment_data` - BYTEA
|
||
- `direction` - VARCHAR(8) (НЕ зашифрованное!)
|
||
- `message_type` - VARCHAR(20) DEFAULT 'public'
|
||
|
||
**Триггеры:**
|
||
- `trg_set_message_user_id` - автоматически устанавливает user_id
|
||
|
||
## Таблица `conversation_participants`
|
||
```sql
|
||
CREATE TABLE conversation_participants (
|
||
id SERIAL PRIMARY KEY,
|
||
conversation_id INTEGER REFERENCES conversations(id) ON DELETE CASCADE,
|
||
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
UNIQUE(conversation_id, user_id)
|
||
);
|
||
```
|
||
|
||
**Колонки:**
|
||
- `id` - SERIAL PRIMARY KEY
|
||
- `conversation_id` - INTEGER REFERENCES conversations(id)
|
||
- `user_id` - INTEGER REFERENCES users(id)
|
||
- `created_at` - TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
|
||
**Индексы:**
|
||
- PRIMARY KEY на `id`
|
||
- UNIQUE CONSTRAINT на `(conversation_id, user_id)`
|
||
- Индекс на `conversation_id`
|
||
- Индекс на `user_id`
|
||
|
||
## Таблица `admin_read_messages`
|
||
```sql
|
||
CREATE TABLE admin_read_messages (
|
||
admin_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||
last_read_at TIMESTAMP NOT NULL,
|
||
PRIMARY KEY (admin_id, user_id)
|
||
);
|
||
```
|
||
|
||
**Колонки:**
|
||
- `admin_id` - INTEGER NOT NULL REFERENCES users(id) (админ)
|
||
- `user_id` - INTEGER NOT NULL REFERENCES users(id) (пользователь)
|
||
- `last_read_at` - TIMESTAMP NOT NULL (время последнего прочтения)
|
||
|
||
**Индексы:**
|
||
- PRIMARY KEY на `(admin_id, user_id)`
|
||
|
||
## Таблица `admin_read_contacts`
|
||
```sql
|
||
CREATE TABLE admin_read_contacts (
|
||
admin_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||
contact_id TEXT NOT NULL,
|
||
read_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||
PRIMARY KEY (admin_id, contact_id)
|
||
);
|
||
```
|
||
|
||
**Колонки:**
|
||
- `admin_id` - INTEGER NOT NULL REFERENCES users(id) (админ)
|
||
- `contact_id` - TEXT NOT NULL (ID контакта)
|
||
- `read_at` - TIMESTAMP NOT NULL DEFAULT NOW() (время прочтения)
|
||
|
||
**Индексы:**
|
||
- PRIMARY KEY на `(admin_id, contact_id)`
|
||
- Индекс на `admin_id`
|
||
- Индекс на `contact_id`
|
||
|
||
## Таблица `user_identities`
|
||
```sql
|
||
CREATE TABLE user_identities (
|
||
id SERIAL PRIMARY KEY,
|
||
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
||
provider_encrypted TEXT NOT NULL,
|
||
provider_id_encrypted TEXT NOT NULL,
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
```
|
||
|
||
**Колонки:**
|
||
- `id` - SERIAL PRIMARY KEY
|
||
- `user_id` - INTEGER REFERENCES users(id) (пользователь)
|
||
- `provider_encrypted` - TEXT NOT NULL (зашифрованный провайдер)
|
||
- `provider_id_encrypted` - TEXT NOT NULL (зашифрованный ID провайдера)
|
||
- `created_at` - TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
|
||
**Индексы:**
|
||
- PRIMARY KEY на `id`
|
||
- Индекс на `user_id`
|
||
|
||
## Таблица `user_preferences`
|
||
```sql
|
||
CREATE TABLE user_preferences (
|
||
id SERIAL PRIMARY KEY,
|
||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||
preference_key VARCHAR(50) NOT NULL,
|
||
preference_value TEXT,
|
||
metadata JSONB DEFAULT '{}',
|
||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||
UNIQUE(user_id, preference_key)
|
||
);
|
||
```
|
||
|
||
**Колонки:**
|
||
- `id` - SERIAL PRIMARY KEY
|
||
- `user_id` - INTEGER NOT NULL REFERENCES users(id) (пользователь)
|
||
- `preference_key` - VARCHAR(50) NOT NULL (ключ настройки)
|
||
- `preference_value` - TEXT (значение настройки)
|
||
- `metadata` - JSONB DEFAULT '{}' (метаданные)
|
||
- `created_at` - TIMESTAMP NOT NULL DEFAULT NOW()
|
||
- `updated_at` - TIMESTAMP NOT NULL DEFAULT NOW()
|
||
|
||
**Индексы:**
|
||
- PRIMARY KEY на `id`
|
||
- Индекс на `user_id`
|
||
- UNIQUE CONSTRAINT на `(user_id, preference_key)`
|
||
|
||
## Таблица `user_tag_links`
|
||
```sql
|
||
CREATE TABLE user_tag_links (
|
||
id SERIAL PRIMARY KEY,
|
||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||
tag_id INTEGER NOT NULL REFERENCES user_rows(id) ON DELETE CASCADE,
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
UNIQUE(user_id, tag_id)
|
||
);
|
||
```
|
||
|
||
**Колонки:**
|
||
- `id` - SERIAL PRIMARY KEY
|
||
- `user_id` - INTEGER NOT NULL REFERENCES users(id) (пользователь)
|
||
- `tag_id` - INTEGER NOT NULL REFERENCES user_rows(id) (тег)
|
||
- `created_at` - TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
|
||
**Индексы:**
|
||
- PRIMARY KEY на `id`
|
||
- Индекс на `user_id`
|
||
- Индекс на `tag_id`
|
||
- UNIQUE CONSTRAINT на `(user_id, tag_id)`
|
||
|
||
## Анализ проблем в коде
|
||
|
||
Теперь, имея полную схему базы данных, давайте проверим код на соответствие:
|