322 lines
12 KiB
Ruby
322 lines
12 KiB
Ruby
# 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'
|
||
require_relative '../core/colores'
|
||
require_relative '../core/help_formatter'
|
||
|
||
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
|
||
# Handle help flags
|
||
if @args.empty? || @args[0] == 'help' || @args[0] == '-h' || @args[0] == '--help'
|
||
mostrar_ayuda
|
||
return
|
||
end
|
||
|
||
parser = crear_parser
|
||
|
||
begin
|
||
parser.parse!(@args)
|
||
rescue OptionParser::InvalidOption => e
|
||
@logger.error("Opción inválida: #{e.message}")
|
||
puts parser
|
||
exit 1
|
||
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
|
||
ayuda = ADN::HelpFormatter.generar_help(
|
||
titulo: "Gestión de Triggers ADN",
|
||
descripcion: "Gestiona el sistema de triggers para sincronización automática del ADN",
|
||
uso: "./adn/tools/run triggers [OPCIONES]",
|
||
opciones: [
|
||
{ names: ['--test [TRIGGER_ID]'], desc: "Probar un trigger específico (modo simulación)" },
|
||
{ names: ['--forzar'], desc: "Ejecutar triggers incluso si sistema deshabilitado" },
|
||
{ names: ['--listar'], desc: "Listar todos los triggers configurados" },
|
||
{ names: ['--registrar'], desc: "Registrar triggers en el bus de eventos" },
|
||
{ names: ['--limpiar'], desc: "Limpiar todos los triggers registrados" },
|
||
{ names: ['-h', '--help'], desc: "Mostrar esta ayuda" }
|
||
],
|
||
ejemplos: [
|
||
{ cmd: "./adn/tools/run triggers --listar", desc: "Listar todos los triggers configurados" },
|
||
{ cmd: "./adn/tools/run triggers --registrar", desc: "Registrar triggers en el bus de eventos" },
|
||
{ cmd: "./adn/tools/run triggers --test bitacoras_0", desc: "Probar trigger bitacoras_0 (modo simulación)" },
|
||
{ cmd: "./adn/tools/run triggers --forzar", desc: "Forzar ejecución de triggers" },
|
||
{ cmd: "./adn/tools/run triggers --limpiar", desc: "Limpiar todos los triggers registrados" }
|
||
]
|
||
)
|
||
|
||
puts ayuda
|
||
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 "📚 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
|