first commit
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS customers (
|
||||
customer_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
first_name TEXT NOT NULL,
|
||||
last_name TEXT NOT NULL,
|
||||
email TEXT UNIQUE,
|
||||
phone TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS vehicles (
|
||||
vehicle_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
customer_id UUID NOT NULL REFERENCES customers(customer_id) ON DELETE CASCADE,
|
||||
registration_number TEXT NOT NULL UNIQUE,
|
||||
make TEXT NOT NULL,
|
||||
model TEXT NOT NULL,
|
||||
model_year INTEGER CHECK (model_year BETWEEN 1886 AND EXTRACT(YEAR FROM CURRENT_DATE)::INTEGER + 1),
|
||||
vin CHAR(17) UNIQUE,
|
||||
mileage INTEGER NOT NULL DEFAULT 0 CHECK (mileage >= 0),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS employees (
|
||||
employee_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
first_name TEXT NOT NULL,
|
||||
last_name TEXT NOT NULL,
|
||||
role TEXT NOT NULL CHECK (role IN ('technician', 'service_advisor', 'manager')),
|
||||
email TEXT UNIQUE,
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS appointments (
|
||||
appointment_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
vehicle_id UUID NOT NULL REFERENCES vehicles(vehicle_id) ON DELETE CASCADE,
|
||||
employee_id UUID REFERENCES employees(employee_id) ON DELETE SET NULL,
|
||||
scheduled_at TIMESTAMPTZ NOT NULL,
|
||||
reason TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'scheduled'
|
||||
CHECK (status IN ('scheduled', 'confirmed', 'completed', 'cancelled', 'no_show')),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS service_orders (
|
||||
service_order_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
vehicle_id UUID NOT NULL REFERENCES vehicles(vehicle_id) ON DELETE RESTRICT,
|
||||
assigned_employee_id UUID REFERENCES employees(employee_id) ON DELETE SET NULL,
|
||||
opened_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
closed_at TIMESTAMPTZ,
|
||||
complaint TEXT NOT NULL,
|
||||
service_date DATE NOT NULL DEFAULT CURRENT_DATE,
|
||||
diagnosis TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'open'
|
||||
CHECK (status IN ('open', 'in_progress', 'waiting_for_parts', 'ready', 'closed', 'cancelled')),
|
||||
CHECK (closed_at IS NULL OR closed_at >= opened_at)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS service_order_items (
|
||||
item_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
service_order_id UUID NOT NULL REFERENCES service_orders(service_order_id) ON DELETE CASCADE,
|
||||
item_type TEXT NOT NULL CHECK (item_type IN ('labor', 'part')),
|
||||
description TEXT NOT NULL,
|
||||
quantity NUMERIC(10, 2) NOT NULL DEFAULT 1 CHECK (quantity > 0),
|
||||
unit_price NUMERIC(12, 2) NOT NULL CHECK (unit_price >= 0),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS invoices (
|
||||
invoice_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
service_order_id UUID NOT NULL UNIQUE REFERENCES service_orders(service_order_id) ON DELETE RESTRICT,
|
||||
issued_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
due_at DATE,
|
||||
status TEXT NOT NULL DEFAULT 'unpaid'
|
||||
CHECK (status IN ('draft', 'unpaid', 'paid', 'void')),
|
||||
tax_rate NUMERIC(5, 2) NOT NULL DEFAULT 0 CHECK (tax_rate >= 0 AND tax_rate <= 100)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS app_users (
|
||||
user_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
username TEXT NOT NULL UNIQUE,
|
||||
display_name TEXT NOT NULL,
|
||||
email TEXT UNIQUE,
|
||||
role TEXT NOT NULL DEFAULT 'viewer'
|
||||
CHECK (role IN ('admin', 'service_advisor', 'technician', 'viewer')),
|
||||
can_read BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
can_add BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_vehicles_customer_id ON vehicles(customer_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_appointments_scheduled_at ON appointments(scheduled_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_service_orders_vehicle_id ON service_orders(vehicle_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_service_orders_status ON service_orders(status);
|
||||
|
||||
INSERT INTO customers (first_name, last_name, email, phone)
|
||||
VALUES ('Alex', 'Morgan', 'alex.morgan@example.com', '+1-555-0100')
|
||||
ON CONFLICT (email) DO NOTHING;
|
||||
|
||||
INSERT INTO app_users (username, display_name, role, can_read, can_add, can_delete)
|
||||
VALUES ('admin', 'Workshop administrator', 'admin', TRUE, TRUE, TRUE)
|
||||
ON CONFLICT (username) DO NOTHING;
|
||||
Reference in New Issue
Block a user