b0350abfbe
- Fix DB_NAME=db_yal -> mydb in api_yal .env - Add connection pool (MaxOpenConns 25, MaxIdleConns 10, ConnMaxLifetime 30m) - Replace GORM AutoMigrate with golang-migrate in api_yal and api_bb - Create embedded SQL migrations for both APIs - Add DB_SCHEMA support to api_bb config - Consolidate to single Postgres: db_bb -> schema 'bb' on db container - Remove db_bb service, bb-network, db_bb volume from compose - Remove api_tp targets from Makefile - Clean up old migrate.go
218 lines
6.6 KiB
SQL
218 lines
6.6 KiB
SQL
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);
|