# frozen_string_literal: true # adn/tools/subcomando_triggers.rb — Subcomando para gestión del sistema de triggers ADN # ================================================================================ # Este subcomando permite gestionar el sistema de triggers que implementa # el Principio de Armonía Integral mediante la propagación automática de cambios. # # Integrado con: ADN::Triggers (adn/tools/triggers.rb) # Configuración: adn/triggers.yml # # 📅 Última actualización: 2026-03-07 (Fase 2: Automatización Inteligente) # 📚 Referencia: docs/plan/260307-1400_Plan_Mejoras_ADN.md require 'optparse' require_relative 'triggers/motor' require_relative 'triggers/eventos' module ADN class SubcomandoTriggers def initialize(args, logger) @args = args @logger = logger @opciones = { test: false, forzar: false, listar: false, registrar: false, limpiar: false, trigger_id: nil, ayuda: false } end # Ejecuta el subcomando con las opciones especificadas def ejecutar parser = crear_parser begin parser.parse!(@args) rescue OptionParser::InvalidOption => e @logger.error("Opción inválida: #{e.message}") puts parser exit 1 end if @opciones[:ayuda] || @args.empty? && !@opciones[:listar] && !@opciones[:limpiar] && !@opciones[:registrar] mostrar_ayuda(parser) return end # Cargar configuración primero cargar_configuracion # Ejecutar acción según opciones if @opciones[:listar] listar_triggers elsif @opciones[:registrar] registrar_triggers elsif @opciones[:limpiar] limpiar_triggers elsif @opciones[:test] probar_trigger else ejecutar_triggers end end private # Crea el parser de opciones def crear_parser OptionParser.new do |opts| opts.banner = "Uso: ./adn/tools/run triggers [OPCIONES]" opts.separator "" opts.separator "Gestiona el sistema de triggers para sincronización automática del ADN" opts.separator "" opts.separator "Opciones:" opts.on("--test [TRIGGER_ID]", "Probar un trigger específico (modo simulación)") do |trigger_id| @opciones[:test] = true @opciones[:trigger_id] = trigger_id end opts.on("--forzar", "Ejecutar triggers incluso si sistema deshabilitado") do @opciones[:forzar] = true end opts.on("--listar", "Listar todos los triggers configurados") do @opciones[:listar] = true end opts.on("--registrar", "Registrar triggers en el bus de eventos") do @opciones[:registrar] = true end opts.on("--limpiar", "Limpiar todos los triggers registrados") do @opciones[:limpiar] = true end opts.on("-h", "--help", "Mostrar esta ayuda") do @opciones[:ayuda] = true end end end # Muestra la ayuda del subcomando def mostrar_ayuda(parser) puts parser puts "" puts "Descripción:" puts " El sistema de triggers implementa el Principio de Armonía Integral al propagar" puts " automáticamente cambios entre diferentes componentes del sistema ADN." puts "" puts " Triggers definidos en: adn/triggers.yml" puts " Bus de eventos: adn/tools/eventos.rb" puts " Motor de triggers: adn/tools/triggers.rb" puts "" puts "Ejemplos:" puts " ./adn/tools/run triggers --listar" puts " ./adn/tools/run triggers --registrar" puts " ./adn/tools/run triggers --test bitacoras_0" puts " ./adn/tools/run triggers --forzar" puts " ./adn/tools/run triggers --limpiar" puts "" puts "📚 Documentación: docs/plan/260307-1400_Plan_Mejoras_ADN.md" end # Carga la configuración de triggers def cargar_configuracion @logger.info("Cargando configuración de triggers...") begin @triggers = ADN::Triggers.instance @triggers.cargar_configuracion @logger.exito("Configuración de triggers cargada") rescue => e @logger.error("Error cargando configuración: #{e.message}") exit 1 end end # Lista todos los triggers configurados def listar_triggers @logger.info("Listando triggers configurados...") triggers = @triggers.lista_triggers if triggers.empty? puts "#{Color::YELLOW}ℹ No se encontraron triggers configurados#{Color::RESET}" return end puts "#{Color::CYAN}📋 Triggers configurados (#{triggers.length} total)#{Color::RESET}" puts "#{Color::DIM}#{'-' * 80}#{Color::RESET}" triggers.each do |trigger| estado = trigger[:habilitado] ? "#{Color::GREEN}✓#{Color::RESET}" : "#{Color::DIM}✗#{Color::RESET}" suscriptores = trigger[:suscriptores_registrados] > 0 ? "#{Color::CYAN}(#{trigger[:suscriptores_registrados]} susc.)#{Color::RESET}" : "" puts " #{estado} #{trigger[:id]} #{suscriptores}" puts " #{Color::DIM}Evento:#{Color::RESET} #{trigger[:evento]}" puts " #{Color::DIM}Acción:#{Color::RESET} #{trigger[:accion]}" if trigger[:condicion] && !trigger[:condicion].empty? puts " #{Color::DIM}Condición:#{Color::RESET} #{trigger[:condicion]}" end puts " #{Color::DIM}Descripción:#{Color::RESET} #{trigger[:descripcion]}" puts "" end habilitados = triggers.count { |t| t[:habilitado] } puts "#{Color::DIM}Triggers habilitados: #{habilitados}/#{triggers.length}#{Color::RESET}" @logger.info("Listado completado: #{triggers.length} triggers encontrados") end # Registra triggers en el bus de eventos def registrar_triggers @logger.info("Registrando triggers en el bus de eventos...") registrados = @triggers.registrar_triggers if registrados > 0 @logger.exito("#{registrados} trigger(s) registrado(s) en el bus de eventos") puts "#{Color::GREEN}✓ #{registrados} trigger(s) registrado(s)#{Color::RESET}" puts "#{Color::DIM}Los triggers responderán a eventos automáticamente#{Color::RESET}" else @logger.advertencia("No se registraron triggers (sistema deshabilitado o sin triggers habilitados)") puts "#{Color::YELLOW}⚠ No se registraron triggers#{Color::RESET}" puts "#{Color::DIM}Verifica que el sistema esté habilitado en adn/triggers.yml#{Color::RESET}" end end # Limpia todos los triggers registrados def limpiar_triggers @logger.info("Limpiando triggers registrados...") limpiados = @triggers.limpiar_triggers_registrados @logger.exito("#{limpiados} trigger(s) limpiado(s) del bus de eventos") puts "#{Color::GREEN}✓ #{limpiados} trigger(s) limpiado(s)#{Color::RESET}" puts "#{Color::DIM}Los triggers ya no responderán a eventos automáticamente#{Color::RESET}" end # Prueba un trigger específico def probar_trigger trigger_id = @opciones[:trigger_id] unless trigger_id @logger.error("Se requiere ID de trigger para probar (ej: bitacoras_0)") puts "#{Color::RED}✗ Se requiere ID de trigger para probar#{Color::RESET}" puts " Ejemplo: ./adn/tools/run triggers --test bitacoras_0" puts " Usa --listar para ver IDs disponibles" exit 1 end @logger.info("Probando trigger: #{trigger_id}") # Datos simulados para la prueba datos_simulados = { modo: 'prueba', timestamp: Time.now.utc, descripcion: "Datos simulados para prueba del trigger" } # Ejecutar prueba resultado = @triggers.probar_trigger(trigger_id, datos_simulados) # Mostrar resultados mostrar_resultado_prueba(resultado) end # Ejecuta todos los triggers (modo batch) def ejecutar_triggers @logger.info("Ejecutando triggers en modo batch...") resultados = @triggers.ejecutar_triggers(forzar: @opciones[:forzar]) mostrar_resultados_ejecucion(resultados) end # Muestra el resultado de una prueba de trigger def mostrar_resultado_prueba(resultado) puts "\n#{Color::CYAN}🧪 Resultado de prueba del trigger#{Color::RESET}" puts "#{Color::DIM}#{'-' * 60}#{Color::RESET}" if resultado[:exito] puts " #{Color::GREEN}✓ Trigger probado exitosamente#{Color::RESET}" puts " #{Color::DIM}ID:#{Color::RESET} #{resultado[:trigger]}" puts " #{Color::DIM}Modo:#{Color::RESET} #{resultado[:accion_simulada][:modo]}" puts " #{Color::DIM}Mensaje:#{Color::RESET} #{resultado[:accion_simulada][:mensaje]}" else puts " #{Color::RED}✗ Error probando trigger#{Color::RESET}" puts " #{Color::DIM}ID:#{Color::RESET} #{resultado[:trigger]}" puts " #{Color::DIM}Error:#{Color::RESET} #{resultado[:error]}" end puts "#{Color::DIM}#{'-' * 60}#{Color::RESET}" puts "#{Color::DIM}Nota: Esta fue una prueba en modo simulación (sin efectos reales)#{Color::RESET}" @logger.info("Prueba completada: #{resultado[:exito] ? 'éxito' : 'fallo'}") end # Muestra resultados de ejecución de triggers def mostrar_resultados_ejecucion(resultados) total = resultados[:total_ejecutados] exitosos = resultados[:exitosos] fallidos = resultados[:fallidos] puts "\n#{Color::CYAN}📊 Resultados de ejecución de triggers#{Color::RESET}" puts "#{Color::DIM}#{'-' * 60}#{Color::RESET}" puts " #{Color::GREEN}Ejecutados:#{Color::RESET} #{total}" puts " #{Color::GREEN}Exitosos:#{Color::RESET} #{exitosos}" puts " #{Color::GREEN}Fallidos:#{Color::RESET} #{fallidos}" if fallidos > 0 puts "\n#{Color::YELLOW}⚠ Triggers con errores:#{Color::RESET}" resultados[:detalles].each do |detalle| next if detalle[:exito] puts " #{Color::RED}✗ #{detalle[:trigger_id]}#{Color::RESET}" puts " #{Color::DIM}Evento:#{Color::RESET} #{detalle[:evento]}" puts " #{Color::DIM}Error:#{Color::RESET} #{detalle[:error]}" end end puts "#{Color::DIM}#{'-' * 60}#{Color::RESET}" if total == 0 @logger.advertencia("No se ejecutaron triggers (sistema deshabilitado)") puts "#{Color::YELLOW}ℹ No se ejecutaron triggers#{Color::RESET}" puts "#{Color::DIM}Usa --forzar para ejecutar de todos modos#{Color::RESET}" elsif fallidos == 0 @logger.exito("Ejecución completada: #{exitosos}/#{total} triggers exitosos") puts "#{Color::GREEN}✓ Ejecución completada sin errores#{Color::RESET}" else @logger.error("Ejecución completada con errores: #{fallidos}/#{total} fallidos") puts "#{Color::RED}✗ Ejecución completada con #{fallidos} error(es)#{Color::RESET}" end end end end