#!/bin/bash # create_consolidated_migration.sh - Создание консолидированной миграции из всех источников echo "🚀 Создание консолидированной миграции..." # Создаем каталог для миграций если его нет mkdir -p migrations # Текущее время для имени файла timestamp=$(date +%s) # Путь к консолидированной миграции consolidated_file="migrations/${timestamp}_consolidated_migration.js" echo "📝 Создание файла $consolidated_file..." # Создаем JS-миграцию cat > "$consolidated_file" << EOL /* eslint-disable camelcase */ exports.shorthands = undefined; exports.up = pgm => { // Консолидированная миграция, созданная автоматически // Создаем таблицу migrations, если её ещё нет pgm.sql(\` CREATE TABLE IF NOT EXISTS migrations ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); \`); // Создаем основную структуру базы данных pgm.sql(\` -- Таблица пользователей CREATE TABLE IF NOT EXISTS users ( id BIGINT PRIMARY KEY, username VARCHAR(255), first_name VARCHAR(255), last_name VARCHAR(255), language_code VARCHAR(10), is_bot BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, state VARCHAR(50) DEFAULT 'START', state_data JSONB, gender VARCHAR(10), looking_for VARCHAR(10), bio TEXT, age INTEGER, location VARCHAR(255), photos JSONB DEFAULT '[]'::jsonb, interests TEXT[], premium BOOLEAN DEFAULT FALSE, premium_expires_at TIMESTAMP ); -- Таблица профилей CREATE TABLE IF NOT EXISTS profiles ( id SERIAL PRIMARY KEY, user_id BIGINT REFERENCES users(id) ON DELETE CASCADE, name VARCHAR(255), age INTEGER, gender VARCHAR(10), bio TEXT, photos JSONB DEFAULT '[]'::jsonb, interests TEXT[], location VARCHAR(255), religion VARCHAR(50), education VARCHAR(255), job VARCHAR(255), height INTEGER, smoking VARCHAR(50), drinking VARCHAR(50), looking_for VARCHAR(10), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Таблица лайков CREATE TABLE IF NOT EXISTS likes ( id SERIAL PRIMARY KEY, from_user_id BIGINT REFERENCES users(id) ON DELETE CASCADE, to_user_id BIGINT REFERENCES users(id) ON DELETE CASCADE, is_like BOOLEAN NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(from_user_id, to_user_id) ); -- Таблица матчей CREATE TABLE IF NOT EXISTS matches ( id SERIAL PRIMARY KEY, user1_id BIGINT REFERENCES users(id) ON DELETE CASCADE, user2_id BIGINT REFERENCES users(id) ON DELETE CASCADE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, active BOOLEAN DEFAULT TRUE, UNIQUE(user1_id, user2_id) ); -- Таблица сообщений CREATE TABLE IF NOT EXISTS messages ( id SERIAL PRIMARY KEY, match_id INTEGER REFERENCES matches(id) ON DELETE CASCADE, sender_id BIGINT REFERENCES users(id) ON DELETE CASCADE, message_text TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Таблица просмотров профилей CREATE TABLE IF NOT EXISTS profile_views ( id SERIAL PRIMARY KEY, viewer_id BIGINT REFERENCES users(id) ON DELETE CASCADE, viewed_id BIGINT REFERENCES users(id) ON DELETE CASCADE, viewed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(viewer_id, viewed_id) ); -- Таблица уведомлений CREATE TABLE IF NOT EXISTS notifications ( id SERIAL PRIMARY KEY, user_id BIGINT REFERENCES users(id) ON DELETE CASCADE, type VARCHAR(50) NOT NULL, data JSONB, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, scheduled_for TIMESTAMP, processed BOOLEAN DEFAULT FALSE ); \`); // Индексы для оптимизации запросов pgm.sql(\` -- Индексы для таблицы пользователей CREATE INDEX IF NOT EXISTS users_username_idx ON users(username); CREATE INDEX IF NOT EXISTS users_gender_idx ON users(gender); CREATE INDEX IF NOT EXISTS users_looking_for_idx ON users(looking_for); CREATE INDEX IF NOT EXISTS users_premium_idx ON users(premium); -- Индексы для таблицы лайков CREATE INDEX IF NOT EXISTS likes_from_user_id_idx ON likes(from_user_id); CREATE INDEX IF NOT EXISTS likes_to_user_id_idx ON likes(to_user_id); CREATE INDEX IF NOT EXISTS likes_is_like_idx ON likes(is_like); -- Индексы для таблицы матчей CREATE INDEX IF NOT EXISTS matches_user1_id_idx ON matches(user1_id); CREATE INDEX IF NOT EXISTS matches_user2_id_idx ON matches(user2_id); CREATE INDEX IF NOT EXISTS matches_active_idx ON matches(active); -- Индексы для таблицы сообщений CREATE INDEX IF NOT EXISTS messages_match_id_idx ON messages(match_id); CREATE INDEX IF NOT EXISTS messages_sender_id_idx ON messages(sender_id); -- Индексы для таблицы профилей CREATE INDEX IF NOT EXISTS profiles_user_id_idx ON profiles(user_id); CREATE INDEX IF NOT EXISTS profiles_gender_idx ON profiles(gender); CREATE INDEX IF NOT EXISTS profiles_looking_for_idx ON profiles(looking_for); -- Индексы для таблицы просмотров профилей CREATE INDEX IF NOT EXISTS profile_views_viewer_id_idx ON profile_views(viewer_id); CREATE INDEX IF NOT EXISTS profile_views_viewed_id_idx ON profile_views(viewed_id); -- Индексы для таблицы уведомлений CREATE INDEX IF NOT EXISTS notifications_user_id_idx ON notifications(user_id); CREATE INDEX IF NOT EXISTS notifications_scheduled_for_idx ON notifications(scheduled_for); CREATE INDEX IF NOT EXISTS notifications_processed_idx ON notifications(processed); \`); }; exports.down = pgm => { // Эта функция не будет фактически использоваться, // но для полноты оставляем возможность отката pgm.sql(\` DROP TABLE IF EXISTS notifications; DROP TABLE IF EXISTS profile_views; DROP TABLE IF EXISTS messages; DROP TABLE IF EXISTS matches; DROP TABLE IF EXISTS likes; DROP TABLE IF EXISTS profiles; DROP TABLE IF EXISTS users; \`); }; EOL echo "✅ Консолидированная миграция создана: $consolidated_file" echo "" echo "🚀 Для применения миграции выполните:" echo "DATABASE_URL=postgres://\${DB_USERNAME}:\${DB_PASSWORD}@\${DB_HOST}:\${DB_PORT}/\${DB_NAME} npx node-pg-migrate up"