Files
dtic-DIIAA/tools/orquestador/dashboard/orquestador.rb
T

420 lines
13 KiB
Ruby
Executable File

#!/usr/bin/env ruby
# frozen_string_literal: true
# tools/orquestador/dashboard/orquestador.rb
# ==========================================
# Script maestro para orquestar todas las herramientas del dashboard P2601
# Filosofía: "Menos es más" - orquestación de herramientas pequeñas y específicas
require 'fileutils'
class DashboardOrchestrator
VERSION = '1.0.0'
# Mapeo de comandos a herramientas
HERRAMIENTAS = {
'limpiar' => {
archivo: 'limpiar.rb',
descripcion: 'Limpiar hitos duplicados del dashboard',
uso: './orquestador.rb limpiar [--dashboard RUTA]'
},
'agregar-hitos' => {
archivo: 'agregar_hitos.rb',
descripcion: 'Agregar hitos al dashboard',
uso: './orquestador.rb agregar-hitos [fase] [modo] [--dashboard RUTA]'
},
'actualizar-estados' => {
archivo: 'actualizar_estados.rb',
descripcion: 'Actualizar estados de hitos',
uso: './orquestador.rb actualizar-estados [comando] [argumentos...]'
},
'verificar' => {
archivo: 'verificar.rb',
descripcion: 'Verificar estructura del dashboard',
uso: './orquestador.rb verificar [comando] [--dashboard RUTA]'
},
'vista-previa' => {
archivo: 'vista_previa.rb',
descripcion: 'Vista previa del dashboard',
uso: './orquestador.rb vista-previa [modo] [--dashboard RUTA]'
},
'sincronizar' => {
archivo: 'sincronizar.rb',
descripcion: 'Sincronizar dashboard local con producción',
uso: './orquestador.rb sincronizar [--dry-run] [--no-backup]'
},
'agregar-hitos-db' => {
archivo: 'agregar_hitos_db.rb',
descripcion: 'Agregar hitos a la base de datos PostgreSQL',
uso: './orquestador.rb agregar-hitos-db [comando]'
}
}.freeze
# Flujos de trabajo predefinidos
FLUJOS_TRABAJO = {
'inicializar' => {
descripcion: 'Inicializar dashboard limpio con hitos de fase 5',
pasos: [
{ herramienta: 'limpiar', args: [] },
{ herramienta: 'agregar-hitos', args: ['fase5', 'append'] },
{ herramienta: 'verificar', args: ['verificar'] }
]
},
'seguimiento-diario' => {
descripcion: 'Flujo para seguimiento diario del proyecto',
pasos: [
{ herramienta: 'vista-previa', args: ['rapido'] },
{ herramienta: 'actualizar-estados', args: ['listar'] }
]
},
'revision-semanal' => {
descripcion: 'Flujo para revisión semanal completa',
pasos: [
{ herramienta: 'limpiar', args: [] },
{ herramienta: 'verificar', args: ['verificar'] },
{ herramienta: 'vista-previa', args: ['resumen'] },
{ herramienta: 'actualizar-estados', args: ['listar'] }
]
},
'agregar-fase5' => {
descripcion: 'Agregar hitos de fase 5 y verificar',
pasos: [
{ herramienta: 'agregar-hitos', args: ['fase5', 'append'] },
{ herramienta: 'verificar', args: ['analizar'] }
]
},
'desplegar-produccion' => {
descripcion: 'Sincronizar cambios a producción y verificar',
pasos: [
{ herramienta: 'sincronizar', args: [] },
{ herramienta: 'verificar', args: ['verificar'] },
{ herramienta: 'vista-previa', args: ['rapido'] }
]
},
'ciclo-completo' => {
descripcion: 'Ciclo completo: limpiar, agregar hitos, sincronizar',
pasos: [
{ herramienta: 'limpiar', args: [] },
{ herramienta: 'agregar-hitos', args: ['fase5', 'append'] },
{ herramienta: 'sincronizar', args: [] },
{ herramienta: 'verificar', args: ['verificar'] }
]
},
'agregar-hitos-produccion' => {
descripcion: 'Agregar hitos a la base de datos de producción',
pasos: [
{ herramienta: 'agregar-hitos-db', args: ['agregar'] },
{ herramienta: 'agregar-hitos-db', args: ['estado'] }
]
},
'dashboard-completo' => {
descripcion: 'Flujo completo para dashboard en producción',
pasos: [
{ herramienta: 'agregar-hitos-db', args: ['agregar'] },
{ herramienta: 'vista-previa', args: ['rapido'] },
{ herramienta: 'verificar', args: ['verificar'] }
]
}
}.freeze
def initialize
@directorio_herramientas = File.dirname(__FILE__)
end
def ejecutar_herramienta(nombre_herramienta, args = [])
puts "🛠️ EJECUTANDO: #{nombre_herramienta}"
puts "=" * 60
herramienta = HERRAMIENTAS[nombre_herramienta]
unless herramienta
puts "❌ Error: Herramienta '#{nombre_herramienta}' no encontrada"
puts " Herramientas disponibles: #{HERRAMIENTAS.keys.join(', ')}"
return false
end
ruta_herramienta = File.join(@directorio_herramientas, herramienta[:archivo])
unless File.exist?(ruta_herramienta)
puts "❌ Error: Archivo de herramienta no encontrado: #{ruta_herramienta}"
return false
end
# Construir comando
comando = "ruby #{ruta_herramienta} #{args.join(' ')}"
puts "📝 Comando: #{comando}"
puts "-" * 60
# Ejecutar herramienta
system(comando)
exit_status = $?.exitstatus
puts "-" * 60
if exit_status == 0
puts "✅ Herramienta ejecutada exitosamente"
true
else
puts "❌ Herramienta falló con código #{exit_status}"
false
end
end
def ejecutar_flujo_trabajo(nombre_flujo)
puts "🔄 EJECUTANDO FLUJO DE TRABAJO: #{nombre_flujo}"
puts "=" * 60
flujo = FLUJOS_TRABAJO[nombre_flujo]
unless flujo
puts "❌ Error: Flujo de trabajo '#{nombre_flujo}' no encontrado"
puts " Flujos disponibles: #{FLUJOS_TRABAJO.keys.join(', ')}"
return false
end
puts "📋 Descripción: #{flujo[:descripcion]}"
puts "📊 Pasos: #{flujo[:pasos].size}"
puts
resultados = []
flujo[:pasos].each_with_index do |paso, index|
puts "📝 PASO #{index + 1}/#{flujo[:pasos].size}: #{paso[:herramienta]}"
puts " Argumentos: #{paso[:args].join(' ')}" if paso[:args].any?
puts
exito = ejecutar_herramienta(paso[:herramienta], paso[:args])
resultados << { paso: paso[:herramienta], exito: exito }
unless exito
puts "⚠️ Flujo interrumpido por fallo en paso #{index + 1}"
break
end
puts "\n" unless index == flujo[:pasos].size - 1
end
# Mostrar resumen
mostrar_resumen_flujo(resultados, nombre_flujo)
resultados.all? { |r| r[:exito] }
end
def listar_herramientas
puts "🛠️ HERRAMIENTAS DISPONIBLES"
puts "=" * 60
HERRAMIENTAS.each do |nombre, info|
puts "• #{nombre}"
puts " 📝 #{info[:descripcion]}"
puts " 📋 Uso: #{info[:uso]}"
puts
end
true
end
def listar_flujos
puts "🔄 FLUJOS DE TRABAJO PREDEFINIDOS"
puts "=" * 60
FLUJOS_TRABAJO.each do |nombre, flujo|
puts "• #{nombre}"
puts " 📝 #{flujo[:descripcion]}"
puts " 📊 Pasos: #{flujo[:pasos].size}"
flujo[:pasos].each_with_index do |paso, i|
puts " #{i + 1}. #{paso[:herramienta]} #{paso[:args].join(' ')}"
end
puts
end
true
end
def mostrar_estado_sistema
puts "📊 ESTADO DEL SISTEMA DE ORQUESTACIÓN"
puts "=" * 60
puts "🏗️ INFORMACIÓN GENERAL:"
puts " • Versión: #{VERSION}"
puts " • Directorio herramientas: #{@directorio_herramientas}"
puts " • Herramientas disponibles: #{HERRAMIENTAS.size}"
puts "📊 Flujos predefinidos: #{FLUJOS_TRABAJO.size}"
puts "\n🎯 DASHBOARDS DISPONIBLES:"
puts " • Producción: https://ns8.frlr.utn.edu.ar/bitacoras/p2601"
puts " • Estático: https://ns8.frlr.utn.edu.ar/P2601/"
puts "\n🔍 VERIFICACIÓN DE HERRAMIENTAS:"
herramientas_ok = 0
HERRAMIENTAS.each do |nombre, info|
ruta = File.join(@directorio_herramientas, info[:archivo])
existe = File.exist?(ruta)
ejecutable = File.executable?(ruta)
emoji = existe && ejecutable ? '✅' : '❌'
puts " #{emoji} #{nombre}: #{info[:archivo]}"
puts " - Existe: #{existe ? 'Sí' : 'No'}"
puts " - Ejecutable: #{ejecutable ? 'Sí' : 'No'}"
puts " - Tipo: #{nombre.include?('db') ? 'Base de datos' : 'Archivo'}"
herramientas_ok += 1 if existe && ejecutable
end
puts "\n📈 RESUMEN:"
puts " • Herramientas listas: #{herramientas_ok}/#{HERRAMIENTAS.size}"
if herramientas_ok == HERRAMIENTAS.size
puts " ✅ Todas las herramientas están listas para usar"
else
puts " ⚠️ Algunas herramientas requieren atención"
end
true
end
private
def mostrar_resumen_flujo(resultados, nombre_flujo)
puts "📊 RESUMEN DEL FLUJO: #{nombre_flujo}"
puts "=" * 60
exitosos = resultados.count { |r| r[:exito] }
total = resultados.size
resultados.each_with_index do |resultado, index|
emoji = resultado[:exito] ? '✅' : '❌'
puts " #{emoji} Paso #{index + 1}: #{resultado[:paso]}"
end
puts "\n📈 ESTADÍSTICAS:"
puts " • Pasos ejecutados: #{total}"
puts " • Pasos exitosos: #{exitosos}"
puts " • Porcentaje de éxito: #{(exitosos * 100.0 / total).round(1)}%"
if exitosos == total
puts "\n🎉 ¡Flujo de trabajo completado exitosamente!"
else
puts "\n⚠️ Flujo de trabajo completado con errores"
end
end
end
# Interfaz de línea de comandos
if __FILE__ == $0
begin
orquestador = DashboardOrchestrator.new
# Parsear argumentos
comando = ARGV[0] || 'help'
case comando
when 'herramienta', 'tool'
if ARGV.length < 2
puts "❌ Error: Se requiere nombre de herramienta"
puts " Uso: #{$0} herramienta NOMBRE_HERRAMIENTA [argumentos...]"
exit 1
end
nombre_herramienta = ARGV[1]
args = ARGV[2..-1] || []
success = orquestador.ejecutar_herramienta(nombre_herramienta, args)
when 'flujo', 'workflow'
if ARGV.length < 2
puts "❌ Error: Se requiere nombre de flujo"
puts " Uso: #{$0} flujo NOMBRE_FLUJO"
exit 1
end
nombre_flujo = ARGV[1]
success = orquestador.ejecutar_flujo_trabajo(nombre_flujo)
when 'listar-herramientas', 'list-tools'
success = orquestador.listar_herramientas
when 'listar-flujos', 'list-workflows'
success = orquestador.listar_flujos
when 'estado', 'status'
success = orquestador.mostrar_estado_sistema
when 'version', '--version', '-v'
puts "Dashboard Orchestrator v#{DashboardOrchestrator::VERSION}"
success = true
when 'help', '--help', '-h'
puts "📖 ORQUESTADOR DE HERRAMIENTAS - DASHBOARD P2601"
puts "=" * 60
puts
puts "DESCRIPCIÓN:"
puts " Script maestro para orquestar herramientas pequeñas y específicas"
puts " del dashboard P2601, siguiendo la filosofía 'Menos es más'."
puts
puts "USO:"
puts " #{$0} [comando] [argumentos...]"
puts
puts "COMANDOS PRINCIPALES:"
puts " herramienta, tool NOMBRE [args...] Ejecutar una herramienta específica"
puts " flujo, workflow NOMBRE Ejecutar flujo de trabajo predefinido"
puts " listar-herramientas, list-tools Listar todas las herramientas"
puts " listar-flujos, list-workflows Listar flujos de trabajo"
puts " estado, status Mostrar estado del sistema"
puts " version, -v Mostrar versión"
puts " help, -h Mostrar esta ayuda"
puts
puts "HERRAMIENTAS DISPONIBLES:"
DashboardOrchestrator::HERRAMIENTAS.each do |nombre, info|
puts " • #{nombre}: #{info[:descripcion]}"
end
puts
puts "FLUJOS PREDEFINIDOS:"
DashboardOrchestrator::FLUJOS_TRABAJO.each do |nombre, flujo|
puts " • #{nombre}: #{flujo[:descripcion]}"
end
puts
puts "EJEMPLOS:"
puts " #{$0} herramienta limpiar"
puts " #{$0} herramienta agregar-hitos fase5 append"
puts " #{$0} flujo inicializar"
puts " #{$0} flujo seguimiento-diario"
puts " #{$0} estado"
puts
puts "📅 #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
puts "=" * 60
success = true
else
puts "❌ Comando '#{comando}' no reconocido"
puts " Use '#{$0} help' para ver la ayuda"
success = false
end
# Verificar si es un comando de base de datos
if comando == 'herramienta' && nombre_herramienta == 'agregar-hitos-db'
puts "\n⚠️ NOTA: Esta herramienta modifica la base de datos PostgreSQL"
puts " • Asegúrese de que el contenedor esté ejecutándose"
puts " • Los cambios se reflejan en: https://ns8.frlr.utn.edu.ar/bitacoras/p2601"
end
if success
puts "\n🚀 RECOMENDACIONES:"
puts " 1. Usar 'flujo inicializar' para dashboard limpio"
puts " 1. Usar 'flujo agregar-hitos-produccion' para hitos en base de datos"
puts " 2. Usar 'flujo seguimiento-diario' para monitoreo regular"
puts " 3. Verificar dashboard en: https://ns8.frlr.utn.edu.ar/bitacoras/p2601"
puts " 4. Dashboard estático en: https://ns8.frlr.utn.edu.ar/P2601/"
puts
puts "📅 #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
puts "=" * 60
else
exit 1
end
rescue => e
puts "❌ Error: #{e.message}"
puts e.backtrace if ENV['DEBUG']
exit 1
end
end