135 lines
7.3 KiB
SQL
135 lines
7.3 KiB
SQL
-- Пользователи
|
|
CREATE TABLE users (
|
|
id SERIAL PRIMARY KEY,
|
|
username VARCHAR(50) NOT NULL UNIQUE,
|
|
avatar TEXT NOT NULL DEFAULT 'https://s3.regru.cloud/tailly/default_avatar.jpg',
|
|
email VARCHAR(255) NOT NULL UNIQUE,
|
|
email_confirmation_token VARCHAR(255),
|
|
email_confirmed_at TIMESTAMP WITH TIME ZONE,
|
|
password VARCHAR(255) NOT NULL,
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Устройства
|
|
CREATE TABLE devices (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
name VARCHAR(100) NOT NULL,
|
|
ip_address VARCHAR(45) NOT NULL,
|
|
user_agent TEXT NOT NULL,
|
|
confirmation_token VARCHAR(255),
|
|
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Сессии
|
|
CREATE TABLE sessions (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
device_id INTEGER NOT NULL REFERENCES devices(id) ON DELETE CASCADE,
|
|
started_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
ended_at TIMESTAMP WITH TIME ZONE,
|
|
is_current BOOLEAN DEFAULT FALSE
|
|
);
|
|
|
|
-- Посты
|
|
CREATE TABLE posts (
|
|
id SERIAL PRIMARY KEY,
|
|
title VARCHAR(255) NOT NULL,
|
|
content TEXT NOT NULL,
|
|
author_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Комментарии
|
|
CREATE TABLE comments (
|
|
id SERIAL PRIMARY KEY,
|
|
content TEXT NOT NULL,
|
|
post_id INTEGER NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
|
|
author_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Лайки
|
|
CREATE TABLE likes (
|
|
id SERIAL PRIMARY KEY,
|
|
post_id INTEGER NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
UNIQUE(post_id, user_id) -- Один лайк на пост от пользователя
|
|
);
|
|
|
|
-- Чаты
|
|
CREATE TABLE chats (
|
|
id SERIAL PRIMARY KEY,
|
|
user1_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
user2_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
UNIQUE(user1_id, user2_id), -- Уникальный чат между двумя пользователями
|
|
CHECK (user1_id < user2_id) -- Предотвращение дублирования чатов (1-2 и 2-1)
|
|
);
|
|
-- Сообщения
|
|
CREATE TABLE messages (
|
|
id SERIAL PRIMARY KEY,
|
|
chat_id INTEGER NOT NULL REFERENCES chats(id) ON DELETE CASCADE,
|
|
sender_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
receiver_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
content TEXT NOT NULL,
|
|
status VARCHAR(20) NOT NULL DEFAULT 'sent' CHECK (status IN ('sent', 'delivered', 'read')),
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Методы восстановления
|
|
CREATE TABLE recovery_methods (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
method_type VARCHAR(20) NOT NULL CHECK (method_type IN ('email', 'phone', 'totp')),
|
|
value VARCHAR(255) NOT NULL, -- email/phone number
|
|
is_primary BOOLEAN NOT NULL DEFAULT FALSE,
|
|
verified_at TIMESTAMP WITH TIME ZONE,
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Запросы восстановления
|
|
CREATE TABLE recovery_requests (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
token VARCHAR(255) NOT NULL,
|
|
new_device_id INTEGER REFERENCES devices(id) ON DELETE SET NULL,
|
|
status VARCHAR(20) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'completed', 'expired')),
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
expires_at TIMESTAMP WITH TIME ZONE NOT NULL
|
|
);
|
|
|
|
-- Аудит
|
|
CREATE TABLE audit_logs (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
|
action VARCHAR(50) NOT NULL,
|
|
entity_type VARCHAR(50) NOT NULL,
|
|
entity_id INTEGER,
|
|
ip_address VARCHAR(45) NOT NULL,
|
|
user_agent TEXT NOT NULL,
|
|
metadata JSONB,
|
|
status VARCHAR(20) NOT NULL CHECK (status IN ('success', 'failed')),
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Индексы для улучшения производительности
|
|
CREATE INDEX idx_sessions_user_id ON sessions(user_id);
|
|
CREATE INDEX idx_sessions_device_id ON sessions(device_id);
|
|
CREATE INDEX idx_posts_author_id ON posts(author_id);
|
|
CREATE INDEX idx_comments_post_id ON comments(post_id);
|
|
CREATE INDEX idx_comments_author_id ON comments(author_id);
|
|
CREATE INDEX idx_likes_post_id ON likes(post_id);
|
|
CREATE INDEX idx_likes_user_id ON likes(user_id);
|
|
CREATE INDEX idx_messages_chat_id ON messages(chat_id);
|
|
CREATE INDEX idx_messages_sender_id ON messages(sender_id);
|
|
CREATE INDEX idx_messages_receiver_id ON messages(receiver_id);
|
|
CREATE INDEX idx_recovery_requests_user_id ON recovery_requests(user_id);
|
|
CREATE INDEX idx_recovery_requests_token ON recovery_requests(token);
|
|
CREATE INDEX idx_audit_logs_user_id ON audit_logs(user_id);
|
|
CREATE INDEX idx_audit_logs_created_at ON audit_logs(created_at); |