133 lines
5.2 KiB
SQL
133 lines
5.2 KiB
SQL
CREATE TABLE IF NOT EXISTS users (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
email TEXT NOT NULL UNIQUE,
|
|
password_hash TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
role TEXT NOT NULL CHECK (role IN ('tenant_admin', 'manager', 'technician')),
|
|
active BOOLEAN NOT NULL DEFAULT true,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS clients (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
name TEXT NOT NULL,
|
|
nif TEXT,
|
|
phone TEXT,
|
|
email TEXT,
|
|
address TEXT,
|
|
notes TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS vehicles (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
client_id UUID REFERENCES clients(id) ON DELETE SET NULL,
|
|
plate TEXT NOT NULL,
|
|
brand TEXT NOT NULL,
|
|
model TEXT NOT NULL,
|
|
year INT,
|
|
vin TEXT,
|
|
mileage INT,
|
|
notes TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS staff (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
name TEXT NOT NULL,
|
|
email TEXT,
|
|
phone TEXT,
|
|
type TEXT NOT NULL CHECK (type IN ('internal', 'external')),
|
|
hourly_rate NUMERIC(10,2) NOT NULL DEFAULT 0,
|
|
active BOOLEAN NOT NULL DEFAULT true,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS catalog_items (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
code TEXT NOT NULL UNIQUE,
|
|
name TEXT NOT NULL,
|
|
category TEXT NOT NULL,
|
|
unit TEXT NOT NULL CHECK (unit IN ('un', 'hora', 'litro', 'kg')),
|
|
base_price NUMERIC(10,2) NOT NULL DEFAULT 0,
|
|
active BOOLEAN NOT NULL DEFAULT true,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS work_orders (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
number SERIAL UNIQUE,
|
|
client_id UUID REFERENCES clients(id) ON DELETE SET NULL,
|
|
vehicle_id UUID REFERENCES vehicles(id) ON DELETE SET NULL,
|
|
status TEXT NOT NULL DEFAULT 'open' CHECK (status IN ('open', 'in_progress', 'completed', 'invoiced', 'cancelled')),
|
|
internal_notes TEXT,
|
|
client_notes TEXT,
|
|
created_by UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS wo_items (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
work_order_id UUID NOT NULL REFERENCES work_orders(id) ON DELETE CASCADE,
|
|
catalog_item_id UUID REFERENCES catalog_items(id) ON DELETE SET NULL,
|
|
description TEXT NOT NULL,
|
|
qty NUMERIC(10,3) NOT NULL DEFAULT 1,
|
|
unit_price NUMERIC(10,2) NOT NULL,
|
|
discount_pct NUMERIC(5,2) NOT NULL DEFAULT 0,
|
|
total NUMERIC(10,2) GENERATED ALWAYS AS (qty * unit_price * (1 - discount_pct / 100)) STORED
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS wo_staff_hours (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
work_order_id UUID NOT NULL REFERENCES work_orders(id) ON DELETE CASCADE,
|
|
staff_id UUID NOT NULL REFERENCES staff(id) ON DELETE RESTRICT,
|
|
hours NUMERIC(6,2) NOT NULL,
|
|
cost_per_hour NUMERIC(10,2) NOT NULL,
|
|
total NUMERIC(10,2) GENERATED ALWAYS AS (hours * cost_per_hour) STORED
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS wo_status_log (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
work_order_id UUID NOT NULL REFERENCES work_orders(id) ON DELETE CASCADE,
|
|
from_status TEXT,
|
|
to_status TEXT NOT NULL,
|
|
changed_by UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
changed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS invoices (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
work_order_id UUID NOT NULL REFERENCES work_orders(id) ON DELETE RESTRICT,
|
|
type TEXT NOT NULL CHECK (type IN ('quote', 'invoice')),
|
|
number SERIAL UNIQUE,
|
|
pdf_path TEXT,
|
|
issued_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS expenses (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
vehicle_id UUID REFERENCES vehicles(id) ON DELETE SET NULL,
|
|
type TEXT NOT NULL CHECK (type IN ('fuel', 'parts', 'tools', 'other')),
|
|
amount NUMERIC(10,2) NOT NULL,
|
|
description TEXT,
|
|
date DATE NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS tenant_settings (
|
|
key TEXT PRIMARY KEY,
|
|
value TEXT NOT NULL,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_work_orders_status ON work_orders(status);
|
|
CREATE INDEX IF NOT EXISTS idx_work_orders_client_id ON work_orders(client_id);
|
|
CREATE INDEX IF NOT EXISTS idx_vehicles_client_id ON vehicles(client_id);
|
|
CREATE INDEX IF NOT EXISTS idx_vehicles_plate ON vehicles(plate);
|
|
CREATE INDEX IF NOT EXISTS idx_expenses_date ON expenses(date);
|