erp-core-database/ddl/schemas/core_shared/00-schema.sql

160 lines
5.2 KiB
PL/PgSQL

-- ============================================================================
-- Schema: core_shared
-- Descripcion: Funciones y tipos compartidos entre todos los modulos
-- Proyecto: ERP Core
-- Autor: Database-Agent
-- Fecha: 2025-12-06
-- ============================================================================
-- Crear schema
CREATE SCHEMA IF NOT EXISTS core_shared;
COMMENT ON SCHEMA core_shared IS 'Funciones, tipos y utilidades compartidas entre modulos';
-- ============================================================================
-- FUNCIONES DE AUDITORIA
-- ============================================================================
-- Funcion para actualizar updated_at automaticamente
CREATE OR REPLACE FUNCTION core_shared.set_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
COMMENT ON FUNCTION core_shared.set_updated_at() IS
'Trigger function para actualizar automaticamente el campo updated_at en cada UPDATE';
-- Funcion para establecer tenant_id desde contexto
CREATE OR REPLACE FUNCTION core_shared.set_tenant_id()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.tenant_id IS NULL THEN
NEW.tenant_id = current_setting('app.current_tenant_id', true)::uuid;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
COMMENT ON FUNCTION core_shared.set_tenant_id() IS
'Trigger function para establecer tenant_id automaticamente desde el contexto de sesion';
-- Funcion para establecer created_by desde contexto
CREATE OR REPLACE FUNCTION core_shared.set_created_by()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.created_by IS NULL THEN
NEW.created_by = current_setting('app.current_user_id', true)::uuid;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
COMMENT ON FUNCTION core_shared.set_created_by() IS
'Trigger function para establecer created_by automaticamente desde el contexto de sesion';
-- Funcion para establecer updated_by desde contexto
CREATE OR REPLACE FUNCTION core_shared.set_updated_by()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_by = current_setting('app.current_user_id', true)::uuid;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
COMMENT ON FUNCTION core_shared.set_updated_by() IS
'Trigger function para establecer updated_by automaticamente desde el contexto de sesion';
-- ============================================================================
-- FUNCIONES DE CONTEXTO
-- ============================================================================
-- Obtener tenant_id actual del contexto
CREATE OR REPLACE FUNCTION core_shared.get_current_tenant_id()
RETURNS UUID AS $$
BEGIN
RETURN NULLIF(current_setting('app.current_tenant_id', true), '')::UUID;
EXCEPTION
WHEN OTHERS THEN
RETURN NULL;
END;
$$ LANGUAGE plpgsql STABLE;
COMMENT ON FUNCTION core_shared.get_current_tenant_id() IS
'Obtiene el ID del tenant actual desde el contexto de sesion';
-- Obtener user_id actual del contexto
CREATE OR REPLACE FUNCTION core_shared.get_current_user_id()
RETURNS UUID AS $$
BEGIN
RETURN NULLIF(current_setting('app.current_user_id', true), '')::UUID;
EXCEPTION
WHEN OTHERS THEN
RETURN NULL;
END;
$$ LANGUAGE plpgsql STABLE;
COMMENT ON FUNCTION core_shared.get_current_user_id() IS
'Obtiene el ID del usuario actual desde el contexto de sesion';
-- ============================================================================
-- FUNCIONES DE UTILIDAD
-- ============================================================================
-- Generar slug desde texto
CREATE OR REPLACE FUNCTION core_shared.generate_slug(input_text TEXT)
RETURNS TEXT AS $$
BEGIN
RETURN LOWER(
REGEXP_REPLACE(
REGEXP_REPLACE(
TRIM(input_text),
'[^a-zA-Z0-9\s-]', '', 'g'
),
'\s+', '-', 'g'
)
);
END;
$$ LANGUAGE plpgsql IMMUTABLE;
COMMENT ON FUNCTION core_shared.generate_slug(TEXT) IS
'Genera un slug URL-friendly desde un texto';
-- Validar formato de email
CREATE OR REPLACE FUNCTION core_shared.is_valid_email(email TEXT)
RETURNS BOOLEAN AS $$
BEGIN
RETURN email ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$';
END;
$$ LANGUAGE plpgsql IMMUTABLE;
COMMENT ON FUNCTION core_shared.is_valid_email(TEXT) IS
'Valida si un texto tiene formato de email valido';
-- Validar formato de RFC mexicano
CREATE OR REPLACE FUNCTION core_shared.is_valid_rfc(rfc TEXT)
RETURNS BOOLEAN AS $$
BEGIN
-- RFC persona moral: 3 letras + 6 digitos + 3 caracteres
-- RFC persona fisica: 4 letras + 6 digitos + 3 caracteres
RETURN rfc ~* '^[A-Z&Ñ]{3,4}[0-9]{6}[A-Z0-9]{3}$';
END;
$$ LANGUAGE plpgsql IMMUTABLE;
COMMENT ON FUNCTION core_shared.is_valid_rfc(TEXT) IS
'Valida si un texto tiene formato de RFC mexicano valido';
-- ============================================================================
-- GRANT PERMISOS
-- ============================================================================
-- Permitir uso del schema a todos los roles de la aplicacion
GRANT USAGE ON SCHEMA core_shared TO PUBLIC;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA core_shared TO PUBLIC;
-- ============================================================================
-- FIN
-- ============================================================================