erp-transportistas-database-v2/ddl/05-maintenance-schema-ddl.sql
Adrian Flores Cortes 7a91823784 feat: Add complete DDL for all transport schemas (01-08)
DDL files created:
- 01-transport-schema-ddl.sql: OT, embarques, viajes, paradas, POD, incidencias
- 02-fleet-schema-ddl.sql: unidades, remolques, operadores, documentos, asignaciones
- 03-tracking-schema-ddl.sql: posiciones GPS, eventos, geocercas, alertas, ETA
- 04-fuel-schema-ddl.sql: cargas combustible, peajes, gastos, anticipos, rendimiento
- 05-maintenance-schema-ddl.sql: planes, programacion, ordenes trabajo, checklist
- 06-carriers-schema-ddl.sql: carriers, documentos, unidades, operadores, scorecard
- 07-billing-transport-ddl.sql: lanes, tarifas, recargos, facturas, fuel surcharge
- 08-compliance-schema-ddl.sql: carta porte CFDI 3.1, HOS NOM-087, inspecciones

Features:
- All tables with tenant_id and RLS policies
- ENUMs for all status and type fields
- Proper indexes for common queries
- PostGIS for geospatial data
- Partitioned tables for high-volume GPS data
- CFDI Carta Porte 3.1 compliant structure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 10:26:20 -06:00

307 lines
9.4 KiB
SQL

-- =============================================================================
-- ERP TRANSPORTISTAS - Schema Maintenance DDL
-- =============================================================================
-- Archivo: 05-maintenance-schema-ddl.sql
-- Version: 1.0.0
-- Fecha: 2026-01-25
-- Descripcion: Mantenimiento preventivo, correctivo, ordenes de trabajo
-- =============================================================================
-- =============================================================================
-- TIPOS ENUMERADOS
-- =============================================================================
CREATE TYPE maintenance.tipo_mantenimiento AS ENUM (
'PREVENTIVO',
'CORRECTIVO',
'PREDICTIVO',
'EMERGENCIA'
);
CREATE TYPE maintenance.prioridad AS ENUM (
'BAJA',
'MEDIA',
'ALTA',
'URGENTE'
);
CREATE TYPE maintenance.estado_orden AS ENUM (
'BORRADOR',
'PROGRAMADA',
'EN_PROCESO',
'ESPERANDO_REFACCIONES',
'COMPLETADA',
'CANCELADA'
);
CREATE TYPE maintenance.tipo_servicio AS ENUM (
'CAMBIO_ACEITE',
'FRENOS',
'LLANTAS',
'SUSPENSION',
'MOTOR',
'TRANSMISION',
'ELECTRICO',
'CARROCERIA',
'REFRIGERACION',
'ALINEACION_BALANCEO',
'REVISION_GENERAL',
'OTRO'
);
-- =============================================================================
-- TABLA: planes_mantenimiento
-- =============================================================================
CREATE TABLE maintenance.planes_mantenimiento (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES public.tenants(id),
-- Identificación
codigo VARCHAR(50) NOT NULL,
nombre VARCHAR(200) NOT NULL,
descripcion TEXT,
-- Tipo de unidad que aplica
aplica_tipo_unidad fleet.tipo_unidad[],
aplica_todas_unidades BOOLEAN DEFAULT FALSE,
-- Frecuencia
frecuencia_km INT,
frecuencia_dias INT,
frecuencia_horas_motor INT,
-- Servicios incluidos
servicios maintenance.tipo_servicio[] NOT NULL,
-- Costos estimados
costo_estimado_mano_obra DECIMAL(12, 2),
costo_estimado_refacciones DECIMAL(12, 2),
tiempo_estimado_horas DECIMAL(6, 2),
-- Estado
activo BOOLEAN DEFAULT TRUE,
-- Auditoría
created_at TIMESTAMPTZ DEFAULT NOW(),
created_by_id UUID NOT NULL,
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_plan_tenant ON maintenance.planes_mantenimiento(tenant_id);
CREATE UNIQUE INDEX idx_plan_codigo ON maintenance.planes_mantenimiento(tenant_id, codigo);
-- =============================================================================
-- TABLA: programacion_mantenimiento
-- =============================================================================
CREATE TABLE maintenance.programacion_mantenimiento (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES public.tenants(id),
-- Unidad y plan
unidad_id UUID NOT NULL,
plan_id UUID REFERENCES maintenance.planes_mantenimiento(id),
-- Tipo
tipo maintenance.tipo_mantenimiento NOT NULL,
-- Próximo mantenimiento
proximo_km INT,
proxima_fecha DATE,
proximas_horas_motor INT,
-- Último mantenimiento
ultimo_km INT,
ultima_fecha DATE,
ultima_orden_id UUID,
-- Estado
vencido BOOLEAN DEFAULT FALSE,
dias_para_vencer INT,
-- Auditoría
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_programacion_unidad ON maintenance.programacion_mantenimiento(unidad_id);
CREATE INDEX idx_programacion_vencido ON maintenance.programacion_mantenimiento(tenant_id, vencido);
CREATE INDEX idx_programacion_proxima ON maintenance.programacion_mantenimiento(proxima_fecha);
-- =============================================================================
-- TABLA: ordenes_trabajo
-- =============================================================================
CREATE TABLE maintenance.ordenes_trabajo (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES public.tenants(id),
-- Identificación
numero_orden VARCHAR(50) NOT NULL,
-- Unidad
unidad_id UUID NOT NULL,
remolque_id UUID,
-- Tipo y prioridad
tipo maintenance.tipo_mantenimiento NOT NULL,
prioridad maintenance.prioridad DEFAULT 'MEDIA',
-- Diagnóstico inicial
descripcion_falla TEXT,
reportado_por VARCHAR(200),
reportado_fecha TIMESTAMPTZ,
-- Programación
fecha_programada DATE,
hora_programada TIME,
taller_id UUID,
taller_externo_nombre VARCHAR(200),
es_taller_externo BOOLEAN DEFAULT FALSE,
-- Ejecución
fecha_inicio TIMESTAMPTZ,
fecha_fin TIMESTAMPTZ,
mecanico_responsable VARCHAR(200),
-- Odómetro
odometro_entrada INT,
odometro_salida INT,
-- Diagnóstico final
diagnostico_final TEXT,
trabajos_realizados TEXT,
-- Costos
costo_mano_obra DECIMAL(12, 2) DEFAULT 0,
costo_refacciones DECIMAL(12, 2) DEFAULT 0,
costo_otros DECIMAL(12, 2) DEFAULT 0,
costo_total DECIMAL(12, 2) DEFAULT 0,
-- Plan relacionado
plan_id UUID REFERENCES maintenance.planes_mantenimiento(id),
-- Estado
estado maintenance.estado_orden DEFAULT 'BORRADOR',
-- Garantía
tiene_garantia BOOLEAN DEFAULT FALSE,
garantia_dias INT,
garantia_km INT,
-- Auditoría
created_at TIMESTAMPTZ DEFAULT NOW(),
created_by_id UUID NOT NULL,
updated_at TIMESTAMPTZ DEFAULT NOW(),
updated_by_id UUID
);
CREATE INDEX idx_ot_tenant ON maintenance.ordenes_trabajo(tenant_id);
CREATE INDEX idx_ot_unidad ON maintenance.ordenes_trabajo(unidad_id);
CREATE INDEX idx_ot_estado ON maintenance.ordenes_trabajo(tenant_id, estado);
CREATE INDEX idx_ot_fecha ON maintenance.ordenes_trabajo(fecha_programada);
CREATE UNIQUE INDEX idx_ot_numero ON maintenance.ordenes_trabajo(tenant_id, numero_orden);
-- =============================================================================
-- TABLA: lineas_orden_trabajo (Refacciones usadas)
-- =============================================================================
CREATE TABLE maintenance.lineas_orden_trabajo (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES public.tenants(id),
orden_id UUID NOT NULL REFERENCES maintenance.ordenes_trabajo(id),
-- Tipo de línea
tipo VARCHAR(20) NOT NULL, -- 'REFACCION', 'MANO_OBRA', 'OTRO'
-- Refacción (si aplica)
producto_id UUID,
numero_parte VARCHAR(100),
descripcion VARCHAR(500) NOT NULL,
-- Cantidades
cantidad DECIMAL(10, 3) NOT NULL,
unidad_medida VARCHAR(20),
-- Precios
precio_unitario DECIMAL(12, 2) NOT NULL,
descuento DECIMAL(12, 2) DEFAULT 0,
total DECIMAL(12, 2) NOT NULL,
-- Proveedor
proveedor_id UUID,
proveedor_nombre VARCHAR(200),
-- Factura
factura_proveedor VARCHAR(50)
);
CREATE INDEX idx_linea_ot ON maintenance.lineas_orden_trabajo(orden_id);
-- =============================================================================
-- TABLA: checklist_mantenimiento
-- =============================================================================
CREATE TABLE maintenance.checklist_items (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES public.tenants(id),
orden_id UUID NOT NULL REFERENCES maintenance.ordenes_trabajo(id),
-- Item
categoria VARCHAR(100),
descripcion VARCHAR(500) NOT NULL,
obligatorio BOOLEAN DEFAULT FALSE,
-- Resultado
resultado VARCHAR(20), -- 'OK', 'REPARADO', 'PENDIENTE', 'NO_APLICA'
observaciones TEXT,
-- Evidencia
foto_url TEXT,
-- Revisado
revisado_por VARCHAR(200),
revisado_fecha TIMESTAMPTZ
);
CREATE INDEX idx_checklist_orden ON maintenance.checklist_items(orden_id);
-- =============================================================================
-- RLS POLICIES
-- =============================================================================
ALTER TABLE maintenance.planes_mantenimiento ENABLE ROW LEVEL SECURITY;
ALTER TABLE maintenance.programacion_mantenimiento ENABLE ROW LEVEL SECURITY;
ALTER TABLE maintenance.ordenes_trabajo ENABLE ROW LEVEL SECURITY;
ALTER TABLE maintenance.lineas_orden_trabajo ENABLE ROW LEVEL SECURITY;
ALTER TABLE maintenance.checklist_items ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation_planes ON maintenance.planes_mantenimiento
USING (tenant_id = current_setting('app.tenant_id')::uuid);
CREATE POLICY tenant_isolation_programacion ON maintenance.programacion_mantenimiento
USING (tenant_id = current_setting('app.tenant_id')::uuid);
CREATE POLICY tenant_isolation_ordenes ON maintenance.ordenes_trabajo
USING (tenant_id = current_setting('app.tenant_id')::uuid);
CREATE POLICY tenant_isolation_lineas ON maintenance.lineas_orden_trabajo
USING (tenant_id = current_setting('app.tenant_id')::uuid);
CREATE POLICY tenant_isolation_checklist ON maintenance.checklist_items
USING (tenant_id = current_setting('app.tenant_id')::uuid);
-- =============================================================================
-- COMENTARIOS
-- =============================================================================
COMMENT ON TABLE maintenance.planes_mantenimiento IS 'Planes de mantenimiento preventivo';
COMMENT ON TABLE maintenance.programacion_mantenimiento IS 'Programación de próximos mantenimientos por unidad';
COMMENT ON TABLE maintenance.ordenes_trabajo IS 'Órdenes de trabajo de mantenimiento';
COMMENT ON TABLE maintenance.lineas_orden_trabajo IS 'Líneas de detalle de órdenes de trabajo';
COMMENT ON TABLE maintenance.checklist_items IS 'Items de checklist de mantenimiento';
-- =============================================================================
-- FIN DDL MAINTENANCE
-- =============================================================================