CREATE TABLE IF NOT EXISTS users ( id BIGSERIAL PRIMARY KEY, email VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL, first_name VARCHAR(255) NOT NULL, last_name VARCHAR(255) NOT NULL, avatar VARCHAR(255), phone VARCHAR(255), experience VARCHAR(255), goals VARCHAR(255), newsletter BOOLEAN DEFAULT FALSE, role VARCHAR(255) DEFAULT 'user', created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ, deleted_at TIMESTAMPTZ, email_verified BOOLEAN DEFAULT FALSE, verified_at TIMESTAMPTZ ); CREATE UNIQUE INDEX IF NOT EXISTS idx_users_email ON users(email); CREATE INDEX IF NOT EXISTS idx_users_deleted_at ON users(deleted_at); CREATE TABLE IF NOT EXISTS news ( id BIGSERIAL PRIMARY KEY, created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ, deleted_at TIMESTAMPTZ, title VARCHAR(255) NOT NULL, excerpt VARCHAR(500) NOT NULL, content TEXT NOT NULL, image VARCHAR(255), category VARCHAR(20) NOT NULL, views BIGINT DEFAULT 0, author_id BIGINT NOT NULL ); CREATE INDEX IF NOT EXISTS idx_news_deleted_at ON news(deleted_at); CREATE TABLE IF NOT EXISTS comments ( id BIGSERIAL PRIMARY KEY, created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ, content TEXT NOT NULL, news_id BIGINT NOT NULL, author_id BIGINT NOT NULL ); CREATE TABLE IF NOT EXISTS reviews ( id BIGSERIAL PRIMARY KEY, created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ, deleted_at TIMESTAMPTZ, rating BIGINT NOT NULL, text TEXT NOT NULL, achievement VARCHAR(255), distance VARCHAR(50), improvement VARCHAR(100), trainings BIGINT DEFAULT 0, verified BOOLEAN DEFAULT FALSE, author_id BIGINT NOT NULL ); CREATE INDEX IF NOT EXISTS idx_reviews_deleted_at ON reviews(deleted_at); CREATE TABLE IF NOT EXISTS user_stats ( id BIGSERIAL PRIMARY KEY, user_id BIGINT NOT NULL, total_distance DECIMAL(10,2) DEFAULT 0, total_time BIGINT DEFAULT 0, avg_pace VARCHAR(20), workouts_count BIGINT DEFAULT 0, current_streak BIGINT DEFAULT 0, longest_streak BIGINT DEFAULT 0, weekly_distance DECIMAL(8,2) DEFAULT 0, monthly_distance DECIMAL(8,2) DEFAULT 0, best_5k VARCHAR(20), best_10k VARCHAR(20), best_half VARCHAR(20), best_marathon VARCHAR(20), last_workout TIMESTAMPTZ, created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ ); CREATE UNIQUE INDEX IF NOT EXISTS idx_user_stats_user_id ON user_stats(user_id); CREATE TABLE IF NOT EXISTS workouts ( id BIGSERIAL PRIMARY KEY, user_id BIGINT NOT NULL, type VARCHAR(20) NOT NULL, distance_km DECIMAL(5,2) NOT NULL, duration_min BIGINT NOT NULL, pace VARCHAR(20), calories BIGINT DEFAULT 0, notes TEXT, date TIMESTAMPTZ NOT NULL, created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ ); CREATE INDEX IF NOT EXISTS idx_workouts_user_id ON workouts(user_id); CREATE INDEX IF NOT EXISTS idx_workouts_date ON workouts(date); CREATE TABLE IF NOT EXISTS achievements ( id BIGSERIAL PRIMARY KEY, user_id BIGINT NOT NULL, type VARCHAR(20) NOT NULL, title VARCHAR(255) NOT NULL, description TEXT, result VARCHAR(100), distance VARCHAR(50), date TIMESTAMPTZ NOT NULL, verified BOOLEAN DEFAULT FALSE, badge_image VARCHAR(500), created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ ); CREATE INDEX IF NOT EXISTS idx_achievements_user_id ON achievements(user_id); CREATE TABLE IF NOT EXISTS events ( id BIGSERIAL PRIMARY KEY, title VARCHAR(255) NOT NULL, description TEXT NOT NULL, date TIMESTAMPTZ NOT NULL, location VARCHAR(255) NOT NULL, type VARCHAR(50) NOT NULL, distance VARCHAR(50), participants_count BIGINT DEFAULT 0, max_participants BIGINT DEFAULT 0, registration_open BOOLEAN DEFAULT TRUE, image VARCHAR(500), created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ ); CREATE TABLE IF NOT EXISTS event_registrations ( id BIGSERIAL PRIMARY KEY, user_id BIGINT NOT NULL, event_id BIGINT NOT NULL, status VARCHAR(50) DEFAULT 'pending', notes TEXT, result_time VARCHAR(20), created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ ); CREATE TABLE IF NOT EXISTS personal_bests ( id BIGSERIAL PRIMARY KEY, user_id BIGINT NOT NULL, distance_type VARCHAR(20) NOT NULL, time VARCHAR(20) NOT NULL, pace VARCHAR(20), date TIMESTAMPTZ NOT NULL, verified BOOLEAN DEFAULT FALSE, event_name VARCHAR(255), location VARCHAR(255), created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ ); CREATE INDEX IF NOT EXISTS idx_personal_bests_user_id ON personal_bests(user_id); CREATE TABLE IF NOT EXISTS training_plans ( id BIGSERIAL PRIMARY KEY, user_id BIGINT NOT NULL, title VARCHAR(255) NOT NULL, description TEXT, weeks BIGINT NOT NULL DEFAULT 12, workouts_per_week BIGINT NOT NULL DEFAULT 3, target_distance VARCHAR(50), target_date TIMESTAMPTZ, current_week BIGINT DEFAULT 1, completed BOOLEAN DEFAULT FALSE, created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ ); CREATE INDEX IF NOT EXISTS idx_training_plans_user_id ON training_plans(user_id); CREATE TABLE IF NOT EXISTS training_workouts ( id BIGSERIAL PRIMARY KEY, plan_id BIGINT NOT NULL, week BIGINT NOT NULL, day BIGINT NOT NULL, type VARCHAR(20) NOT NULL, description TEXT, distance_km DECIMAL(5,2), duration_min BIGINT, completed BOOLEAN DEFAULT FALSE, completed_at TIMESTAMPTZ, created_at TIMESTAMPTZ ); CREATE INDEX IF NOT EXISTS idx_training_workouts_plan_id ON training_workouts(plan_id); CREATE TABLE IF NOT EXISTS email_verifications ( id BIGSERIAL PRIMARY KEY, user_id BIGINT NOT NULL, token VARCHAR(100) NOT NULL, email VARCHAR(255) NOT NULL, type VARCHAR(20) NOT NULL, expires_at TIMESTAMPTZ NOT NULL, used BOOLEAN DEFAULT FALSE, created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ, deleted_at TIMESTAMPTZ ); CREATE INDEX IF NOT EXISTS idx_email_verifications_user_id ON email_verifications(user_id); CREATE UNIQUE INDEX IF NOT EXISTS idx_email_verifications_token ON email_verifications(token); CREATE INDEX IF NOT EXISTS idx_email_verifications_deleted_at ON email_verifications(deleted_at); CREATE TABLE IF NOT EXISTS galleries ( id BIGSERIAL PRIMARY KEY, title VARCHAR(255) NOT NULL, description TEXT, image_path VARCHAR(500) NOT NULL, category VARCHAR(20) NOT NULL, author_id BIGINT NOT NULL, event_date TIMESTAMPTZ, views BIGINT DEFAULT 0, likes BIGINT DEFAULT 0, created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ ); CREATE INDEX IF NOT EXISTS idx_galleries_author_id ON galleries(author_id);