-- ===================================================== -- SISTEMA DE TRAZABILIDAD - VINCULACIONES EXTERNAS -- ===================================================== -- Este esquema permite vincular registros de sistemas externos -- (Ingresos, Carretas, Salidas, Rechazos) con los lotes del sistema. -- Los registros externos se consultan via Metabase API (solo lectura). -- ===================================================== -- TABLA: vinculaciones_externas -- ===================================================== -- Relaciona registros de tablas externas con lotes locales. -- Cardinalidad: N registros → 1 lote CREATE TABLE IF NOT EXISTS vinculaciones_externas ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), -- Identificación del registro externo tipo_registro TEXT NOT NULL, -- 'ingreso', 'carreta', 'salida', 'rechazo' registro_id BIGINT NOT NULL, -- ID del registro en la tabla externa -- Vinculación al lote local lote_id UUID NOT NULL REFERENCES lotes(id) ON DELETE CASCADE, -- Metadatos de la vinculación fecha_vinculacion TIMESTAMPTZ NOT NULL DEFAULT NOW(), usuario_id TEXT, -- Usuario de Authentik que hizo la vinculación observaciones TEXT, -- Cache de datos del registro externo (para evitar consultas repetidas) datos_cache JSONB, -- Snapshot del registro al momento de vincular -- Periodo de cosecha (para filtros y unicidad) periodo_cosecha TEXT NOT NULL DEFAULT '25-26', -- '25-26' para cosecha 2025-2026 -- Un registro externo solo puede vincularse una vez por periodo CONSTRAINT vinculaciones_registro_unico UNIQUE (tipo_registro, registro_id, periodo_cosecha), CONSTRAINT vinculaciones_tipo_valido CHECK (tipo_registro IN ( 'ingreso', 'carreta', 'salida', 'rechazo' )) ); -- Índices para consultas frecuentes CREATE INDEX IF NOT EXISTS idx_vinculaciones_lote ON vinculaciones_externas(lote_id); CREATE INDEX IF NOT EXISTS idx_vinculaciones_tipo ON vinculaciones_externas(tipo_registro); CREATE INDEX IF NOT EXISTS idx_vinculaciones_periodo ON vinculaciones_externas(periodo_cosecha); CREATE INDEX IF NOT EXISTS idx_vinculaciones_registro ON vinculaciones_externas(tipo_registro, registro_id); CREATE INDEX IF NOT EXISTS idx_vinculaciones_fecha ON vinculaciones_externas(fecha_vinculacion DESC); -- Comentarios COMMENT ON TABLE vinculaciones_externas IS 'Vincula registros de sistemas externos (Ingresos, Carretas, Salidas, Rechazos) con lotes locales'; COMMENT ON COLUMN vinculaciones_externas.tipo_registro IS 'Tipo de registro externo: ingreso, carreta, salida, rechazo'; COMMENT ON COLUMN vinculaciones_externas.registro_id IS 'ID del registro en la tabla externa (Metabase)'; COMMENT ON COLUMN vinculaciones_externas.lote_id IS 'FK al lote local al que se vincula'; COMMENT ON COLUMN vinculaciones_externas.datos_cache IS 'Snapshot JSONB del registro al momento de vincular (para evitar consultas repetidas)'; COMMENT ON COLUMN vinculaciones_externas.periodo_cosecha IS 'Periodo de cosecha en formato YY-YY (ej: 25-26)'; -- ===================================================== -- VISTA: vista_lotes_con_vinculaciones -- ===================================================== -- Muestra cada lote con el conteo de vinculaciones por tipo. CREATE OR REPLACE VIEW vista_lotes_con_vinculaciones AS SELECT l.id, l.codigo, l.tipo, l.fecha_creado, l.cantidad_kg, l.meta, l.lugar_id, COUNT(*) FILTER (WHERE v.tipo_registro = 'ingreso') AS ingresos_vinculados, COUNT(*) FILTER (WHERE v.tipo_registro = 'carreta') AS carretas_vinculadas, COUNT(*) FILTER (WHERE v.tipo_registro = 'salida') AS salidas_vinculadas, COUNT(*) FILTER (WHERE v.tipo_registro = 'rechazo') AS rechazos_vinculados, COUNT(v.id) AS total_vinculaciones FROM lotes l LEFT JOIN vinculaciones_externas v ON v.lote_id = l.id GROUP BY l.id, l.codigo, l.tipo, l.fecha_creado, l.cantidad_kg, l.meta, l.lugar_id; COMMENT ON VIEW vista_lotes_con_vinculaciones IS 'Muestra lotes con conteo de registros vinculados por tipo'; -- ===================================================== -- FUNCIÓN: get_estadisticas_vinculacion -- ===================================================== -- Obtiene estadísticas de vinculación para un periodo dado. CREATE OR REPLACE FUNCTION get_estadisticas_vinculacion(p_periodo TEXT DEFAULT '25-26') RETURNS TABLE ( tipo_registro TEXT, total BIGINT, vinculados BIGINT, sin_vincular BIGINT, porcentaje NUMERIC ) AS $$ BEGIN RETURN QUERY SELECT v.tipo_registro, COUNT(*)::BIGINT AS total, COUNT(*)::BIGINT AS vinculados, 0::BIGINT AS sin_vincular, -- Se calculará con datos de Metabase 100.0 AS porcentaje FROM vinculaciones_externas v WHERE v.periodo_cosecha = p_periodo GROUP BY v.tipo_registro ORDER BY v.tipo_registro; END; $$ LANGUAGE plpgsql; COMMENT ON FUNCTION get_estadisticas_vinculacion IS 'Retorna estadísticas de vinculación por tipo de registro para un periodo'; -- ===================================================== -- MENSAJES DE ÉXITO -- ===================================================== DO $$ BEGIN RAISE NOTICE '✓ Esquema de vinculaciones externas creado exitosamente'; RAISE NOTICE ' - Tabla vinculaciones_externas creada'; RAISE NOTICE ' - Vista vista_lotes_con_vinculaciones creada'; RAISE NOTICE ' - Función get_estadisticas_vinculacion() creada'; END $$;