# frozen_string_literal: true # Dron::Bitacora — Módulo atómico para registro en bitácora humana # # Responsabilidad única: Gestionar registro de eventos en bitácora require_relative 'base' module Dron class Bitacora class << self def iniciar(nota:, nodo_id: 1, modo: 'A') descripcion = "🛸 dron: #{nota}" Base.logger.info("📝 Bitácora: Iniciando evento - #{nota}") sql = "INSERT INTO bitacoras.events (nodo_id, descripcion, estado, modo, inicio) VALUES ($1, $2, $3, $4, $5) RETURNING id" resultado = Base.db_exec(sql, [nodo_id, descripcion, '⏳', modo, Time.now.strftime('%H:%M')]) evento_id = resultado.first['id'] Base.logger.info("📝 Evento creado: ##{evento_id}") evento_id rescue StandardError => e Base.logger.error("📝 Error creando evento: #{e.message}") nil end def finalizar(evento_id, exit_code:, nota: nil) evento = Base.db_query("SELECT * FROM bitacoras.events WHERE id = $1", [evento_id]).first return false unless evento estado_icono = exit_code == 0 ? '✅' : '❌' nota_original = evento['descripcion'].to_s.gsub('🛸 dron: ', '').split(' — ').first descripcion = "🛸 dron: #{nota_original} — #{estado_icono}#{nota ? " — #{nota}" : ''}" Base.logger.info("📝 Bitácora: Finalizando evento ##{evento_id} - #{estado_icono}") sql = "UPDATE bitacoras.events SET descripcion = $1, estado = $2, fin = $3, updated_at = NOW() WHERE id = $4" Base.db_exec(sql, [descripcion, estado_icono, Time.now.strftime('%H:%M'), evento_id]) true rescue StandardError => e Base.logger.error("📝 Error actualizando evento: #{e.message}") false end def auto(nota:, &bloque) evento_id = iniciar(nota: nota) inicio = Time.now resultado = nil exit_code = 0 begin resultado = yield rescue StandardError => e Base.logger.error("📝 Error en ejecución AUTO: #{e.message}") exit_code = 1 end duracion = (Time.now - inicio).round(2) finalizar(evento_id, exit_code: exit_code, nota: "#{duracion}s") if evento_id { evento_id: evento_id, exit_code: exit_code, resultado: resultado, duracion: duracion } end def vincular_flujo(evento_id, flujo_id) evento = Base.db_query("SELECT * FROM bitacoras.events WHERE id = $1", [evento_id]).first return false unless evento metadata_hash = (evento['metadata'] && JSON.parse(evento['metadata'])) rescue {} metadata_hash['flujo_id'] = flujo_id Base.db_exec("UPDATE bitacoras.events SET metadata = $1 WHERE id = $2", [metadata_hash.to_json, evento_id]) Base.logger.info("📝 Evento ##{evento_id} vinculado al flujo #{flujo_id}") true rescue StandardError => e Base.logger.error("📝 Error vinculando flujo: #{e.message}") false end end end end