-- ============================================================================= -- Horux Strategy - Script de Inicializacion PostgreSQL -- ============================================================================= -- Este script se ejecuta automaticamente cuando el contenedor de PostgreSQL -- se inicia por primera vez. -- -- Crea: -- - Base de datos horux_strategy -- - Usuario de aplicacion con permisos limitados -- - Extensiones necesarias -- - Esquemas base -- ============================================================================= -- Crear base de datos si no existe (la variable POSTGRES_DB ya la crea) -- Este bloque es por si se necesita una base de datos adicional -- CREATE DATABASE horux_strategy_test; -- ============================================================================= -- Extensiones necesarias -- ============================================================================= -- UUID: Generacion de identificadores unicos universales -- Usado para IDs de entidades (usuarios, empresas, transacciones, etc.) CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- pgcrypto: Funciones criptograficas -- Usado para hash de passwords, generacion de tokens seguros CREATE EXTENSION IF NOT EXISTS "pgcrypto"; -- pg_trgm: Busqueda por trigramas -- Mejora las busquedas de texto parcial (LIKE, ILIKE) CREATE EXTENSION IF NOT EXISTS "pg_trgm"; -- btree_gin: Indices GIN para tipos de datos adicionales -- Mejora consultas con multiples condiciones en indices compuestos CREATE EXTENSION IF NOT EXISTS "btree_gin"; -- ============================================================================= -- Usuario de aplicacion -- ============================================================================= -- Creamos un usuario con permisos limitados para la aplicacion -- Esto sigue el principio de menor privilegio DO $$ BEGIN -- Crear usuario de aplicacion si no existe IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'horux_app') THEN CREATE USER horux_app WITH PASSWORD 'horux_app_secret'; END IF; END $$; -- Permisos en la base de datos GRANT CONNECT ON DATABASE horux_strategy TO horux_app; -- Permisos en el esquema public GRANT USAGE ON SCHEMA public TO horux_app; GRANT CREATE ON SCHEMA public TO horux_app; -- Permisos por defecto para tablas futuras ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO horux_app; -- Permisos por defecto para secuencias futuras ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO horux_app; -- ============================================================================= -- Esquemas adicionales (opcional) -- ============================================================================= -- Esquema para datos de auditoria CREATE SCHEMA IF NOT EXISTS audit; GRANT USAGE ON SCHEMA audit TO horux_app; GRANT CREATE ON SCHEMA audit TO horux_app; ALTER DEFAULT PRIVILEGES IN SCHEMA audit GRANT SELECT, INSERT ON TABLES TO horux_app; -- Esquema para reportes y vistas materializadas CREATE SCHEMA IF NOT EXISTS reports; GRANT USAGE ON SCHEMA reports TO horux_app; ALTER DEFAULT PRIVILEGES IN SCHEMA reports GRANT SELECT ON TABLES TO horux_app; -- ============================================================================= -- Funciones de utilidad -- ============================================================================= -- Funcion para generar UUIDs v4 CREATE OR REPLACE FUNCTION generate_uuid() RETURNS UUID AS $$ BEGIN RETURN uuid_generate_v4(); END; $$ LANGUAGE plpgsql; -- Funcion para actualizar timestamps automaticamente CREATE OR REPLACE FUNCTION update_updated_at_column() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = CURRENT_TIMESTAMP; RETURN NEW; END; $$ LANGUAGE plpgsql; -- Funcion para registrar cambios en auditoria CREATE OR REPLACE FUNCTION audit.log_changes() RETURNS TRIGGER AS $$ DECLARE audit_table_name TEXT; BEGIN audit_table_name := TG_TABLE_SCHEMA || '.' || TG_TABLE_NAME || '_audit'; IF TG_OP = 'DELETE' THEN EXECUTE format( 'INSERT INTO audit.changes_log (table_name, operation, old_data, changed_at) VALUES ($1, $2, $3, CURRENT_TIMESTAMP)' ) USING TG_TABLE_NAME, TG_OP, row_to_json(OLD); RETURN OLD; ELSIF TG_OP = 'UPDATE' THEN EXECUTE format( 'INSERT INTO audit.changes_log (table_name, operation, old_data, new_data, changed_at) VALUES ($1, $2, $3, $4, CURRENT_TIMESTAMP)' ) USING TG_TABLE_NAME, TG_OP, row_to_json(OLD), row_to_json(NEW); RETURN NEW; ELSIF TG_OP = 'INSERT' THEN EXECUTE format( 'INSERT INTO audit.changes_log (table_name, operation, new_data, changed_at) VALUES ($1, $2, $3, CURRENT_TIMESTAMP)' ) USING TG_TABLE_NAME, TG_OP, row_to_json(NEW); RETURN NEW; END IF; RETURN NULL; END; $$ LANGUAGE plpgsql; -- Tabla para log de cambios de auditoria CREATE TABLE IF NOT EXISTS audit.changes_log ( id BIGSERIAL PRIMARY KEY, table_name VARCHAR(100) NOT NULL, operation VARCHAR(10) NOT NULL, old_data JSONB, new_data JSONB, changed_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, changed_by UUID -- Se puede llenar con el usuario de la sesion ); -- Indice para busquedas rapidas por tabla y fecha CREATE INDEX IF NOT EXISTS idx_audit_changes_table_date ON audit.changes_log (table_name, changed_at DESC); -- ============================================================================= -- Mensaje de confirmacion -- ============================================================================= DO $$ BEGIN RAISE NOTICE '==========================================='; RAISE NOTICE 'Horux Strategy - Base de datos inicializada'; RAISE NOTICE '==========================================='; RAISE NOTICE 'Extensiones instaladas:'; RAISE NOTICE ' - uuid-ossp'; RAISE NOTICE ' - pgcrypto'; RAISE NOTICE ' - pg_trgm'; RAISE NOTICE ' - btree_gin'; RAISE NOTICE 'Usuarios creados:'; RAISE NOTICE ' - horux_app (usuario de aplicacion)'; RAISE NOTICE 'Esquemas creados:'; RAISE NOTICE ' - public (tablas principales)'; RAISE NOTICE ' - audit (auditoria de cambios)'; RAISE NOTICE ' - reports (reportes y vistas)'; RAISE NOTICE '==========================================='; END $$;