Files
dtic-DIIAA/tools/adn/cli/db/evento.rb
T

261 lines
9.1 KiB
Ruby

module ADN
module SubcomandoDBEvento
# Comando: evento:crear [OPCIONES] - Crear nueva entrada cronológica
def comando_evento_crear(args)
opts = {
inicio: nil,
descripcion: nil,
fin: nil,
estado: nil,
modo: nil,
es_ia: false,
nodo: nil,
tema: nil
}
parser = OptionParser.new do |opt|
opt.banner = "Uso: adn db evento:crear [OPCIONES]"
opt.on("--inicio HH:MM", "Hora de inicio (requerido)") do |i|
opts[:inicio] = i
end
opt.on("--descripcion TEXTO", "Descripción de la actividad (requerido)") do |d|
opts[:descripcion] = d
end
opt.on("--fin HH:MM", "Hora de fin (opcional)") do |f|
opts[:fin] = f
end
opt.on("--estado ESTADO", "Estado (⏳, ✅, ❌, ⚠️, ⏸️)") do |e|
opts[:estado] = e
end
opt.on("--modo MODO", "Modo (P=Presencial, R=Remoto)") do |m|
opts[:modo] = m
end
opt.on("--nodo NOMBRE", "Nombre del nodo (servidor/VM)") do |n|
opts[:nodo] = n
end
opt.on("--ia", "Marcar como generado por IA") do
opts[:es_ia] = true
end
opt.on("-h", "--help", "Mostrar ayuda") do
puts opt
exit
end
end
begin
parser.parse!(args)
rescue OptionParser::InvalidOption => e
puts "#{Color::RED}✗ Error: #{e.message}#{Color::RESET}"
puts parser
exit 1
end
# Validaciones básicas
unless opts[:inicio] && opts[:descripcion]
puts "#{Color::RED}✗ Error: --inicio y --descripcion son requeridos#{Color::RESET}"
puts parser
exit 1
end
puts "#{Color::CYAN}📝 Creando nueva entrada...#{Color::RESET}"
BitacorasDB::BitacoraDB.with_connection do |db|
# Buscar nodo por nombre si se especificó
nodo_id = nil
if opts[:nodo]
nodo = db.find_nodo_by_nombre(opts[:nodo])
if nodo
nodo_id = nodo['id']
puts " #{Color::DIM}Nodo encontrado: #{opts[:nodo]} (ID: #{nodo_id})#{Color::RESET}"
else
puts "#{Color::YELLOW}⚠ Nodo '#{opts[:nodo]}' no encontrado#{Color::RESET}"
puts " Creando entrada sin nodo asociado"
end
end
# Buscar bitácora para hoy (o crearla)
fecha_hoy = Date.today.to_s
bitacora = db.find_bitacora_by_fecha(fecha_hoy)
if bitacora.nil?
puts " #{Color::DIM}Creando bitácora para hoy...#{Color::RESET}"
bitacora = db.create_bitacora(fecha: fecha_hoy)
end
bitacora_id = bitacora['id']
# Crear la entrada
entrada = db.create_entrada(
inicio: opts[:inicio],
descripcion: opts[:descripcion],
fin: opts[:fin],
estado: opts[:estado],
modo: opts[:modo],
es_ia: opts[:es_ia],
bitacora_id: bitacora_id,
nodo_id: nodo_id,
tema_id: nil # Por ahora sin tema
)
puts "#{Color::GREEN}✅ Entrada creada exitosamente#{Color::RESET}"
puts ""
puts " #{Color::BOLD}ID:#{Color::RESET} #{entrada['id']}"
puts " #{Color::BOLD}Inicio:#{Color::RESET} #{entrada['inicio']}"
puts " #{Color::BOLD}Fin:#{Color::RESET} #{entrada['fin'] || '(sin fin)'}"
puts " #{Color::BOLD}Descripción:#{Color::RESET} #{entrada['descripcion']}"
puts " #{Color::BOLD}Estado:#{Color::RESET} #{entrada['estado']}"
puts " #{Color::BOLD}Modo:#{Color::RESET} #{entrada['modo'] == 'P' ? 'Presencial' : 'Remoto'}"
puts " #{Color::BOLD}IA:#{Color::RESET} #{entrada['es_ia'] ? 'Sí' : 'No'}"
puts " #{Color::BOLD}Bitácora:#{Color::RESET} #{fecha_hoy} (ID: #{bitacora_id})"
end
end
# Comando: evento:actualizar <ID> [OPCIONES] - Actualizar una entrada existente
def comando_evento_actualizar(args)
if args.length < 1 || args[0].start_with?('-')
puts "#{Color::YELLOW}Uso: adn db evento:actualizar <ID> [OPCIONES]#{Color::RESET}"
puts "Opciones soportadas: --fin \"HH:MM\", --inicio \"HH:MM\", --estado \"\", --descripcion \"Texto\""
return
end
id_evento = args.shift.to_i
opts = {}
parser = OptionParser.new do |opt|
opt.banner = "Opciones:"
opt.on("--inicio HH:MM", "Nueva hora de inicio") { |i| opts[:inicio] = i }
opt.on("--fin HH:MM", "Nueva hora de fin") { |f| opts[:fin] = f }
opt.on("--descripcion TEXTO", "Nueva descripción") { |d| opts[:descripcion] = d }
opt.on("--estado ESTADO", "Nuevo estado (⏳, ✅, ❌, ⚠️, ⏸️)") { |e| opts[:estado] = e }
opt.on("-h", "--help", "Mostrar ayuda") do
puts opt
exit
end
end
begin
parser.parse!(args)
rescue OptionParser::InvalidOption => e
puts "#{Color::RED}✗ Error: #{e.message}#{Color::RESET}"
exit 1
end
if opts.empty?
puts "#{Color::YELLOW}⚠ No se especificó nada para actualizar. Use --fin, --inicio, --descripcion o --estado#{Color::RESET}"
return
end
puts "#{Color::CYAN}🔄 Actualizando evento #{id_evento}...#{Color::RESET}"
BitacorasDB::BitacoraDB.with_connection do |db|
begin
res = db.update_entrada(id_evento, opts)
if res
puts "#{Color::GREEN}✅ Evento #{id_evento} actualizado exitosamente.#{Color::RESET}"
puts " #{Color::BOLD}Inicio:#{Color::RESET} #{res['inicio']}"
puts " #{Color::BOLD}Fin:#{Color::RESET} #{res['fin'] || '(sin fin)'}"
else
puts "#{Color::YELLOW}⚠ No se pudo actualizar el evento. ¿Existe el ID #{id_evento}?#{Color::RESET}"
end
rescue => e
puts "#{Color::RED}✗ Error: #{e.message}#{Color::RESET}"
end
end
end
# Comando: evento:listar [OPCIONES] - Listar entradas con filtros
def comando_evento_listar(args)
opts = { limit: 20, offset: 0, nodo: nil, estado: nil, buscar: nil, desde: nil, hasta: nil }
parser = OptionParser.new do |opt|
opt.banner = "Uso: adn db evento:listar [OPCIONES]"
opt.on("--limit N", Integer, "Número máximo de resultados (default: 20)") do |n|
opts[:limit] = n
end
opt.on("--offset N", Integer, "Desplazamiento para paginación (default: 0)") do |n|
opts[:offset] = n
end
opt.on("--nodo NOMBRE", "Filtrar por nombre de nodo") do |n|
opts[:nodo] = n
end
opt.on("--estado ESTADO", "Filtrar por estado (⏳, ✅, ❌, ⚠️, ⏸️)") do |e|
opts[:estado] = e
end
opt.on("--buscar TEXTO", "Buscar texto en descripción") do |b|
opts[:buscar] = b
end
opt.on("--desde FECHA", "Filtrar desde fecha (YYYY-MM-DD)") do |d|
opts[:desde] = d
end
opt.on("--hasta FECHA", "Filtrar hasta fecha (YYYY-MM-DD)") do |h|
opts[:hasta] = h
end
opt.on("-h", "--help", "Mostrar ayuda") do
puts opt
exit
end
end
begin
parser.parse!(args)
rescue OptionParser::InvalidOption => e
puts "#{Color::RED}✗ Error: #{e.message}#{Color::RESET}"
puts parser
exit 1
end
puts "#{Color::CYAN}📋 Listando entradas...#{Color::RESET}"
BitacorasDB::BitacoraDB.with_connection do |db|
# Obtener ID de nodo si se especificó nombre
nodo_id = nil
if opts[:nodo]
nodo = db.find_nodo_by_nombre(opts[:nodo])
if nodo
nodo_id = nodo['id']
puts " #{Color::DIM}Filtrando por nodo: #{opts[:nodo]} (ID: #{nodo_id})#{Color::RESET}"
else
puts "#{Color::YELLOW}⚠ Nodo '#{opts[:nodo]}' no encontrado#{Color::RESET}"
end
end
entradas = db.list_entradas(
nodo_id: nodo_id,
estado: opts[:estado],
buscar: opts[:buscar],
desde: opts[:desde],
hasta: opts[:hasta],
limit: opts[:limit],
offset: opts[:offset]
)
if entradas.empty?
puts "#{Color::YELLOW}⚠ No se encontraron entradas#{Color::RESET}"
return
end
puts ""
puts "#{Color::BOLD}#{"ID".ljust(5)} #{"Inicio".ljust(8)} #{"Fin".ljust(8)} #{"Nodo".ljust(15)} #{"Estado".ljust(3)} #{"Descripción".ljust(40)}#{Color::RESET}"
puts "#{"─" * 5} #{"─" * 8} #{"─" * 8} #{"─" * 15} #{"─" * 3} #{"─" * 40}"
entradas.each do |e|
id = e['id'].to_s
inicio = e['inicio'][0..7] # HH:MM:SS -> HH:MM
fin = e['fin'] ? e['fin'][0..7] : '--:--'
nodo = e['nodo_nombre'] || '(sin nodo)'
nodo = nodo[0..13] + '...' if nodo.length > 15
estado = e['estado']
desc = e['descripcion']
desc = desc[0..37] + '...' if desc.length > 40
puts "#{id.ljust(5)} #{inicio.ljust(8)} #{fin.ljust(8)} #{nodo.ljust(15)} #{estado.ljust(3)} #{desc.ljust(40)}"
end
puts ""
puts "Total: #{entradas.length} entradas"
end
end
end
end