-- ============================================================================ -- 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 -- ============================================================================