Загрузка данных
-- ================================================================
-- SQL DDL TEMPLATE (TOPIC 04)
-- ================================================================
-- WHAT SHOULD BE ADDED HERE:
-- 1) Full PostgreSQL DDL for your finalized schema.
-- 2) CREATE TABLE statements for all entities from your ER diagram.
-- 3) Primary keys, foreign keys, NOT NULL, UNIQUE, CHECK constraints.
-- 4) Indexes for important search/join columns.
-- 5) Clean structure and comments (group by tables/constraints/indexes).
--
-- RECOMMENDED ORDER:
-- 1) Tables
-- 2) Constraints (if not inline)
-- 3) Indexes
--
-- TEAM NOTE:
-- Add short attribution comments for who implemented which part.
-- Example:
-- [Name] - users, roles, permissions tables
-- [Name] - orders, payments, invoices tables
--
-- IMPORTANT:
-- The script must run in PostgreSQL and produce a working schema that
-- matches your approved ER diagram and conceptual schema.
-- Submit this as one SQL file.
-- ================================================================
-- Add your DDL below this line
CREATE SCHEMA FitServe;
-- ENUMs
CREATE TYPE FitServe.sex_type AS ENUM ( -- Oleksii
'Male',
'Female',
'Other'
);
CREATE TYPE FitServe.role_type AS ENUM ( -- Oleksii
'Administrator',
'Athlete',
'Trainer'
);
CREATE TYPE FitServe.achievement_rate_type AS ENUM ( -- Oleksii
'Bronze',
'Silver',
'Gold',
'Platinum',
'Diamond'
);
CREATE TYPE FitServe.interest_rate_type AS ENUM ( -- Oleksii
'Bronze',
'Silver',
'Gold',
'Platinum',
'Diamond'
);
CREATE TYPE FitServe.contract_type_enum AS ENUM ( -- Oleksii
'individual',
'salaried',
'both'
);
CREATE TYPE FitServe.severity_level AS ENUM ( -- Oleksii
'mild',
'moderate',
'severe'
);
CREATE TYPE FitServe.studio_name_enum AS ENUM ( -- lily
'aerobics',
'yoga',
'pilates',
'weightlifting',
'cycling',
'powerlifting',
'boxing',
'swimming_pool',
'gymnastics'
);
CREATE TYPE FitServe.booking_status_enum AS ENUM ( -- lily
'planned',
'confirmed',
'completed',
'cancelled'
);
CREATE TYPE FitServe.status_type AS ENUM ( -- Oleksii
'ready',
'repairing',
'occupied'
);
CREATE TYPE FitServe.warranty_type AS ENUM ( -- Oleksii
'full',
'partial'
);
CREATE TYPE FitServe.payment_status_type AS ENUM ( -- Oleksii
'unpaid',
'in_process',
'completed'
);
-- TABLEs
CREATE TABLE FitServe.user_info ( -- Oleksii
user_info_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
registration_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
date_of_birth DATE NOT NULL,
phone_number VARCHAR(20) NOT NULL UNIQUE,
sex FitServe.sex_type NOT NULL,
preferred_pronouns VARCHAR(20),
address VARCHAR(255) NOT NULL,
CONSTRAINT chk_user_info_minimum_age
CHECK (
registration_date >= date_of_birth + INTERVAL '14 years'
) -- lily-CHECK
);
CREATE TABLE FitServe.users ( -- Oleksii
user_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
role FitServe.role_type NOT NULL,
login varchar(255) NOT NULL UNIQUE,
password_hash varchar(1024) NOT NULL,
user_info_id INTEGER,
CONSTRAINT uq_users_user_info_role -- lily-UNIQUE
UNIQUE (user_info_id, role),
FOREIGN KEY (user_info_id) REFERENCES FitServe.user_info(user_info_id)
);
CREATE TABLE FitServe.interest_rate ( -- Oleksii
interest_rate_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
trainer_share_rate NUMERIC(5, 2) NOT NULL,
trainer_rate FitServe.interest_rate_type NOT NULL,
CONSTRAINT chk_interest_rate_share_range
CHECK (trainer_share_rate BETWEEN 0 AND 100) -- lily-CHECK
);
CREATE TABLE FitServe.trainers ( -- Oleksii
trainer_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
contract_type FitServe.contract_type_enum NOT NULL,
user_id INTEGER NOT NULL UNIQUE,
interest_rate_id INTEGER UNIQUE,
FOREIGN KEY (user_id) REFERENCES FitServe.users(user_id),
FOREIGN KEY (interest_rate_id) REFERENCES FitServe.interest_rate(interest_rate_id)
);
CREATE TABLE FitServe.trainer_specialization ( -- Oleksii
trainer_specialization_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
specialization_name VARCHAR(100) NOT NULL,
trainer_id INTEGER NOT NULL,
FOREIGN KEY (trainer_id) REFERENCES FitServe.trainers(trainer_id)
);
CREATE TABLE FitServe.certifications ( -- Oleksii
certification_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
certification_link VARCHAR(500) NOT NULL UNIQUE,
receiving_date DATE,
trainer_specialization_id INTEGER NOT NULL,
FOREIGN KEY (trainer_specialization_id) REFERENCES FitServe.trainer_specialization(trainer_specialization_id)
);
CREATE TABLE FitServe.athletes( -- Andriy
athlete_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
goals VARCHAR(1500) NOT NULL,
user_id INTEGER NOT NULL UNIQUE,
FOREIGN KEY (user_id) REFERENCES FitServe.users(user_id)
);
CREATE TABLE FitServe.achievements ( -- Andriy
achievement_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR(100) NOT NULL,
category VARCHAR(50),
tier FitServe.achievement_rate_type NOT NULL,
description VARCHAR(255) NOT NULL,
target_value SMALLINT NOT NULL,
CONSTRAINT chk_achievements_target_positive
CHECK (target_value > 0) -- lily-CHECK
);
CREATE TABLE FitServe.athlete_achievement( -- Andriy
athlete_achievement_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
achievement_id INTEGER NOT NULL,
athlete_id INTEGER NOT NULL,
date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
current_state SMALLINT,
UNIQUE (achievement_id, athlete_id),
CONSTRAINT chk_athlete_achievement_date_not_future
CHECK (date <= CURRENT_TIMESTAMP), -- lily-CHECK
CONSTRAINT chk_athlete_achievement_state_nonnegative
CHECK (current_state >= 0), -- lily-CHECK
FOREIGN KEY (achievement_id) REFERENCES FitServe.achievements(achievement_id),
FOREIGN KEY (athlete_id) REFERENCES FitServe.athletes(athlete_id)
);
CREATE TABLE FitServe.body_metrics( -- Andriy
metric_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
date DATE NOT NULL DEFAULT NOW(),
weight NUMERIC(4,1) NOT NULL,
athlete_id INTEGER NOT NULL,
CONSTRAINT chk_body_metrics_date_not_future
CHECK (date <= CURRENT_DATE), -- lily-CHECK
CONSTRAINT chk_body_metrics_weight_range
CHECK (weight BETWEEN 40.0 AND 200.0), -- lily-CHECK
FOREIGN KEY (athlete_id) REFERENCES FitServe.athletes(athlete_id)
);
CREATE TABLE FitServe.health_restriction( -- Andriy
health_restriction_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
description VARCHAR(4000) NOT NULL,
severity_level FitServe.severity_level NOT NULL,
athlete_id INTEGER NOT NULL,
FOREIGN KEY (athlete_id) REFERENCES FitServe.athletes(athlete_id)
);
CREATE TABLE FitServe.nutrition( -- Andriy
nutrition_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
date DATE NOT NULL DEFAULT NOW(),
calories SMALLINT NOT NULL,
carbs_weight SMALLINT,
fat_weight SMALLINT,
athlete_id INTEGER NOT NULL,
CONSTRAINT chk_nutrition_calories_nonnegative
CHECK (calories >= 0), -- lily-CHECK
CONSTRAINT chk_nutrition_carbs
CHECK (carbs_weight >= 0 AND carbs_weight < 1000), -- lily-CHECK
CONSTRAINT chk_nutrition_fat
CHECK (fat_weight >= 0 AND fat_weight < 1000), -- lily-CHECK
FOREIGN KEY (athlete_id) REFERENCES FitServe.athletes(athlete_id)
);
CREATE TABLE FitServe.protein( -- Andriy
protein_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
weight SMALLINT NOT NULL,
type VARCHAR(50) NOT NULL,
nutrition_id BIGINT NOT NULL,
CONSTRAINT chk_protein_weight
CHECK (weight > 0 AND weight < 2000), -- lily-CHECK !
FOREIGN KEY (nutrition_id) REFERENCES FitServe.nutrition(nutrition_id)
);
CREATE TABLE FitServe.studios ( -- lily
studio_id SMALLINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
studio_name FitServe.studio_name_enum NOT NULL UNIQUE,
max_capacity INTEGER NOT NULL,
studio_status BOOLEAN NOT NULL DEFAULT TRUE,
CONSTRAINT chk_studios_capacity
CHECK (max_capacity > 0 AND max_capacity < 500) -- lily-CHECK
);
CREATE TABLE FitServe.studio_type ( -- lily
studio_type_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
activity_name VARCHAR(50) NOT NULL,
studio_id INTEGER NOT NULL,
UNIQUE (studio_id, activity_name),
CONSTRAINT chk_studio_type_activity_not_blank
CHECK (TRIM(activity_name) <> ''),
FOREIGN KEY (studio_id) REFERENCES FitServe.studios(studio_id)
);
CREATE TABLE FitServe.session ( -- lily
session_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
time_start TIMESTAMP NOT NULL,
time_end TIMESTAMP NOT NULL,
booking FitServe.booking_status_enum NOT NULL DEFAULT 'planned',
studio_id INTEGER,
CONSTRAINT chk_session_end_after_start
CHECK (time_end > time_start),
CONSTRAINT chk_session_max_duration
CHECK (time_end <= time_start + INTERVAL '3 hours'),
FOREIGN KEY (studio_id) REFERENCES FitServe.studios(studio_id)
);
CREATE TABLE FitServe.athlete_session ( -- lily
athlete_session_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
session_id BIGINT NOT NULL,
athlete_id INTEGER NOT NULL,
UNIQUE (session_id, athlete_id),
FOREIGN KEY (session_id) REFERENCES FitServe.session(session_id),
FOREIGN KEY (athlete_id) REFERENCES FitServe.athletes(athlete_id)
);
CREATE TABLE FitServe.trainer_session ( -- lily
trainer_session_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
trainer_id INTEGER NOT NULL,
session_id BIGINT NOT NULL,
UNIQUE (trainer_id, session_id),
FOREIGN KEY (trainer_id) REFERENCES FitServe.trainers(trainer_id),
FOREIGN KEY (session_id) REFERENCES FitServe.session(session_id)
);
CREATE TABLE FitServe.packs ( -- Oleksii
pack_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
pack_name VARCHAR(100) NOT NULL UNIQUE,
pack_type VARCHAR(50) NOT NULL,
is_active BOOLEAN NOT NULL
);
CREATE TABLE FitServe.pack_subscription ( -- Oleksii
pack_subscription_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
start_date DATE NOT NULL,
end_date DATE NOT NULL,
athlete_id INTEGER NOT NULL,
pack_id INTEGER NOT NULL,
CONSTRAINT chk_pack_subscription_date_order
CHECK (end_date >= start_date), -- lily-CHECK
CONSTRAINT chk_pack_subscription_start_limit
CHECK (start_date <= CURRENT_DATE + INTERVAL '1 year'), -- lily-CHECK (перевірити INTERVAL)
FOREIGN KEY (athlete_id) REFERENCES FitServe.athletes(athlete_id),
FOREIGN KEY (pack_id) REFERENCES FitServe.packs(pack_id)
);
CREATE TABLE FitServe.equipment ( -- Oleksii
equipment_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR(100) NOT NULL,
model VARCHAR(100) NOT NULL,
brand varchar(100) NOT NULL,
status FitServe.status_type NOT NULL DEFAULT 'ready',
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
studio_id INTEGER NOT NULL,
FOREIGN KEY (studio_id) REFERENCES FitServe.studios(studio_id)
);
CREATE TABLE FitServe.warranty ( -- Oleksii
warranty_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
warranty_status FitServe.warranty_type NOT NULL,
expiry_date DATE NOT NULL,
renewal_date DATE,
terms_link VARCHAR(500) NOT NULL,
equipment_id INTEGER NOT NULL UNIQUE,
FOREIGN KEY (equipment_id) REFERENCES FitServe.equipment(equipment_id)
);
CREATE TABLE FitServe.pack_equipment ( -- Oleksii
pack_equipment_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
pack_id INTEGER NOT NULL,
equipment_id INTEGER NOT NULL,
UNIQUE (pack_id, equipment_id),
FOREIGN KEY (pack_id) REFERENCES FitServe.packs(pack_id),
FOREIGN KEY (equipment_id) REFERENCES FitServe.equipment(equipment_id)
);
CREATE TABLE FitServe.promocodes ( -- Oleksii
promocode_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
code VARCHAR(16) NOT NULL UNIQUE,
quantity SMALLINT NOT NULL,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
CONSTRAINT chk_promocodes_quantity_nonnegative
CHECK (quantity >= 0) -- lily-CHECK
);
CREATE TABLE FitServe.payment ( -- Oleksii
payment_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
price NUMERIC(10, 2) NOT NULL,
payment_method VARCHAR(50),
payment_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
amount_paid NUMERIC(10, 2),
payment_status FitServe.payment_status_type NOT NULL DEFAULT 'unpaid',
pack_subscription_id INTEGER NOT NULL UNIQUE,
promocode_id INTEGER,
CONSTRAINT chk_payment_price_positive
CHECK (price > 0), -- lily-CHECK
CONSTRAINT chk_payment_amount_positive
CHECK (amount_paid > 0), -- lily-CHECK
FOREIGN KEY (pack_subscription_id) REFERENCES FitServe.pack_subscription(pack_subscription_id),
FOREIGN KEY (promocode_id) REFERENCES FitServe.promocodes(promocode_id)
);
CREATE TABLE FitServe.discounts ( -- Oleksii
discount_id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
discount_name VARCHAR(50) NOT NULL,
description VARCHAR(500) NOT NULL,
start_date DATE NOT NULL,
end_date DATE NOT NULL,
CONSTRAINT chk_discounts_date_order
CHECK (end_date > start_date) -- lily-CHECK
);
CREATE TABLE FitServe.payment_discount ( -- Oleksii
payment_discount_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
discount_id INTEGER NOT NULL,
payment_id INTEGER NOT NULL,
CONSTRAINT uq_payment_discount_pair
UNIQUE (discount_id, payment_id), -- lily-UNIQUE
FOREIGN KEY (discount_id) REFERENCES FitServe.discounts(discount_id),
FOREIGN KEY (payment_id) REFERENCES FitServe.payment(payment_id)
);
-- =========================================================
-- FOREIGN KEY UPDATE / DELETE RULES
-- =========================================================
ALTER TABLE FitServe.users
DROP CONSTRAINT IF EXISTS users_user_info_id_fkey,
ADD CONSTRAINT fk_users_user_info
FOREIGN KEY (user_info_id)
REFERENCES FitServe.user_info (user_info_id)
ON UPDATE CASCADE
ON DELETE RESTRICT;
ALTER TABLE FitServe.trainers
DROP CONSTRAINT IF EXISTS trainers_user_id_fkey,
ADD CONSTRAINT fk_trainers_user
FOREIGN KEY (user_id)
REFERENCES FitServe.users (user_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.trainers
DROP CONSTRAINT IF EXISTS trainers_interest_rate_id_fkey,
ADD CONSTRAINT fk_trainers_interest_rate
FOREIGN KEY (interest_rate_id)
REFERENCES FitServe.interest_rate (interest_rate_id)
ON UPDATE CASCADE
ON DELETE SET NULL;
ALTER TABLE FitServe.trainer_specialization
DROP CONSTRAINT IF EXISTS trainer_specialization_trainer_id_fkey,
ADD CONSTRAINT fk_trainer_specialization_trainer
FOREIGN KEY (trainer_id)
REFERENCES FitServe.trainers (trainer_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.certifications
DROP CONSTRAINT IF EXISTS certifications_trainer_specialization_id_fkey,
ADD CONSTRAINT fk_certifications_trainer_specialization
FOREIGN KEY (trainer_specialization_id)
REFERENCES FitServe.trainer_specialization (trainer_specialization_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.athletes
DROP CONSTRAINT IF EXISTS athletes_user_id_fkey,
ADD CONSTRAINT fk_athletes_user
FOREIGN KEY (user_id)
REFERENCES FitServe.users (user_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.athlete_achievement
DROP CONSTRAINT IF EXISTS athlete_achievement_achievement_id_fkey,
ADD CONSTRAINT fk_athlete_achievement_achievement
FOREIGN KEY (achievement_id)
REFERENCES FitServe.achievements (achievement_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.athlete_achievement
DROP CONSTRAINT IF EXISTS athlete_achievement_athlete_id_fkey,
ADD CONSTRAINT fk_athlete_achievement_athlete
FOREIGN KEY (athlete_id)
REFERENCES FitServe.athletes (athlete_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.body_metrics
DROP CONSTRAINT IF EXISTS body_metrics_athlete_id_fkey,
ADD CONSTRAINT fk_body_metrics_athlete
FOREIGN KEY (athlete_id)
REFERENCES FitServe.athletes (athlete_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.health_restriction
DROP CONSTRAINT IF EXISTS health_restriction_athlete_id_fkey,
ADD CONSTRAINT fk_health_restriction_athlete
FOREIGN KEY (athlete_id)
REFERENCES FitServe.athletes (athlete_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.nutrition
DROP CONSTRAINT IF EXISTS nutrition_athlete_id_fkey,
ADD CONSTRAINT fk_nutrition_athlete
FOREIGN KEY (athlete_id)
REFERENCES FitServe.athletes (athlete_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.protein
DROP CONSTRAINT IF EXISTS protein_nutrition_id_fkey,
ADD CONSTRAINT fk_protein_nutrition
FOREIGN KEY (nutrition_id)
REFERENCES FitServe.nutrition (nutrition_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.studio_type
DROP CONSTRAINT IF EXISTS studio_type_studio_id_fkey,
ADD CONSTRAINT fk_studio_type_studio
FOREIGN KEY (studio_id)
REFERENCES FitServe.studios (studio_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.session
DROP CONSTRAINT IF EXISTS session_studio_id_fkey,
ADD CONSTRAINT fk_session_studio
FOREIGN KEY (studio_id)
REFERENCES FitServe.studios (studio_id)
ON UPDATE CASCADE
ON DELETE SET NULL;
ALTER TABLE FitServe.athlete_session
DROP CONSTRAINT IF EXISTS athlete_session_session_id_fkey,
ADD CONSTRAINT fk_athlete_session_session
FOREIGN KEY (session_id)
REFERENCES FitServe.session (session_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.athlete_session
DROP CONSTRAINT IF EXISTS athlete_session_athlete_id_fkey,
ADD CONSTRAINT fk_athlete_session_athlete
FOREIGN KEY (athlete_id)
REFERENCES FitServe.athletes (athlete_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.trainer_session
DROP CONSTRAINT IF EXISTS trainer_session_trainer_id_fkey,
ADD CONSTRAINT fk_trainer_session_trainer
FOREIGN KEY (trainer_id)
REFERENCES FitServe.trainers (trainer_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.trainer_session
DROP CONSTRAINT IF EXISTS trainer_session_session_id_fkey,
ADD CONSTRAINT fk_trainer_session_session
FOREIGN KEY (session_id)
REFERENCES FitServe.session (session_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.pack_subscription
DROP CONSTRAINT IF EXISTS pack_subscription_athlete_id_fkey,
ADD CONSTRAINT fk_pack_subscription_athlete
FOREIGN KEY (athlete_id)
REFERENCES FitServe.athletes (athlete_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.pack_subscription
DROP CONSTRAINT IF EXISTS pack_subscription_pack_id_fkey,
ADD CONSTRAINT fk_pack_subscription_pack
FOREIGN KEY (pack_id)
REFERENCES FitServe.packs (pack_id)
ON UPDATE CASCADE
ON DELETE RESTRICT;
ALTER TABLE FitServe.equipment
DROP CONSTRAINT IF EXISTS equipment_studio_id_fkey,
ADD CONSTRAINT fk_equipment_studio
FOREIGN KEY (studio_id)
REFERENCES FitServe.studios (studio_id)
ON UPDATE CASCADE
ON DELETE RESTRICT;
ALTER TABLE FitServe.warranty
DROP CONSTRAINT IF EXISTS warranty_equipment_id_fkey,
ADD CONSTRAINT fk_warranty_equipment
FOREIGN KEY (equipment_id)
REFERENCES FitServe.equipment (equipment_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.pack_equipment
DROP CONSTRAINT IF EXISTS pack_equipment_pack_id_fkey,
ADD CONSTRAINT fk_pack_equipment_pack
FOREIGN KEY (pack_id)
REFERENCES FitServe.packs (pack_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.pack_equipment
DROP CONSTRAINT IF EXISTS pack_equipment_equipment_id_fkey,
ADD CONSTRAINT fk_pack_equipment_equipment
FOREIGN KEY (equipment_id)
REFERENCES FitServe.equipment (equipment_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE FitServe.payment
DROP CONSTRAINT IF EXISTS payment_pack_subscription_id_fkey,
ADD CONSTRAINT fk_payment_pack_subscription
FOREIGN KEY (pack_subscription_id)
REFERENCES FitServe.pack_subscription (pack_subscription_id)
ON UPDATE CASCADE
ON DELETE RESTRICT;
ALTER TABLE FitServe.payment
DROP CONSTRAINT IF EXISTS payment_promocode_id_fkey,
ADD CONSTRAINT fk_payment_promocode
FOREIGN KEY (promocode_id)
REFERENCES FitServe.promocodes (promocode_id)
ON UPDATE CASCADE
ON DELETE SET NULL;
ALTER TABLE FitServe.payment_discount
DROP CONSTRAINT IF EXISTS payment_discount_discount_id_fkey,
ADD CONSTRAINT fk_payment_discount_discount
FOREIGN KEY (discount_id)
REFERENCES FitServe.discounts (discount_id)
ON UPDATE CASCADE
ON DELETE RESTRICT;
ALTER TABLE FitServe.payment_discount
DROP CONSTRAINT IF EXISTS payment_discount_payment_id_fkey,
ADD CONSTRAINT fk_payment_discount_payment
FOREIGN KEY (payment_id)
REFERENCES FitServe.payment (payment_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
-- =========================================================
-- INDEXES
-- =========================================================
-- TRAINERS AND CERTIFICATIONS
CREATE INDEX IF NOT EXISTS idx_trainer_specialization_trainer_id
ON FitServe.trainer_specialization (trainer_id);
CREATE INDEX IF NOT EXISTS idx_trainer_specialization_name
ON FitServe.trainer_specialization (specialization_name);
-- ATHLETES, PROGRESS AND HEALTH
CREATE INDEX IF NOT EXISTS idx_athlete_achievement_athlete_id
ON FitServe.athlete_achievement (athlete_id);
CREATE INDEX IF NOT EXISTS idx_body_metrics_athlete_date
ON FitServe.body_metrics (athlete_id, date DESC);
CREATE INDEX IF NOT EXISTS idx_health_restriction_athlete_id
ON FitServe.health_restriction (athlete_id);
CREATE INDEX IF NOT EXISTS idx_nutrition_athlete_date
ON FitServe.nutrition (athlete_id, date DESC);
-- STUDIOS AND SESSIONS
CREATE INDEX IF NOT EXISTS idx_studio_type_activity_name
ON FitServe.studio_type (activity_name);
CREATE INDEX IF NOT EXISTS idx_session_active_schedule
ON FitServe.session (time_start, time_end, studio_id)
WHERE booking IN ('planned', 'confirmed');
CREATE INDEX IF NOT EXISTS idx_athlete_session_athlete_session
ON FitServe.athlete_session (athlete_id, session_id);
CREATE INDEX IF NOT EXISTS idx_trainer_session_session_trainer
ON FitServe.trainer_session (session_id, trainer_id);
-- PACKS AND SUBSCRIPTIONS
CREATE INDEX IF NOT EXISTS idx_packs_type_active
ON FitServe.packs (pack_type, is_active);
CREATE INDEX IF NOT EXISTS idx_pack_subscription_athlete_period
ON FitServe.pack_subscription (athlete_id, start_date, end_date);
-- EQUIPMENT AND WARRANTY
CREATE INDEX IF NOT EXISTS idx_equipment_studio_status
ON FitServe.equipment (studio_id, status);
CREATE INDEX IF NOT EXISTS idx_warranty_renewal_date
ON FitServe.warranty (renewal_date)
WHERE renewal_date IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_pack_equipment_equipment_id
ON FitServe.pack_equipment (equipment_id);
-- PAYMENTS AND DISCOUNTS
CREATE INDEX IF NOT EXISTS idx_payment_status_date
ON FitServe.payment (payment_status, payment_date DESC);
CREATE INDEX IF NOT EXISTS idx_discounts_active_period
ON FitServe.discounts (start_date, end_date);
CREATE INDEX IF NOT EXISTS idx_payment_discount_payment_id
ON FitServe.payment_discount (payment_id);
--DROP SCHEMA fitserve CASCADE;