COMMIT 16MAR
This commit is contained in:
326
src/server/scripts/init-db.sql
Normal file
326
src/server/scripts/init-db.sql
Normal file
@@ -0,0 +1,326 @@
|
||||
-- Full Database Schema for GPI (PostgreSQL)
|
||||
CREATE SCHEMA IF NOT EXISTS gpi;
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
|
||||
-- 1. Organizations
|
||||
CREATE TABLE IF NOT EXISTS gpi.organizations (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
clerk_id TEXT UNIQUE, -- Legacy
|
||||
logto_id TEXT UNIQUE,
|
||||
name TEXT NOT NULL,
|
||||
is_banned BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 2. Users
|
||||
CREATE TABLE IF NOT EXISTS gpi.users (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
clerk_id TEXT UNIQUE, -- Legacy
|
||||
logto_id TEXT UNIQUE,
|
||||
email TEXT UNIQUE NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
role TEXT CHECK (role IN ('guest', 'user', 'admin')) DEFAULT 'guest',
|
||||
is_banned BOOLEAN DEFAULT FALSE,
|
||||
last_seen_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 3. many-to-many user_organizations
|
||||
CREATE TABLE IF NOT EXISTS gpi.user_organizations (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id UUID REFERENCES gpi.users(id) ON DELETE CASCADE,
|
||||
organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
|
||||
role TEXT CHECK (role IN ('guest', 'user', 'admin')) DEFAULT 'guest',
|
||||
is_banned BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
UNIQUE (user_id, organization_id)
|
||||
);
|
||||
|
||||
-- 4. Technical Data Sheets (Fichas Técnicas)
|
||||
CREATE TABLE IF NOT EXISTS gpi.technical_data_sheets (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
manufacturer TEXT,
|
||||
type TEXT,
|
||||
file_url TEXT,
|
||||
solids_volume DECIMAL,
|
||||
density DECIMAL,
|
||||
mixing_ratio TEXT,
|
||||
yield_theoretical DECIMAL,
|
||||
wft_min DECIMAL,
|
||||
wft_max DECIMAL,
|
||||
dft_min DECIMAL,
|
||||
dft_max DECIMAL,
|
||||
reducer TEXT,
|
||||
yield_factor DECIMAL DEFAULT 1.0,
|
||||
min_stock DECIMAL DEFAULT 0,
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 5. Projects
|
||||
CREATE TABLE IF NOT EXISTS gpi.projects (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
client TEXT NOT NULL,
|
||||
start_date DATE,
|
||||
end_date DATE,
|
||||
technician TEXT,
|
||||
environment TEXT,
|
||||
weight_kg DECIMAL,
|
||||
status TEXT DEFAULT 'active',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 6. Parts
|
||||
CREATE TABLE IF NOT EXISTS gpi.parts (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
project_id UUID REFERENCES gpi.projects(id) ON DELETE CASCADE,
|
||||
description TEXT NOT NULL,
|
||||
dimensions TEXT,
|
||||
weight DECIMAL,
|
||||
type TEXT,
|
||||
area DECIMAL,
|
||||
complexity INTEGER,
|
||||
quantity INTEGER DEFAULT 1,
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 7. Painting Schemes
|
||||
CREATE TABLE IF NOT EXISTS gpi.painting_schemes (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
project_id UUID REFERENCES gpi.projects(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
type TEXT,
|
||||
coat TEXT, -- Primer, Intermediate, Finish
|
||||
solids_volume DECIMAL,
|
||||
yield_theoretical DECIMAL,
|
||||
eps_min DECIMAL,
|
||||
eps_max DECIMAL,
|
||||
dilution DECIMAL,
|
||||
manufacturer TEXT,
|
||||
color TEXT,
|
||||
notes TEXT,
|
||||
paint_id UUID REFERENCES gpi.technical_data_sheets(id),
|
||||
thinner_id UUID REFERENCES gpi.technical_data_sheets(id),
|
||||
color_hex TEXT,
|
||||
thinner_symbol TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 8. Application Records (Lotes de Pintura)
|
||||
CREATE TABLE IF NOT EXISTS gpi.application_records (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
project_id UUID REFERENCES gpi.projects(id) ON DELETE CASCADE,
|
||||
coat_stage TEXT,
|
||||
piece_description TEXT,
|
||||
date DATE,
|
||||
operator TEXT,
|
||||
real_weight DECIMAL,
|
||||
volume_used DECIMAL,
|
||||
area_painted DECIMAL,
|
||||
wet_thickness_avg DECIMAL,
|
||||
dry_thickness_calc DECIMAL,
|
||||
real_yield DECIMAL,
|
||||
method TEXT,
|
||||
diluent_used DECIMAL,
|
||||
notes TEXT,
|
||||
items JSONB DEFAULT '[]', -- List of {partId, quantity}
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 9. Instruments
|
||||
CREATE TABLE IF NOT EXISTS gpi.instruments (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
serial_number TEXT,
|
||||
type TEXT,
|
||||
last_calibration DATE,
|
||||
calibration_due DATE,
|
||||
status TEXT DEFAULT 'active',
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 10. Stock Items
|
||||
CREATE TABLE IF NOT EXISTS gpi.stock_items (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
|
||||
data_sheet_id UUID REFERENCES gpi.technical_data_sheets(id),
|
||||
batch_number TEXT NOT NULL,
|
||||
manufacturing_date DATE,
|
||||
expiration_date DATE,
|
||||
initial_quantity DECIMAL NOT NULL,
|
||||
current_quantity DECIMAL NOT NULL,
|
||||
unit TEXT DEFAULT 'L',
|
||||
location TEXT,
|
||||
status TEXT DEFAULT 'active',
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 11. Inspections
|
||||
CREATE TABLE IF NOT EXISTS gpi.inspections (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
project_id UUID REFERENCES gpi.projects(id) ON DELETE CASCADE,
|
||||
application_record_id UUID REFERENCES gpi.application_records(id),
|
||||
stock_item_id UUID REFERENCES gpi.stock_items(id),
|
||||
instrument_id UUID REFERENCES gpi.instruments(id),
|
||||
type TEXT CHECK (type IN ('painting', 'surface_treatment')),
|
||||
date DATE,
|
||||
inspector TEXT,
|
||||
part_temperature DECIMAL,
|
||||
weight_kg DECIMAL,
|
||||
appearance TEXT, -- approved, rejected, notes
|
||||
defects TEXT,
|
||||
photos TEXT[] DEFAULT '{}',
|
||||
piece_description TEXT,
|
||||
eps_points DECIMAL[] DEFAULT '{}',
|
||||
adhesion_test TEXT,
|
||||
batch TEXT,
|
||||
treatment_executor TEXT,
|
||||
treatment_type TEXT,
|
||||
cleaning_degree TEXT,
|
||||
roughness_readings DECIMAL[] DEFAULT '{}',
|
||||
flash_rust TEXT,
|
||||
temperature DECIMAL,
|
||||
relative_humidity DECIMAL,
|
||||
period TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 12. Stock Movements
|
||||
CREATE TABLE IF NOT EXISTS gpi.stock_movements (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
|
||||
stock_item_id UUID REFERENCES gpi.stock_items(id) ON DELETE CASCADE,
|
||||
type TEXT CHECK (type IN ('in', 'out', 'adjust')),
|
||||
quantity DECIMAL NOT NULL,
|
||||
reason TEXT,
|
||||
project_id UUID REFERENCES gpi.projects(id),
|
||||
user_id TEXT, -- external_id
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 13. System Settings
|
||||
CREATE TABLE IF NOT EXISTS gpi.system_settings (
|
||||
settings_id TEXT PRIMARY KEY DEFAULT 'global',
|
||||
app_name TEXT DEFAULT 'GPI',
|
||||
app_subtitle TEXT DEFAULT 'Gestão de Pintura Industrial',
|
||||
app_logo_url TEXT,
|
||||
updated_by TEXT,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 14. Notifications
|
||||
CREATE TABLE IF NOT EXISTS gpi.notifications (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
|
||||
recipient_id UUID REFERENCES gpi.users(id) ON DELETE CASCADE,
|
||||
title TEXT NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
type TEXT CHECK (type IN ('info', 'warning', 'error', 'success')) DEFAULT 'info',
|
||||
is_read BOOLEAN DEFAULT FALSE,
|
||||
is_archived BOOLEAN DEFAULT FALSE,
|
||||
archived_by UUID[] DEFAULT '{}',
|
||||
deleted_by UUID[] DEFAULT '{}',
|
||||
metadata JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 15. Yield Studies
|
||||
CREATE TABLE IF NOT EXISTS gpi.yield_studies (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
|
||||
data_sheet_id UUID REFERENCES gpi.technical_data_sheets(id),
|
||||
name TEXT NOT NULL,
|
||||
target_dft DECIMAL NOT NULL,
|
||||
dilution_percent DECIMAL DEFAULT 0,
|
||||
categories JSONB DEFAULT '[]',
|
||||
total_weight DECIMAL,
|
||||
estimated_paint_volume DECIMAL,
|
||||
estimated_reducer_volume DECIMAL,
|
||||
estimated_paint_volume_by_area DECIMAL,
|
||||
estimated_reducer_volume_by_area DECIMAL,
|
||||
average_complexity DECIMAL,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 16. Stock Audit Logs
|
||||
CREATE TABLE IF NOT EXISTS gpi.stock_audit_logs (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
|
||||
stock_item_id UUID REFERENCES gpi.stock_items(id) ON DELETE CASCADE,
|
||||
movement_id UUID,
|
||||
movement_number INTEGER,
|
||||
user_id TEXT, -- external_id
|
||||
user_name TEXT,
|
||||
action TEXT NOT NULL,
|
||||
details TEXT,
|
||||
old_values JSONB,
|
||||
new_values JSONB,
|
||||
timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 17. Messages
|
||||
CREATE TABLE IF NOT EXISTS gpi.messages (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
|
||||
from_user_id TEXT NOT NULL, -- external_id
|
||||
to_user_id TEXT NOT NULL, -- external_id
|
||||
message TEXT NOT NULL,
|
||||
is_read BOOLEAN DEFAULT FALSE,
|
||||
read_at TIMESTAMP WITH TIME ZONE,
|
||||
is_archived BOOLEAN DEFAULT FALSE,
|
||||
is_deleted_by_recipient BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 18. Geometry Types
|
||||
CREATE TABLE IF NOT EXISTS gpi.geometry_types (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
efficiency_loss DECIMAL DEFAULT 0,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
UNIQUE (organization_id, name)
|
||||
);
|
||||
|
||||
-- 19. Stored Files
|
||||
CREATE TABLE IF NOT EXISTS gpi.stored_files (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
|
||||
filename TEXT NOT NULL,
|
||||
original_name TEXT,
|
||||
mimetype TEXT,
|
||||
size INTEGER,
|
||||
path TEXT,
|
||||
category TEXT,
|
||||
reference_id TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_projects_org ON gpi.projects(organization_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_parts_project ON gpi.parts(project_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_schemes_project ON gpi.painting_schemes(project_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_records_project ON gpi.application_records(project_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_inspections_project ON gpi.inspections(project_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_stock_org ON gpi.stock_items(organization_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_notifications_recipient ON gpi.notifications(recipient_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_messages_to ON gpi.messages(to_user_id, is_read);
|
||||
CREATE INDEX IF NOT EXISTS idx_geometry_types_org ON gpi.geometry_types(organization_id);
|
||||
Reference in New Issue
Block a user