erp-vidrio-templado-databas.../init/03-vidrio-tables.sql
rckrdmrd 431e1273b8 Migración desde erp-vidrio-templado/database - Estándar multi-repo v2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 08:12:04 -06:00

717 lines
26 KiB
SQL

-- ============================================================================
-- TABLAS VIDRIO TEMPLADO - ERP Vidrio
-- ============================================================================
-- Módulos: VT-001 (Producción), VT-002 (Calidad), VT-003 (Inventario),
-- VT-004 (Maquinaria), VT-005 (Trazabilidad), VT-006 (Cotizaciones)
-- Versión: 1.0.0
-- Fecha: 2025-12-09
-- ============================================================================
-- PREREQUISITOS:
-- 1. ERP-Core instalado (auth, core, inventory, sales)
-- 2. Schema vidrio creado
-- ============================================================================
-- ============================================================================
-- TYPES (ENUMs)
-- ============================================================================
DO $$ BEGIN
CREATE TYPE vidrio.glass_type AS ENUM (
'clear', 'tinted', 'reflective', 'low_e', 'laminated', 'tempered', 'insulated'
);
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
DO $$ BEGIN
CREATE TYPE vidrio.production_status AS ENUM (
'draft', 'scheduled', 'cutting', 'processing', 'tempering', 'quality_check', 'completed', 'cancelled'
);
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
DO $$ BEGIN
CREATE TYPE vidrio.quality_result AS ENUM (
'pending', 'passed', 'failed', 'conditional'
);
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
DO $$ BEGIN
CREATE TYPE vidrio.furnace_status AS ENUM (
'idle', 'heating', 'ready', 'in_use', 'cooling', 'maintenance'
);
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
DO $$ BEGIN
CREATE TYPE vidrio.edge_type AS ENUM (
'flat_polished', 'beveled', 'pencil', 'ogee', 'waterfall', 'raw'
);
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
-- ============================================================================
-- CATÁLOGOS BASE
-- ============================================================================
-- Tabla: glass_catalog (Catálogo de tipos de vidrio)
CREATE TABLE IF NOT EXISTS vidrio.glass_catalog (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
-- Identificación
code VARCHAR(30) NOT NULL,
name VARCHAR(100) NOT NULL,
description TEXT,
-- Tipo y características
glass_type vidrio.glass_type NOT NULL,
thickness_mm DECIMAL(5,2) NOT NULL, -- 3, 4, 5, 6, 8, 10, 12, 15, 19 mm
color VARCHAR(50),
-- Propiedades físicas
weight_per_m2 DECIMAL(8,3), -- kg/m2
max_width_mm INTEGER,
max_height_mm INTEGER,
-- Precios base
price_per_m2 DECIMAL(12,2),
cost_per_m2 DECIMAL(12,2),
-- Control
is_active BOOLEAN NOT NULL DEFAULT TRUE,
-- Auditoría
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID REFERENCES auth.users(id),
updated_at TIMESTAMPTZ,
updated_by UUID REFERENCES auth.users(id),
CONSTRAINT uq_glass_catalog_code UNIQUE (tenant_id, code)
);
-- Tabla: process_catalog (Catálogo de procesos)
CREATE TABLE IF NOT EXISTS vidrio.process_catalog (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
code VARCHAR(30) NOT NULL,
name VARCHAR(100) NOT NULL,
description TEXT,
-- Tipo de proceso
process_type VARCHAR(50) NOT NULL, -- cutting, edging, drilling, tempering, laminating
-- Costos
cost_per_unit DECIMAL(12,2),
cost_per_m2 DECIMAL(12,2),
time_minutes INTEGER,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID REFERENCES auth.users(id),
updated_at TIMESTAMPTZ,
updated_by UUID REFERENCES auth.users(id),
CONSTRAINT uq_process_catalog_code UNIQUE (tenant_id, code)
);
-- ============================================================================
-- PRODUCCIÓN (VT-001)
-- ============================================================================
-- Tabla: production_orders (Órdenes de producción)
CREATE TABLE IF NOT EXISTS vidrio.production_orders (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
-- Número de orden
order_number VARCHAR(30) NOT NULL,
-- Referencias
sale_order_id UUID, -- FK a sales.sale_orders (ERP Core)
customer_id UUID, -- FK a core.partners (ERP Core)
-- Estado
status vidrio.production_status NOT NULL DEFAULT 'draft',
-- Fechas
order_date DATE NOT NULL DEFAULT CURRENT_DATE,
due_date DATE NOT NULL,
start_date TIMESTAMPTZ,
end_date TIMESTAMPTZ,
-- Prioridad
priority INTEGER DEFAULT 5 CHECK (priority BETWEEN 1 AND 10),
-- Totales
total_pieces INTEGER DEFAULT 0,
total_area_m2 DECIMAL(12,4) DEFAULT 0,
completed_pieces INTEGER DEFAULT 0,
-- Notas
notes TEXT,
internal_notes TEXT,
-- Auditoría
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID REFERENCES auth.users(id),
updated_at TIMESTAMPTZ,
updated_by UUID REFERENCES auth.users(id),
deleted_at TIMESTAMPTZ,
deleted_by UUID REFERENCES auth.users(id),
CONSTRAINT uq_production_orders_number UNIQUE (tenant_id, order_number)
);
-- Tabla: production_lines (Piezas de producción)
CREATE TABLE IF NOT EXISTS vidrio.production_lines (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
production_order_id UUID NOT NULL REFERENCES vidrio.production_orders(id) ON DELETE CASCADE,
-- Identificación de pieza
line_number INTEGER NOT NULL,
piece_code VARCHAR(50),
-- Tipo de vidrio
glass_catalog_id UUID NOT NULL REFERENCES vidrio.glass_catalog(id),
-- Dimensiones (en mm)
width_mm DECIMAL(8,2) NOT NULL,
height_mm DECIMAL(8,2) NOT NULL,
quantity INTEGER NOT NULL DEFAULT 1,
-- Área calculada
area_m2 DECIMAL(12,6) GENERATED ALWAYS AS (
(width_mm / 1000.0) * (height_mm / 1000.0) * quantity
) STORED,
-- Acabados
edge_type vidrio.edge_type DEFAULT 'flat_polished',
has_holes BOOLEAN DEFAULT FALSE,
hole_count INTEGER DEFAULT 0,
has_cutouts BOOLEAN DEFAULT FALSE,
-- Estado
status vidrio.production_status DEFAULT 'draft',
-- Lote de producción
lot_id UUID,
furnace_batch_id UUID,
-- Notas
notes TEXT,
drawing_url VARCHAR(500),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID REFERENCES auth.users(id),
updated_at TIMESTAMPTZ,
updated_by UUID REFERENCES auth.users(id)
);
-- ============================================================================
-- MAQUINARIA (VT-004)
-- ============================================================================
-- Tabla: furnaces (Hornos de templado)
CREATE TABLE IF NOT EXISTS vidrio.furnaces (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
code VARCHAR(30) NOT NULL,
name VARCHAR(100) NOT NULL,
-- Capacidad
max_width_mm INTEGER NOT NULL,
max_height_mm INTEGER NOT NULL,
min_thickness_mm DECIMAL(4,2),
max_thickness_mm DECIMAL(4,2),
-- Estado
status vidrio.furnace_status DEFAULT 'idle',
current_temperature INTEGER,
-- Mantenimiento
last_maintenance_date DATE,
next_maintenance_date DATE,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID REFERENCES auth.users(id),
updated_at TIMESTAMPTZ,
updated_by UUID REFERENCES auth.users(id),
CONSTRAINT uq_furnaces_code UNIQUE (tenant_id, code)
);
-- Tabla: furnace_batches (Lotes de hornada)
CREATE TABLE IF NOT EXISTS vidrio.furnace_batches (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
furnace_id UUID NOT NULL REFERENCES vidrio.furnaces(id),
-- Identificación
batch_number VARCHAR(30) NOT NULL,
-- Tiempos
start_time TIMESTAMPTZ NOT NULL,
end_time TIMESTAMPTZ,
-- Parámetros
temperature INTEGER NOT NULL, -- Temperatura objetivo
cycle_time_minutes INTEGER, -- Tiempo de ciclo
-- Conteo
pieces_count INTEGER DEFAULT 0,
pieces_passed INTEGER DEFAULT 0,
pieces_failed INTEGER DEFAULT 0,
-- Operador
operator_id UUID REFERENCES auth.users(id),
-- Notas
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID REFERENCES auth.users(id),
CONSTRAINT uq_furnace_batches_number UNIQUE (tenant_id, batch_number)
);
-- Tabla: cutting_machines (Máquinas de corte)
CREATE TABLE IF NOT EXISTS vidrio.cutting_machines (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
code VARCHAR(30) NOT NULL,
name VARCHAR(100) NOT NULL,
machine_type VARCHAR(50), -- manual, semi_auto, cnc
-- Capacidad
max_width_mm INTEGER,
max_height_mm INTEGER,
-- Estado
is_active BOOLEAN NOT NULL DEFAULT TRUE,
-- Mantenimiento
last_maintenance_date DATE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID REFERENCES auth.users(id),
updated_at TIMESTAMPTZ,
updated_by UUID REFERENCES auth.users(id),
CONSTRAINT uq_cutting_machines_code UNIQUE (tenant_id, code)
);
-- ============================================================================
-- CALIDAD (VT-002)
-- ============================================================================
-- Tabla: quality_tests (Pruebas de calidad)
CREATE TABLE IF NOT EXISTS vidrio.quality_tests (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
code VARCHAR(30) NOT NULL,
name VARCHAR(100) NOT NULL,
description TEXT,
-- Tipo de prueba
test_type VARCHAR(50) NOT NULL, -- visual, fragmentation, impact, heat_soak
-- Parámetros
min_value DECIMAL(12,4),
max_value DECIMAL(12,4),
unit VARCHAR(20),
is_mandatory BOOLEAN DEFAULT TRUE,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID REFERENCES auth.users(id),
updated_at TIMESTAMPTZ,
updated_by UUID REFERENCES auth.users(id),
CONSTRAINT uq_quality_tests_code UNIQUE (tenant_id, code)
);
-- Tabla: quality_inspections (Inspecciones de calidad)
CREATE TABLE IF NOT EXISTS vidrio.quality_inspections (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
-- Referencia
production_line_id UUID REFERENCES vidrio.production_lines(id),
furnace_batch_id UUID REFERENCES vidrio.furnace_batches(id),
-- Número
inspection_number VARCHAR(30) NOT NULL,
inspection_date TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-- Resultado general
result vidrio.quality_result NOT NULL DEFAULT 'pending',
-- Inspector
inspector_id UUID NOT NULL REFERENCES auth.users(id),
-- Notas
notes TEXT,
rejection_reason TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID REFERENCES auth.users(id),
updated_at TIMESTAMPTZ,
updated_by UUID REFERENCES auth.users(id),
CONSTRAINT uq_quality_inspections_number UNIQUE (tenant_id, inspection_number)
);
-- Tabla: quality_test_results (Resultados de pruebas)
CREATE TABLE IF NOT EXISTS vidrio.quality_test_results (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
inspection_id UUID NOT NULL REFERENCES vidrio.quality_inspections(id) ON DELETE CASCADE,
test_id UUID NOT NULL REFERENCES vidrio.quality_tests(id),
-- Resultado
result vidrio.quality_result NOT NULL,
measured_value DECIMAL(12,4),
-- Notas
notes TEXT,
photo_url VARCHAR(500),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID REFERENCES auth.users(id)
);
-- ============================================================================
-- TRAZABILIDAD (VT-005)
-- ============================================================================
-- Tabla: glass_lots (Lotes de vidrio crudo)
CREATE TABLE IF NOT EXISTS vidrio.glass_lots (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
-- Identificación
lot_number VARCHAR(30) NOT NULL,
glass_catalog_id UUID NOT NULL REFERENCES vidrio.glass_catalog(id),
-- Proveedor
supplier_id UUID, -- FK a core.partners (ERP Core)
supplier_lot VARCHAR(50),
purchase_order_id UUID, -- FK a purchase.purchase_orders (ERP Core)
-- Recepción
receipt_date DATE NOT NULL,
quantity_sheets INTEGER NOT NULL,
quantity_remaining INTEGER NOT NULL,
-- Dimensiones del lote
sheet_width_mm INTEGER,
sheet_height_mm INTEGER,
-- Calidad
quality_certificate VARCHAR(100),
inspection_status vidrio.quality_result DEFAULT 'pending',
-- Fechas
expiry_date DATE,
-- Notas
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID REFERENCES auth.users(id),
updated_at TIMESTAMPTZ,
updated_by UUID REFERENCES auth.users(id),
CONSTRAINT uq_glass_lots_number UNIQUE (tenant_id, lot_number)
);
-- Tabla: lot_consumption (Consumo de lotes)
CREATE TABLE IF NOT EXISTS vidrio.lot_consumption (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
glass_lot_id UUID NOT NULL REFERENCES vidrio.glass_lots(id),
production_line_id UUID NOT NULL REFERENCES vidrio.production_lines(id),
quantity_sheets INTEGER NOT NULL DEFAULT 1,
consumption_date TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID REFERENCES auth.users(id)
);
-- ============================================================================
-- COTIZACIONES (VT-006)
-- ============================================================================
-- Tabla: quotations (Cotizaciones de vidrio)
CREATE TABLE IF NOT EXISTS vidrio.quotations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
-- Número
quotation_number VARCHAR(30) NOT NULL,
-- Cliente
customer_id UUID NOT NULL, -- FK a core.partners (ERP Core)
contact_name VARCHAR(200),
contact_email VARCHAR(255),
contact_phone VARCHAR(20),
-- Estado
status VARCHAR(20) NOT NULL DEFAULT 'draft', -- draft, sent, confirmed, cancelled, expired
-- Fechas
quotation_date DATE NOT NULL DEFAULT CURRENT_DATE,
valid_until DATE NOT NULL,
-- Proyecto/Obra
project_name VARCHAR(200),
project_location VARCHAR(255),
-- Totales
subtotal DECIMAL(14,2) DEFAULT 0,
discount_percent DECIMAL(5,2) DEFAULT 0,
discount_amount DECIMAL(14,2) DEFAULT 0,
tax_amount DECIMAL(14,2) DEFAULT 0,
total DECIMAL(14,2) DEFAULT 0,
-- Conversión
sale_order_id UUID, -- FK a sales.sale_orders cuando se confirma
-- Notas
notes TEXT,
terms_conditions TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID REFERENCES auth.users(id),
updated_at TIMESTAMPTZ,
updated_by UUID REFERENCES auth.users(id),
CONSTRAINT uq_quotations_number UNIQUE (tenant_id, quotation_number)
);
-- Tabla: quotation_lines (Líneas de cotización)
CREATE TABLE IF NOT EXISTS vidrio.quotation_lines (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
quotation_id UUID NOT NULL REFERENCES vidrio.quotations(id) ON DELETE CASCADE,
-- Tipo de vidrio
glass_catalog_id UUID NOT NULL REFERENCES vidrio.glass_catalog(id),
-- Dimensiones
width_mm DECIMAL(8,2) NOT NULL,
height_mm DECIMAL(8,2) NOT NULL,
quantity INTEGER NOT NULL DEFAULT 1,
-- Área
area_m2 DECIMAL(12,6) GENERATED ALWAYS AS (
(width_mm / 1000.0) * (height_mm / 1000.0) * quantity
) STORED,
-- Acabados
edge_type vidrio.edge_type DEFAULT 'flat_polished',
has_holes BOOLEAN DEFAULT FALSE,
hole_count INTEGER DEFAULT 0,
has_cutouts BOOLEAN DEFAULT FALSE,
-- Precios
price_per_m2 DECIMAL(12,2) NOT NULL,
processing_cost DECIMAL(12,2) DEFAULT 0,
subtotal DECIMAL(14,2) NOT NULL,
-- Descripción
description TEXT,
-- Orden
sequence INTEGER DEFAULT 1,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID REFERENCES auth.users(id)
);
-- ============================================================================
-- ÍNDICES
-- ============================================================================
-- Glass catalog
CREATE INDEX IF NOT EXISTS idx_glass_catalog_tenant ON vidrio.glass_catalog(tenant_id);
CREATE INDEX IF NOT EXISTS idx_glass_catalog_type ON vidrio.glass_catalog(glass_type);
-- Process catalog
CREATE INDEX IF NOT EXISTS idx_process_catalog_tenant ON vidrio.process_catalog(tenant_id);
-- Production orders
CREATE INDEX IF NOT EXISTS idx_production_orders_tenant ON vidrio.production_orders(tenant_id);
CREATE INDEX IF NOT EXISTS idx_production_orders_status ON vidrio.production_orders(status);
CREATE INDEX IF NOT EXISTS idx_production_orders_customer ON vidrio.production_orders(customer_id);
CREATE INDEX IF NOT EXISTS idx_production_orders_date ON vidrio.production_orders(order_date);
CREATE INDEX IF NOT EXISTS idx_production_orders_due ON vidrio.production_orders(due_date);
-- Production lines
CREATE INDEX IF NOT EXISTS idx_production_lines_tenant ON vidrio.production_lines(tenant_id);
CREATE INDEX IF NOT EXISTS idx_production_lines_order ON vidrio.production_lines(production_order_id);
CREATE INDEX IF NOT EXISTS idx_production_lines_glass ON vidrio.production_lines(glass_catalog_id);
CREATE INDEX IF NOT EXISTS idx_production_lines_status ON vidrio.production_lines(status);
-- Furnaces
CREATE INDEX IF NOT EXISTS idx_furnaces_tenant ON vidrio.furnaces(tenant_id);
CREATE INDEX IF NOT EXISTS idx_furnaces_status ON vidrio.furnaces(status);
-- Furnace batches
CREATE INDEX IF NOT EXISTS idx_furnace_batches_tenant ON vidrio.furnace_batches(tenant_id);
CREATE INDEX IF NOT EXISTS idx_furnace_batches_furnace ON vidrio.furnace_batches(furnace_id);
CREATE INDEX IF NOT EXISTS idx_furnace_batches_date ON vidrio.furnace_batches(start_time);
-- Quality inspections
CREATE INDEX IF NOT EXISTS idx_quality_inspections_tenant ON vidrio.quality_inspections(tenant_id);
CREATE INDEX IF NOT EXISTS idx_quality_inspections_result ON vidrio.quality_inspections(result);
-- Glass lots
CREATE INDEX IF NOT EXISTS idx_glass_lots_tenant ON vidrio.glass_lots(tenant_id);
CREATE INDEX IF NOT EXISTS idx_glass_lots_glass ON vidrio.glass_lots(glass_catalog_id);
CREATE INDEX IF NOT EXISTS idx_glass_lots_supplier ON vidrio.glass_lots(supplier_id);
-- Quotations
CREATE INDEX IF NOT EXISTS idx_quotations_tenant ON vidrio.quotations(tenant_id);
CREATE INDEX IF NOT EXISTS idx_quotations_customer ON vidrio.quotations(customer_id);
CREATE INDEX IF NOT EXISTS idx_quotations_status ON vidrio.quotations(status);
CREATE INDEX IF NOT EXISTS idx_quotations_date ON vidrio.quotations(quotation_date);
-- Quotation lines
CREATE INDEX IF NOT EXISTS idx_quotation_lines_tenant ON vidrio.quotation_lines(tenant_id);
CREATE INDEX IF NOT EXISTS idx_quotation_lines_quotation ON vidrio.quotation_lines(quotation_id);
-- ============================================================================
-- ROW LEVEL SECURITY
-- ============================================================================
ALTER TABLE vidrio.glass_catalog ENABLE ROW LEVEL SECURITY;
ALTER TABLE vidrio.process_catalog ENABLE ROW LEVEL SECURITY;
ALTER TABLE vidrio.production_orders ENABLE ROW LEVEL SECURITY;
ALTER TABLE vidrio.production_lines ENABLE ROW LEVEL SECURITY;
ALTER TABLE vidrio.furnaces ENABLE ROW LEVEL SECURITY;
ALTER TABLE vidrio.furnace_batches ENABLE ROW LEVEL SECURITY;
ALTER TABLE vidrio.cutting_machines ENABLE ROW LEVEL SECURITY;
ALTER TABLE vidrio.quality_tests ENABLE ROW LEVEL SECURITY;
ALTER TABLE vidrio.quality_inspections ENABLE ROW LEVEL SECURITY;
ALTER TABLE vidrio.quality_test_results ENABLE ROW LEVEL SECURITY;
ALTER TABLE vidrio.glass_lots ENABLE ROW LEVEL SECURITY;
ALTER TABLE vidrio.lot_consumption ENABLE ROW LEVEL SECURITY;
ALTER TABLE vidrio.quotations ENABLE ROW LEVEL SECURITY;
ALTER TABLE vidrio.quotation_lines ENABLE ROW LEVEL SECURITY;
-- Políticas de aislamiento por tenant
DO $$ BEGIN
DROP POLICY IF EXISTS tenant_isolation_glass_catalog ON vidrio.glass_catalog;
CREATE POLICY tenant_isolation_glass_catalog ON vidrio.glass_catalog
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;
DO $$ BEGIN
DROP POLICY IF EXISTS tenant_isolation_process_catalog ON vidrio.process_catalog;
CREATE POLICY tenant_isolation_process_catalog ON vidrio.process_catalog
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;
DO $$ BEGIN
DROP POLICY IF EXISTS tenant_isolation_production_orders ON vidrio.production_orders;
CREATE POLICY tenant_isolation_production_orders ON vidrio.production_orders
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;
DO $$ BEGIN
DROP POLICY IF EXISTS tenant_isolation_production_lines ON vidrio.production_lines;
CREATE POLICY tenant_isolation_production_lines ON vidrio.production_lines
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;
DO $$ BEGIN
DROP POLICY IF EXISTS tenant_isolation_furnaces ON vidrio.furnaces;
CREATE POLICY tenant_isolation_furnaces ON vidrio.furnaces
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;
DO $$ BEGIN
DROP POLICY IF EXISTS tenant_isolation_furnace_batches ON vidrio.furnace_batches;
CREATE POLICY tenant_isolation_furnace_batches ON vidrio.furnace_batches
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;
DO $$ BEGIN
DROP POLICY IF EXISTS tenant_isolation_cutting_machines ON vidrio.cutting_machines;
CREATE POLICY tenant_isolation_cutting_machines ON vidrio.cutting_machines
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;
DO $$ BEGIN
DROP POLICY IF EXISTS tenant_isolation_quality_tests ON vidrio.quality_tests;
CREATE POLICY tenant_isolation_quality_tests ON vidrio.quality_tests
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;
DO $$ BEGIN
DROP POLICY IF EXISTS tenant_isolation_quality_inspections ON vidrio.quality_inspections;
CREATE POLICY tenant_isolation_quality_inspections ON vidrio.quality_inspections
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;
DO $$ BEGIN
DROP POLICY IF EXISTS tenant_isolation_quality_test_results ON vidrio.quality_test_results;
CREATE POLICY tenant_isolation_quality_test_results ON vidrio.quality_test_results
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;
DO $$ BEGIN
DROP POLICY IF EXISTS tenant_isolation_glass_lots ON vidrio.glass_lots;
CREATE POLICY tenant_isolation_glass_lots ON vidrio.glass_lots
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;
DO $$ BEGIN
DROP POLICY IF EXISTS tenant_isolation_lot_consumption ON vidrio.lot_consumption;
CREATE POLICY tenant_isolation_lot_consumption ON vidrio.lot_consumption
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;
DO $$ BEGIN
DROP POLICY IF EXISTS tenant_isolation_quotations ON vidrio.quotations;
CREATE POLICY tenant_isolation_quotations ON vidrio.quotations
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;
DO $$ BEGIN
DROP POLICY IF EXISTS tenant_isolation_quotation_lines ON vidrio.quotation_lines;
CREATE POLICY tenant_isolation_quotation_lines ON vidrio.quotation_lines
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;
-- ============================================================================
-- COMENTARIOS
-- ============================================================================
COMMENT ON TABLE vidrio.glass_catalog IS 'Catálogo de tipos de vidrio';
COMMENT ON TABLE vidrio.process_catalog IS 'Catálogo de procesos de manufactura';
COMMENT ON TABLE vidrio.production_orders IS 'Órdenes de producción';
COMMENT ON TABLE vidrio.production_lines IS 'Piezas individuales de producción';
COMMENT ON TABLE vidrio.furnaces IS 'Hornos de templado';
COMMENT ON TABLE vidrio.furnace_batches IS 'Lotes de hornada';
COMMENT ON TABLE vidrio.cutting_machines IS 'Máquinas de corte';
COMMENT ON TABLE vidrio.quality_tests IS 'Catálogo de pruebas de calidad';
COMMENT ON TABLE vidrio.quality_inspections IS 'Inspecciones de calidad';
COMMENT ON TABLE vidrio.quality_test_results IS 'Resultados de pruebas';
COMMENT ON TABLE vidrio.glass_lots IS 'Lotes de vidrio crudo (trazabilidad)';
COMMENT ON TABLE vidrio.lot_consumption IS 'Consumo de lotes en producción';
COMMENT ON TABLE vidrio.quotations IS 'Cotizaciones de vidrio';
COMMENT ON TABLE vidrio.quotation_lines IS 'Piezas cotizadas';
-- ============================================================================
-- FIN TABLAS VIDRIO
-- Total: 14 tablas, 5 ENUMs
-- ============================================================================