refactor(dron): Atomisidad - Módulo base compartido para drones

Principio "Menos es Más": código común centralizado en un solo lugar.

Cambios:
- Nuevo módulo Dron::Base con funcionalidad compartida:
  - logger: Logger compartido (evita crear múltiples instancias)
  - db_query: Ejecución de SQL con resultados
  - db_exec: Ejecución de SQL sin resultados
  - formato_duracion: Utilitario para formatear segundos
  - slice_safe: Slice seguro de strings
  - blank?: Verificación de strings vacíos/nulos

- Todos los módulos atómicos (ejecutor, vigilante, sanador, bitacora)
  ahora usan Base.logger, Base.db_query, Base.db_exec

Beneficios:
- Un solo lugar para corregir errores comunes
- Menos duplicación de código (~40% menos líneas)
- Consistencia en manejo de logs y DB
- Fácil extensión: nuevos drones heredan funcionalidad automática

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Ricardo Monla
2026-04-07 11:48:55 -03:00
co-authored by Claude Opus 4.6
parent 3543e62263
commit 6e0e04d1e1
5 changed files with 206 additions and 667 deletions
+65
View File
@@ -0,0 +1,65 @@
# frozen_string_literal: true
# Dron::Base — Módulo base para todos los drones atómicos
# ========================================================
# Proporciona funcionalidad común para evitar duplicación.
# Se usa llamando directamente: Base.logger, Base.db_query, etc.
#
# Uso:
# require_relative 'base'
# class Dron::Ejecutor
# class << self
# def accion
# Base.logger.info("...")
# Base.db_query("SELECT ...")
# end
# end
# end
require_relative '../../core/logger'
require_relative '../../db/core/bitacora_db'
module Dron
module Base
module_function
def logger
@@logger ||= ADN::Logger.new
end
def db_query(sql, params = [])
BitacorasDB::BitacoraDB.with_connection { |db| db.execute(sql, params).to_a }
rescue PG::Error => e
logger.error("💥 PG Error: #{e.message}")
raise
rescue StandardError => e
logger.error("💥 Error: #{e.message}")
raise
end
def db_exec(sql, params = [])
BitacorasDB::BitacoraDB.with_connection { |db| db.execute(sql, params) }
rescue PG::Error => e
logger.error("💥 PG Error: #{e.message}")
raise
rescue StandardError => e
logger.error("💥 Error: #{e.message}")
raise
end
def formato_duracion(segundos)
minutos = (segundos / 60).to_i
secs = (segundos % 60).to_i
minutos > 0 ? "#{minutos}min #{secs}s" : "#{secs}s"
end
def blank?(str)
str.nil? || str.to_s.strip.empty?
end
def slice_safe(str, max = 50)
return '' if str.nil?
str.to_s.length > max ? "#{str.to_s[0...max]}..." : str.to_s
end
end
end