mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-05 03:02:56 +00:00
hot fix #1
This commit is contained in:
@@ -0,0 +1,292 @@
|
||||
-- Create facility management tables
|
||||
-- Migration: 20260109000001_create_facility_management_tables.up.sql
|
||||
|
||||
-- Facilities table
|
||||
CREATE TABLE IF NOT EXISTS facilities (
|
||||
id SERIAL PRIMARY KEY,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP WITH TIME ZONE,
|
||||
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
type VARCHAR(20) NOT NULL CHECK (type IN ('field', 'gym', 'locker', 'classroom', 'storage', 'other')),
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'inactive', 'maintenance', 'closed')),
|
||||
capacity INTEGER,
|
||||
area DECIMAL(10,2),
|
||||
location VARCHAR(255),
|
||||
is_indoor BOOLEAN DEFAULT true,
|
||||
is_outdoor BOOLEAN DEFAULT false,
|
||||
image_url VARCHAR(500),
|
||||
|
||||
-- Booking settings
|
||||
requires_approval BOOLEAN DEFAULT false,
|
||||
min_booking_duration INTEGER DEFAULT 30,
|
||||
max_booking_duration INTEGER DEFAULT 240,
|
||||
booking_advance_days INTEGER DEFAULT 30,
|
||||
|
||||
-- Pricing
|
||||
price_per_hour DECIMAL(10,2) DEFAULT 0.00,
|
||||
|
||||
CONSTRAINT facilities_name_unique UNIQUE (name, deleted_at)
|
||||
);
|
||||
|
||||
-- Facility availability rules
|
||||
CREATE TABLE IF NOT EXISTS facility_availability_rules (
|
||||
id SERIAL PRIMARY KEY,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP WITH TIME ZONE,
|
||||
|
||||
facility_id INTEGER NOT NULL REFERENCES facilities(id) ON DELETE CASCADE,
|
||||
day_of_week INTEGER NOT NULL CHECK (day_of_week BETWEEN 0 AND 6),
|
||||
start_time VARCHAR(5) NOT NULL CHECK (start_time ~ '^[0-2][0-9]:[0-5][0-9]$'),
|
||||
end_time VARCHAR(5) NOT NULL CHECK (end_time ~ '^[0-2][0-9]:[0-5][0-9]$'),
|
||||
is_available BOOLEAN DEFAULT true,
|
||||
start_date DATE,
|
||||
end_date DATE
|
||||
);
|
||||
|
||||
-- Facility bookings
|
||||
CREATE TABLE IF NOT EXISTS facility_bookings (
|
||||
id SERIAL PRIMARY KEY,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP WITH TIME ZONE,
|
||||
|
||||
facility_id INTEGER NOT NULL REFERENCES facilities(id) ON DELETE CASCADE,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id),
|
||||
|
||||
title VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
start_time TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
end_time TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'confirmed', 'cancelled', 'completed', 'noshow')),
|
||||
|
||||
-- Pricing
|
||||
total_price DECIMAL(10,2) DEFAULT 0.00,
|
||||
payment_status VARCHAR(20) DEFAULT 'pending',
|
||||
|
||||
-- Attendance tracking
|
||||
actual_start_time TIMESTAMP WITH TIME ZONE,
|
||||
actual_end_time TIMESTAMP WITH TIME ZONE,
|
||||
attendees_count INTEGER DEFAULT 0,
|
||||
|
||||
-- Notes
|
||||
internal_notes TEXT,
|
||||
public_notes TEXT,
|
||||
|
||||
-- Cancellation
|
||||
cancelled_at TIMESTAMP WITH TIME ZONE,
|
||||
cancelled_by INTEGER REFERENCES users(id),
|
||||
cancel_reason TEXT,
|
||||
|
||||
CONSTRAINT bookings_no_overlap EXCLUDE (facility_id WITH =, tsrange(start_time, end_time) WITH &&) WHERE (deleted_at IS NULL AND status NOT IN ('cancelled', 'noshow'))
|
||||
);
|
||||
|
||||
-- Facility equipment
|
||||
CREATE TABLE IF NOT EXISTS facility_equipment (
|
||||
id SERIAL PRIMARY KEY,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP WITH TIME ZONE,
|
||||
|
||||
facility_id INTEGER NOT NULL REFERENCES facilities(id) ON DELETE CASCADE,
|
||||
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
category VARCHAR(100),
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'available' CHECK (status IN ('available', 'in_use', 'maintenance', 'damaged', 'lost', 'retired')),
|
||||
quantity INTEGER NOT NULL DEFAULT 1,
|
||||
available INTEGER NOT NULL DEFAULT 1,
|
||||
|
||||
-- Purchase info
|
||||
purchase_date DATE,
|
||||
purchase_price DECIMAL(10,2),
|
||||
supplier VARCHAR(255),
|
||||
serial_number VARCHAR(255),
|
||||
warranty_expiry DATE,
|
||||
|
||||
-- Maintenance
|
||||
last_maintenance_date DATE,
|
||||
next_maintenance_date DATE,
|
||||
|
||||
-- Location tracking
|
||||
current_location VARCHAR(255),
|
||||
|
||||
image_url VARCHAR(500),
|
||||
|
||||
-- Usage tracking
|
||||
usage_count INTEGER DEFAULT 0,
|
||||
last_used_at TIMESTAMP WITH TIME ZONE,
|
||||
|
||||
CONSTRAINT equipment_name_facility_unique UNIQUE (name, facility_id, deleted_at)
|
||||
);
|
||||
|
||||
-- Facility maintenance
|
||||
CREATE TABLE IF NOT EXISTS facility_maintenance (
|
||||
id SERIAL PRIMARY KEY,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP WITH TIME ZONE,
|
||||
|
||||
facility_id INTEGER NOT NULL REFERENCES facilities(id) ON DELETE CASCADE,
|
||||
|
||||
type VARCHAR(20) NOT NULL CHECK (type IN ('routine', 'repair', 'inspection', 'upgrade')),
|
||||
title VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
|
||||
-- Scheduling
|
||||
scheduled_date TIMESTAMP WITH TIME ZONE,
|
||||
estimated_duration INTEGER, -- minutes
|
||||
actual_duration INTEGER, -- minutes
|
||||
|
||||
-- Status
|
||||
status VARCHAR(20) DEFAULT 'scheduled',
|
||||
started_at TIMESTAMP WITH TIME ZONE,
|
||||
completed_at TIMESTAMP WITH TIME ZONE,
|
||||
|
||||
-- Cost
|
||||
estimated_cost DECIMAL(10,2),
|
||||
actual_cost DECIMAL(10,2),
|
||||
|
||||
-- Personnel
|
||||
assigned_to VARCHAR(255),
|
||||
performed_by VARCHAR(255),
|
||||
|
||||
-- Impact
|
||||
is_facility_unavailable BOOLEAN DEFAULT true,
|
||||
|
||||
-- Notes
|
||||
internal_notes TEXT,
|
||||
public_notes TEXT,
|
||||
|
||||
-- Related equipment (JSON array)
|
||||
equipment_affected TEXT
|
||||
);
|
||||
|
||||
-- Weather conditions for outdoor facilities
|
||||
CREATE TABLE IF NOT EXISTS weather_conditions (
|
||||
id SERIAL PRIMARY KEY,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP WITH TIME ZONE,
|
||||
|
||||
facility_id INTEGER NOT NULL REFERENCES facilities(id) ON DELETE CASCADE,
|
||||
|
||||
date_time TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
temperature DECIMAL(5,2), -- Celsius
|
||||
humidity DECIMAL(5,2), -- Percentage
|
||||
precipitation DECIMAL(8,2), -- mm
|
||||
wind_speed DECIMAL(5,2), -- km/h
|
||||
wind_direction INTEGER, -- Degrees
|
||||
weather_code VARCHAR(10), -- OpenWeatherMap condition code
|
||||
description VARCHAR(255),
|
||||
is_suitable BOOLEAN DEFAULT false,
|
||||
recommendations TEXT,
|
||||
|
||||
CONSTRAINT weather_facility_datetime_unique UNIQUE (facility_id, date_time)
|
||||
);
|
||||
|
||||
-- Facility booking templates
|
||||
CREATE TABLE IF NOT EXISTS facility_booking_templates (
|
||||
id SERIAL PRIMARY KEY,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP WITH TIME ZONE,
|
||||
|
||||
facility_id INTEGER NOT NULL REFERENCES facilities(id) ON DELETE CASCADE,
|
||||
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
|
||||
-- Default booking settings
|
||||
duration INTEGER, -- minutes
|
||||
price_per_hour DECIMAL(10,2),
|
||||
requires_approval BOOLEAN DEFAULT false,
|
||||
|
||||
-- Recurrence pattern
|
||||
is_recurring BOOLEAN DEFAULT false,
|
||||
recurrence_pattern TEXT, -- JSON
|
||||
|
||||
-- Default settings
|
||||
default_title VARCHAR(255),
|
||||
default_description TEXT,
|
||||
default_attendees INTEGER DEFAULT 1,
|
||||
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
|
||||
CONSTRAINT template_name_facility_unique UNIQUE (name, facility_id, deleted_at)
|
||||
);
|
||||
|
||||
-- Indexes for performance
|
||||
CREATE INDEX IF NOT EXISTS idx_facilities_type ON facilities(type);
|
||||
CREATE INDEX IF NOT EXISTS idx_facilities_status ON facilities(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_facilities_is_outdoor ON facilities(is_outdoor);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_facility_bookings_facility_id ON facility_bookings(facility_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_facility_bookings_user_id ON facility_bookings(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_facility_bookings_start_time ON facility_bookings(start_time);
|
||||
CREATE INDEX IF NOT EXISTS idx_facility_bookings_end_time ON facility_bookings(end_time);
|
||||
CREATE INDEX IF NOT EXISTS idx_facility_bookings_status ON facility_bookings(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_facility_bookings_time_range ON facility_bookings USING gist (tsrange(start_time, end_time));
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_facility_equipment_facility_id ON facility_equipment(facility_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_facility_equipment_status ON facility_equipment(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_facility_equipment_category ON facility_equipment(category);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_facility_maintenance_facility_id ON facility_maintenance(facility_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_facility_maintenance_scheduled_date ON facility_maintenance(scheduled_date);
|
||||
CREATE INDEX IF NOT EXISTS idx_facility_maintenance_status ON facility_maintenance(status);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_weather_conditions_facility_id ON weather_conditions(facility_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_weather_conditions_date_time ON weather_conditions(date_time);
|
||||
CREATE INDEX IF NOT EXISTS idx_weather_conditions_is_suitable ON weather_conditions(is_suitable);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_facility_booking_templates_facility_id ON facility_booking_templates(facility_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_facility_booking_templates_is_active ON facility_booking_templates(is_active);
|
||||
|
||||
-- Insert sample data
|
||||
INSERT INTO facilities (name, description, type, status, capacity, area, location, is_indoor, is_outdoor, price_per_hour, min_booking_duration, max_booking_duration, booking_advance_days) VALUES
|
||||
('Hlavní hřiště', 'Plnoformátové fotbalové hřiště s přírodním trávníkem', 'field', 'active', 22, 7200.00, 'Hlavní sportovní areál', false, true, 500.00, 60, 180, 14),
|
||||
('Tréninkové hřiště č. 1', 'Menší tréninkové hřiště s umělým trávníkem', 'field', 'active', 16, 4800.00, 'Tréninkový areál - sever', false, true, 300.00, 30, 120, 7),
|
||||
('Posilovna', 'Plně vybavená posilovna pro hráče', 'gym', 'active', 20, 150.00, 'Hlavní budova - 1. patro', true, false, 100.00, 30, 90, 3),
|
||||
('Šatna A', 'Šatna pro domácí tým', 'locker', 'active', 25, 80.00, 'Hlavní budova - přízemí', true, false, 0.00, 15, 60, 1),
|
||||
('Zasedací místnost', 'Místnost pro týmové porady a prezentace', 'classroom', 'active', 30, 60.00, 'Hlavní budova - 2. patro', true, false, 50.00, 30, 120, 7),
|
||||
('Sklad vybavení', 'Sklad pro tréninkové vybavení', 'storage', 'active', 5, 40.00, 'Hlavní budova - suterén', true, false, 0.00, 15, 30, 1);
|
||||
|
||||
-- Insert availability rules for main field (available Mon-Fri 16:00-22:00, Sat-Sun 08:00-22:00)
|
||||
INSERT INTO facility_availability_rules (facility_id, day_of_week, start_time, end_time, is_available)
|
||||
SELECT f.id, d.day_of_week, d.start_time, d.end_time, true
|
||||
FROM facilities f,
|
||||
(VALUES
|
||||
(1, 1, '16:00', '22:00'), -- Monday
|
||||
(1, 2, '16:00', '22:00'), -- Tuesday
|
||||
(1, 3, '16:00', '22:00'), -- Wednesday
|
||||
(1, 4, '16:00', '22:00'), -- Thursday
|
||||
(1, 5, '16:00', '22:00'), -- Friday
|
||||
(1, 6, '08:00', '22:00'), -- Saturday
|
||||
(1, 0, '08:00', '22:00') -- Sunday
|
||||
) AS d(day_of_week, start_time, end_time)
|
||||
WHERE f.name = 'Hlavní hřiště';
|
||||
|
||||
-- Insert sample equipment
|
||||
INSERT INTO facility_equipment (facility_id, name, description, category, quantity, available, purchase_date, purchase_price)
|
||||
SELECT f.id, e.name, e.description, e.category, e.quantity, e.quantity, e.purchase_date, e.purchase_price
|
||||
FROM facilities f,
|
||||
(VALUES
|
||||
(1, 'Míče velikosti 5', 'Plnoformátové fotbalové míče', 'balls', 20, 20, '2024-01-15', 800.00),
|
||||
(1, 'Tréninkové kužely', 'Plastové kužele pro cvičení', 'cones', 50, 50, '2024-01-15', 500.00),
|
||||
(1, 'Branky', 'Přenosné branky pro trénink', 'goals', 4, 4, '2024-02-01', 2000.00),
|
||||
(3, 'Činky', 'Sada činek různých vah', 'weights', 10, 10, '2024-01-20', 5000.00),
|
||||
(3, 'Posilovací lavice', 'Profesionální lavice na bench press', 'benches', 3, 3, '2024-01-20', 3000.00)
|
||||
) AS e(name, description, category, quantity, available, purchase_date, purchase_price)
|
||||
WHERE f.name = 'Hlavní hřiště' AND e.category IN ('balls', 'cones', 'goals')
|
||||
UNION ALL
|
||||
SELECT f.id, e.name, e.description, e.category, e.quantity, e.quantity, e.purchase_date, e.purchase_price
|
||||
FROM facilities f,
|
||||
(VALUES
|
||||
('Činky', 'Sada činek různých vah', 'weights', 10, 10, '2024-01-20', 5000.00),
|
||||
('Posilovací lavice', 'Profesionální lavice na bench press', 'benches', 3, 3, '2024-01-20', 3000.00)
|
||||
) AS e(name, description, category, quantity, available, purchase_date, purchase_price)
|
||||
WHERE f.name = 'Posilovna' AND e.category IN ('weights', 'benches');
|
||||
Reference in New Issue
Block a user