first commit

This commit is contained in:
Rodrigo Nogueira de Sousa
2026-05-22 11:12:19 +01:00
commit 47d2cc65c3
91 changed files with 18528 additions and 0 deletions

150
database/schema.sql Normal file
View File

@@ -0,0 +1,150 @@
-- Create users table
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
phone VARCHAR(20),
role VARCHAR(20) NOT NULL CHECK (role IN ('customer', 'barber', 'admin')),
photo TEXT,
loyalty_points INTEGER DEFAULT 0,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Create services table
CREATE TABLE services (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL,
description TEXT,
duration INTEGER NOT NULL, -- in minutes
price DECIMAL(10,2) NOT NULL,
image TEXT,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Create barbers table
CREATE TABLE barbers (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
specialty VARCHAR(255) NOT NULL,
bio TEXT,
rating DECIMAL(3,2) DEFAULT 0.0 CHECK (rating >= 0 AND rating <= 5),
availability JSONB DEFAULT '{}', -- JSON object with days and time slots
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(user_id)
);
-- Create bookings table
CREATE TABLE bookings (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
customer_id UUID REFERENCES users(id) ON DELETE CASCADE,
barber_id UUID REFERENCES barbers(id) ON DELETE CASCADE,
service_id UUID REFERENCES services(id) ON DELETE CASCADE,
booking_date DATE NOT NULL,
booking_time TIME NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'confirmed', 'completed', 'cancelled')),
notes TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Create reviews table
CREATE TABLE reviews (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
barber_id UUID REFERENCES barbers(id) ON DELETE CASCADE,
booking_id UUID REFERENCES bookings(id) ON DELETE SET NULL,
rating INTEGER NOT NULL CHECK (rating >= 1 AND rating <= 5),
comment TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(user_id, barber_id, booking_id)
);
-- Create promotions table
CREATE TABLE promotions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
title VARCHAR(255) NOT NULL,
description TEXT,
discount_percentage INTEGER NOT NULL CHECK (discount_percentage > 0 AND discount_percentage <= 100),
service_id UUID REFERENCES services(id) ON DELETE CASCADE,
is_active BOOLEAN DEFAULT true,
start_date DATE NOT NULL,
end_date DATE NOT NULL,
image TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Create indexes for better performance
CREATE INDEX idx_barbers_user_id ON barbers(user_id);
CREATE INDEX idx_bookings_customer_id ON bookings(customer_id);
CREATE INDEX idx_bookings_barber_id ON bookings(barber_id);
CREATE INDEX idx_bookings_service_id ON bookings(service_id);
CREATE INDEX idx_bookings_date_time ON bookings(booking_date, booking_time);
CREATE INDEX idx_reviews_user_id ON reviews(user_id);
CREATE INDEX idx_reviews_barber_id ON reviews(barber_id);
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_role ON users(role);
-- Create function to update updated_at timestamp
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ language 'plpgsql';
-- Create triggers for updated_at
CREATE TRIGGER update_users_updated_at BEFORE UPDATE ON users FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_services_updated_at BEFORE UPDATE ON services FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_barbers_updated_at BEFORE UPDATE ON barbers FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_bookings_updated_at BEFORE UPDATE ON bookings FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_reviews_updated_at BEFORE UPDATE ON reviews FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_promotions_updated_at BEFORE UPDATE ON promotions FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- Insert sample data
INSERT INTO services (name, description, duration, price, image) VALUES
('Classic Haircut', 'Traditional haircut with scissors and clippers', 30, 25.00, 'https://images.unsplash.com/photo-1560069007-67cba843241f?w=400'),
('Beard Trim', 'Professional beard shaping and trimming', 20, 15.00, 'https://images.unsplash.com/photo-1622286342621-4bd786c2447c?w=400'),
('Hot Towel Shave', 'Luxurious hot towel straight razor shave', 45, 35.00, 'https://images.unsplash.com/photo-1596468138837-0c38f5fca1b3?w=400'),
('Haircut & Beard', 'Complete haircut and beard trim package', 45, 35.00, 'https://images.unsplash.com/photo-1585747860715-1ba5b1b0ba72?w=400'),
('Kids Haircut', 'Haircut for children under 12', 25, 20.00, 'https://images.unsplash.com/photo-1503931975084-1a8352b4c66d?w=400');
-- Enable Row Level Security (RLS)
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
ALTER TABLE barbers ENABLE ROW LEVEL SECURITY;
ALTER TABLE services ENABLE ROW LEVEL SECURITY;
ALTER TABLE bookings ENABLE ROW LEVEL SECURITY;
ALTER TABLE reviews ENABLE ROW LEVEL SECURITY;
ALTER TABLE promotions ENABLE ROW LEVEL SECURITY;
-- Create RLS policies
-- Users can view all users but only update their own profile
CREATE POLICY "Users can view all users" ON users FOR SELECT USING (true);
CREATE POLICY "Users can update own profile" ON users FOR UPDATE USING (auth.uid() = id);
-- Anyone can view active services
CREATE POLICY "Services are viewable by everyone" ON services FOR SELECT USING (is_active = true);
-- Barbers can be viewed by everyone
CREATE POLICY "Barbers are viewable by everyone" ON barbers FOR SELECT USING (is_active = true);
-- Users can view their own bookings and barbers can view bookings assigned to them
CREATE POLICY "Users can view own bookings" ON bookings FOR SELECT USING (auth.uid() = customer_id);
CREATE POLICY "Barbers can view their bookings" ON bookings FOR SELECT USING (
EXISTS (SELECT 1 FROM barbers WHERE barbers.id = barber_id AND barbers.user_id = auth.uid())
);
CREATE POLICY "Users can create bookings" ON bookings FOR INSERT WITH CHECK (auth.uid() = customer_id);
-- Reviews can be viewed by everyone
CREATE POLICY "Reviews are viewable by everyone" ON reviews FOR SELECT USING (true);
CREATE POLICY "Users can create reviews" ON reviews FOR INSERT WITH CHECK (auth.uid() = user_id);
-- Active promotions can be viewed by everyone
CREATE POLICY "Active promotions are viewable by everyone" ON promotions FOR SELECT USING (is_active = true);