diff --git a/tools/adn/comando/backup.rb b/tools/adn/comando/backup.rb index e9209e99..72da4ff5 100644 --- a/tools/adn/comando/backup.rb +++ b/tools/adn/comando/backup.rb @@ -185,7 +185,7 @@ module ADN end def registrar_inicio_bitacora(nodo, datos) - require_relative '../../bitacoras-db/core/bitacora_db' + require_relative '../db/core/bitacora_db' BitacorasDB::BitacoraDB.with_connection do |db| # Asegurar bitácora @@ -216,7 +216,7 @@ module ADN def registrar_task_id_bitacora(nodo, task_id) return unless @backup_entrada_id - require_relative '../../bitacoras-db/core/bitacora_db' + require_relative '../db/core/bitacora_db' BitacorasDB::BitacoraDB.with_connection do |db| db.update_entrada(@backup_entrada_id, { @@ -230,8 +230,8 @@ module ADN def registrar_fin_bitacora(nodo, exito, task_id = nil) return unless @backup_entrada_id - require_relative '../../bitacoras-db/core/bitacora_db' - require_relative '../../bitacoras-db/exporters/md_exporter' + require_relative '../db/core/bitacora_db' + require_relative '../db/exporters/md_exporter' hora_fin = Time.now.strftime('%H:%M') estado = exito ? '✅' : '⚠️' diff --git a/tools/adn/comando/cierre.rb b/tools/adn/comando/cierre.rb index b4944e65..8171c3f2 100644 --- a/tools/adn/comando/cierre.rb +++ b/tools/adn/comando/cierre.rb @@ -5,7 +5,7 @@ require 'date' require 'time' -require_relative '../../bitacoras-db/core/bitacora_db' +require_relative '../db/core/bitacora_db' module ADN class SubcomandoCierre diff --git a/tools/adn/comando/db.rb b/tools/adn/comando/db.rb index 83de6984..1244485c 100644 --- a/tools/adn/comando/db.rb +++ b/tools/adn/comando/db.rb @@ -26,13 +26,13 @@ require 'time' # Cargar módulo BitacorasDB begin - require_relative '../../bitacoras-db/core/bitacora_db' - require_relative '../../bitacoras-db/importers/md_importer' - require_relative '../../bitacoras-db/exporters/md_exporter' + require_relative '../db/core/bitacora_db' + require_relative '../db/importers/md_importer' + require_relative '../db/exporters/md_exporter' rescue LoadError => e # Fallback para desarrollo puts "⚠ Advertencia: No se pudo cargar BitacoraDB o MDImporter: #{e.message}" - puts " Asegúrate de que los archivos en tools/bitacoras-db/ existen" + puts " Asegúrate de que los archivos en tools/adn/db/ existen" end module ADN diff --git a/tools/adn/comando/inicio.rb b/tools/adn/comando/inicio.rb index a3abb35b..2ab580d4 100644 --- a/tools/adn/comando/inicio.rb +++ b/tools/adn/comando/inicio.rb @@ -5,7 +5,7 @@ require 'date' require 'time' -require_relative '../../bitacoras-db/core/bitacora_db' +require_relative '../db/core/bitacora_db' module ADN class SubcomandoInicio diff --git a/tools/config/database.yml b/tools/adn/config/database.yml similarity index 100% rename from tools/config/database.yml rename to tools/adn/config/database.yml diff --git a/tools/bitacoras-db/cli/exportar_todo.rb b/tools/adn/db/cli/exportar_todo.rb similarity index 94% rename from tools/bitacoras-db/cli/exportar_todo.rb rename to tools/adn/db/cli/exportar_todo.rb index d31100b4..ae41a3c3 100644 --- a/tools/bitacoras-db/cli/exportar_todo.rb +++ b/tools/adn/db/cli/exportar_todo.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -# tools/bitacoras-db/cli/exportar_todo.rb +# tools/adn/db/cli/exportar_todo.rb # ========================================== # Exporta TODAS las bitácoras de la DB a archivos .md -# Uso: ruby tools/bitacoras-db/cli/exportar_todo.rb [--dir DIRECTORIO] +# Uso: ruby tools/adn/db/cli/exportar_todo.rb [--dir DIRECTORIO] # — o vía enjambre — # ./tools/adn/run db exportar:md --todo diff --git a/tools/bitacoras-db/cli/verificar_migracion.rb b/tools/adn/db/cli/verificar_migracion.rb similarity index 97% rename from tools/bitacoras-db/cli/verificar_migracion.rb rename to tools/adn/db/cli/verificar_migracion.rb index eabd6725..ef8f8587 100644 --- a/tools/bitacoras-db/cli/verificar_migracion.rb +++ b/tools/adn/db/cli/verificar_migracion.rb @@ -1,12 +1,12 @@ # frozen_string_literal: true -# tools/bitacoras-db/cli/verificar_migracion.rb +# tools/adn/db/cli/verificar_migracion.rb # ================================================ # Verifica que todas las bitácoras MD existentes estén correctamente # migradas en la base de datos. Reporta faltantes y discrepancias. # # Uso: -# ruby tools/bitacoras-db/cli/verificar_migracion.rb +# ruby tools/adn/db/cli/verificar_migracion.rb # — o vía enjambre — # ./tools/adn/run db verificar diff --git a/tools/bitacoras-db/core/bitacora_db.rb b/tools/adn/db/core/bitacora_db.rb similarity index 99% rename from tools/bitacoras-db/core/bitacora_db.rb rename to tools/adn/db/core/bitacora_db.rb index a63ca0d8..795bc8a2 100644 --- a/tools/bitacoras-db/core/bitacora_db.rb +++ b/tools/adn/db/core/bitacora_db.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# tools/bitacoras-db/core/bitacora_db.rb — Clase principal para conexión a PostgreSQL +# tools/adn/db/core/bitacora_db.rb — Clase principal para conexión a PostgreSQL # ================================================================================ # Esta clase proporciona una interfaz Ruby para interactuar con la base de datos # dtic-BITACORAs. Maneja conexiones, operaciones CRUD y validaciones para las diff --git a/tools/bitacoras-db/core/buscador_bd.rb b/tools/adn/db/core/buscador_bd.rb similarity index 99% rename from tools/bitacoras-db/core/buscador_bd.rb rename to tools/adn/db/core/buscador_bd.rb index 3836bbe6..56137c76 100644 --- a/tools/bitacoras-db/core/buscador_bd.rb +++ b/tools/adn/db/core/buscador_bd.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# tools/bitacoras-db/core/buscador_bd.rb — Sistema de búsqueda y filtrado para dtic-BITACORAs +# tools/adn/db/core/buscador_bd.rb — Sistema de búsqueda y filtrado para dtic-BITACORAs # ================================================================================ # Esta clase proporciona capacidades avanzadas de búsqueda y filtrado para la # base de datos dtic-BITACORAs. Implementa: diff --git a/tools/bitacoras-db/core/buscador_bd_simple.rb b/tools/adn/db/core/buscador_bd_simple.rb similarity index 99% rename from tools/bitacoras-db/core/buscador_bd_simple.rb rename to tools/adn/db/core/buscador_bd_simple.rb index 3581c108..2f767b0f 100644 --- a/tools/bitacoras-db/core/buscador_bd_simple.rb +++ b/tools/adn/db/core/buscador_bd_simple.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# tools/bitacoras-db/core/buscador_bd_simple.rb — Versión simplificada del sistema de búsqueda +# tools/adn/db/core/buscador_bd_simple.rb — Versión simplificada del sistema de búsqueda # ================================================================================ # Versión simplificada y funcional del sistema de búsqueda para dtic-BITACORAs # Esta versión evita problemas complejos de parámetros y se enfoca en funcionalidad básica diff --git a/tools/bitacoras-db/exporters/md_exporter.rb b/tools/adn/db/exporters/md_exporter.rb similarity index 100% rename from tools/bitacoras-db/exporters/md_exporter.rb rename to tools/adn/db/exporters/md_exporter.rb diff --git a/tools/bitacoras-db/importers/md_importer.rb b/tools/adn/db/importers/md_importer.rb similarity index 99% rename from tools/bitacoras-db/importers/md_importer.rb rename to tools/adn/db/importers/md_importer.rb index 4e73af0a..2e209ef6 100644 --- a/tools/bitacoras-db/importers/md_importer.rb +++ b/tools/adn/db/importers/md_importer.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# tools/bitacoras-db/importers/md_importer.rb — Importador de bitácoras .md a PostgreSQL +# tools/adn/db/importers/md_importer.rb — Importador de bitácoras .md a PostgreSQL # ================================================================================ # Esta clase convierte bitácoras en formato Markdown al esquema de base de datos # dtic-BITACORAs. Procesa la estructura jerárquica: diff --git a/tools/analizar_dashboard_p2601.rb b/tools/analizar_dashboard_p2601.rb index 0e40ac20..eb7fcebe 100644 --- a/tools/analizar_dashboard_p2601.rb +++ b/tools/analizar_dashboard_p2601.rb @@ -480,7 +480,7 @@ class AnalizadorDashboardP2601 # Verificar herramientas existentes herramientas_adn = [ - { nombre: "Sistema de búsqueda", archivo: "buscador_bd_simple.rb", estado: verificar_herramienta("bitacoras-db/core/buscador_bd_simple.rb") }, + { nombre: "Sistema de búsqueda", archivo: "buscador_bd_simple.rb", estado: verificar_herramienta("adn/db/core/buscador_bd_simple.rb") }, { nombre: "Seguimiento de plan", archivo: "subcomando_plan.rb", estado: verificar_herramienta("adn/subcomando_plan.rb") }, { nombre: "Operaciones BD", archivo: "subcomando_db.rb", estado: verificar_herramienta("adn/subcomando_db.rb") }, { nombre: "Sistema de triggers", archivo: "subcomando_triggers.rb", estado: verificar_herramienta("adn/subcomando_triggers.rb") }, diff --git a/tools/bitacoras-db/importers/md_importer.rb.bak b/tools/bitacoras-db/importers/md_importer.rb.bak deleted file mode 100644 index 98a6fe08..00000000 --- a/tools/bitacoras-db/importers/md_importer.rb.bak +++ /dev/null @@ -1,558 +0,0 @@ -# frozen_string_literal: true - -# tools/bitacoras-db/importers/md_importer.rb — Importador de bitácoras .md a PostgreSQL -# ================================================================================ -# Esta clase convierte bitácoras en formato Markdown al esquema de base de datos -# dtic-BITACORAs. Procesa la estructura jerárquica: -# Archivo .md → Bitácora → Nodos → Temas → Entradas (I-F-D-E) -# -# Formato de entrada (.md): -# # Bitácora 2026-02-28 -# ## Control de Gestión -# ### 📝 Resumen de Actividades -# | NODO | RESUMEN INTEGRAL | -# | :--- | :--- | -# | srv-ns8 | Resumen del día... | -# -# ## 📂 Actividades Detalladas -# ### srv-ns8 -# #### ✅ - SEC01 - Refactorización ns8-candados -# | I | F | Descripción | E | -# | :--- | :--- | :--- | :--- | -# | 08:00 | 08:34 | Refactorización ns8-candados... | [P] ✅ | -# -# Uso: -# importer = MDImporter.new(db_connection) -# resultado = importer.importar_bitacora('bitacoras/2026-02-28.md') -# resultado = importer.importar_todo_directorio('bitacoras/') -# -# Dependencias: Clase BitacoraDB del módulo BitacorasDB - -require 'date' -require 'time' -require 'yaml' - -module BitacorasDB - module Importers - class MDImporter - # Estados posibles en archivos .md y su mapeo a BD - ESTADOS_MD = { - '✅' => '✅', - '❌' => '❌', - '⚠️' => '⚠️', - '⏸️' => '⏸️', - '⏳' => '⏳', - '👁️' => '⏳' # Sincronización mapea a ⏳ - }.freeze - - # Modos posibles en archivos .md - MODOS_MD = { - '[P]' => 'P', # Presencial - '[R]' => 'R', # Remoto - '[P/R]' => 'P' # Presencial/Remoto -> Presencial por defecto - }.freeze - - # Tipos de nodo inferidos del nombre - TIPOS_NODO = { - /^srv-/ => 'servidor', - /^dc-/ => 'vm', - /^sql-/ => 'vm', - /^pcv-/ => 'vm', - /^pc-/ => 'pc', - /^srvv-/ => 'vm', - /-pmox\d+$/ => 'hipervisor', - /-xen\d+$/ => 'hipervisor' - }.freeze - - # Inicializa el importador con conexión a base de datos - # - # @param db [BitacoraDB] Instancia de BitacoraDB para operaciones - # @param logger [Object] Logger para registro (opcional) - def initialize(db, logger = nil) - @db = db - @logger = logger || default_logger - @estadisticas = { - archivos_procesados: 0, - bitacoras_creadas: 0, - nodos_creados: 0, - temas_creados: 0, - entradas_creadas: 0, - errores: [] - } - end - - # Importa una bitácora específica desde archivo .md - # - # @param ruta_md [String] Ruta al archivo .md - # @param opciones [Hash] Opciones de importación - # :sobrescribir [Boolean] Sobrescribir bitácora si ya existe (default: false) - # :crear_nodos [Boolean] Crear nodos automáticamente si no existen (default: true) - # @return [Hash] Resultado de la importación con estadísticas - def importar_bitacora(ruta_md, opciones = {}) - defaults = { sobrescribir: false, crear_nodos: true } - opciones = defaults.merge(opciones) - - @estadisticas[:archivos_procesados] += 1 - - begin - # Leer y parsear archivo - contenido = File.read(ruta_md, encoding: 'UTF-8') - fecha = extraer_fecha_desde_ruta(ruta_md) || extraer_fecha_desde_contenido(contenido) - - if fecha.nil? - error = "No se pudo determinar fecha del archivo: #{ruta_md}" - @logger.error(error) - @estadisticas[:errores] << error - return { error: error } - end - - @logger.info("Importando bitácora #{fecha} desde #{ruta_md}") - - # Verificar si ya existe bitácora - bitacora_existente = @db.find_bitacora_by_fecha(fecha) - if bitacora_existente && !opciones[:sobrescribir] - @logger.warn("Bitácora #{fecha} ya existe, omitiendo (use --sobrescribir)") - return { - skip: true, - mensaje: "Bitácora ya existe", - bitacora_id: bitacora_existente['id'], - estadisticas: @estadisticas - } - end - - # Parsear contenido - estructura = parsear_contenido(contenido, fecha) - - # Importar a base de datos - resultado = importar_estructura(estructura, opciones) - - resultado.merge( - exitoso: resultado[:errores].empty?, - fecha: fecha, - estadisticas: @estadisticas.dup - ) - - rescue => e - error = "Error importando #{ruta_md}: #{e.message}" - @logger.error(error) - @estadisticas[:errores] << error - { - error: error, - backtrace: e.backtrace, - estadisticas: @estadisticas - } - end - end - - # Importa todas las bitácoras de un directorio - # - # @param directorio [String] Ruta al directorio con archivos .md - # @param opciones [Hash] Opciones de importación - # @return [Hash] Resultado consolidado - def importar_directorio(directorio, opciones = {}) - archivos = Dir.glob(File.join(directorio, '*.md')).sort - resultados = [] - - @logger.info("Importando #{archivos.length} archivos desde #{directorio}") - - archivos.each do |archivo| - @logger.info("Procesando: #{File.basename(archivo)}") - resultado = importar_bitacora(archivo, opciones) - resultados << resultado.merge(archivo: archivo) - end - - consolidar_resultados(resultados) - end - - # Obtiene estadísticas de importación - # - # @return [Hash] Estadísticas acumuladas - def estadisticas - @estadisticas - end - - private - - # Extrae fecha desde la ruta del archivo (ej: bitacoras/2026-02-28.md) - def extraer_fecha_desde_ruta(ruta) - nombre = File.basename(ruta, '.md') - begin - Date.parse(nombre) - rescue Date::Error - nil - end - end - - # Extrae fecha desde el contenido del archivo - def extraer_fecha_desde_contenido(contenido) - # Buscar patrón: # Bitácora 2026-02-28 - match = contenido.match(/# Bitácora (\d{4}-\d{2}-\d{2})/) - return Date.parse(match[1]) if match - - # Buscar patrón: # Bitácora de Operaciones - 28/02/2026 - match = contenido.match(/# Bitácora de Operaciones - (\d{2}\/\d{2}\/\d{4})/) - if match - fecha_str = match[1] - dia, mes, anio = fecha_str.split('/') - return Date.parse("#{anio}-#{mes}-#{dia}") - end - - nil - end - - # Parsea el contenido del archivo .md a estructura jerárquica - def parsear_contenido(contenido, fecha) - lineas = contenido.lines.map(&:chomp) - - estructura = { - fecha: fecha, - resumen: extraer_resumen(contenido), - nodos: {}, - secciones: {} - } - - nodo_actual = nil - tema_actual = nil - en_actividades_detalladas = false - en_tabla_entradas = false - encabezados_tabla = [] - entradas_tabla = [] - - lineas.each_with_index do |linea, idx| - # Detectar sección de actividades detalladas - if linea.match?(/^## 📂 Actividades Detalladas/) - en_actividades_detalladas = true - next - end - - # Detectar fin de sección (siguiente ##) - if en_actividades_detalladas && linea.start_with?('## ') && !linea.include?('Actividades Detalladas') - en_actividades_detalladas = false - end - - # Solo procesar dentro de actividades detalladas - next unless en_actividades_detalladas - - # Detectar nodo (### srv-ns8) - if linea.start_with?('### ') && !linea.start_with?('####') - nodo_nombre = linea.sub('### ', '').strip - nodo_actual = nodo_nombre - estructura[:nodos][nodo_actual] ||= { - nombre: nodo_nombre, - temas: {} - } - next - end - - # Detectar tema (#### ✅ - SEC01 - Refactorización ns8-candados) - if linea.start_with?('#### ') - tema_linea = linea.sub('#### ', '').strip - tema_info = parsear_tema(tema_linea) - - if tema_info && nodo_actual - tema_actual = tema_info[:id_tema] - estructura[:nodos][nodo_actual][:temas][tema_actual] = { - id_tema: tema_info[:id_tema], - titulo: tema_info[:titulo], - estado: tema_info[:estado], - descripcion: tema_info[:descripcion], - entradas: [] - } - end - next - end - - # Detectar inicio de tabla de entradas - if linea.match?(/^\| I \| F \| Descripción \| E \|$/) - en_tabla_entradas = true - encabezados_tabla = linea.split('|').map(&:strip).reject(&:empty?) - entradas_tabla = [] - next - end - - # Detectar fin de tabla - if en_tabla_entradas && (linea.empty? || linea.start_with?('#') || linea.start_with?('####')) - # Procesar entradas acumuladas - if tema_actual && nodo_actual && !entradas_tabla.empty? - entradas_parseadas = parsear_entradas_tabla(entradas_tabla, encabezados_tabla) - estructura[:nodos][nodo_actual][:temas][tema_actual][:entradas] = entradas_parseadas - end - - en_tabla_entradas = false - encabezados_tabla = [] - entradas_tabla = [] - end - - # Acumular líneas de tabla - if en_tabla_entradas && linea.start_with?('|') - entradas_tabla << linea - end - end - - # Procesar última tabla si estaba activa al final del archivo - if en_tabla_entradas && tema_actual && nodo_actual && !entradas_tabla.empty? - entradas_parseadas = parsear_entradas_tabla(entradas_tabla, encabezados_tabla) - estructura[:nodos][nodo_actual][:temas][tema_actual][:entradas] = entradas_parseadas - end - - estructura - end - - # Extrae resumen general del contenido - def extraer_resumen(contenido) - # Buscar en sección "Resumen de Actividades" - if contenido.include?('### 📝 Resumen de Actividades') - seccion = contenido.split('### 📝 Resumen de Actividades')[1] - if seccion - # Tomar las primeras líneas después de la tabla - lineas = seccion.lines.map(&:chomp) - resumen_lineas = [] - en_tabla = false - - lineas.each do |linea| - if linea.match?(/^\|.*\|$/) - en_tabla = true - elsif en_tabla && !linea.match?(/^\|.*\|$/) - # Fin de tabla, empezar a capturar resumen - if linea.strip.length > 10 # Ignorar líneas muy cortas - resumen_lineas << linea.strip - end - end - end - - return resumen_lineas.join(' ') if resumen_lineas.any? - end - end - - nil - end - - # Parsea línea de tema (ej: "✅ - SEC01 - Refactorización ns8-candados") - def parsear_tema(linea) - # Patrón: estado - id - título - match = linea.match(/^([✅❌⚠️⏸️⏳👁️]+)\s*-\s*([A-Z0-9]+)\s*-\s*(.+)$/) - return nil unless match - - estado = match[1] - id_tema = match[2] - titulo = match[3].strip - - { - id_tema: id_tema, - titulo: titulo, - estado: ESTADOS_MD[estado] || '⏳', - descripcion: titulo # Por defecto, usar título como descripción - } - end - - # Parsea líneas de tabla de entradas - def parsear_entradas_tabla(lineas_tabla, encabezados) - entradas = [] - - # Mapeo de columnas basado en encabezados - columnas = {} - encabezados.each_with_index do |encabezado, idx| - case encabezado.downcase - when 'i' then columnas[:inicio] = idx - when 'f' then columnas[:fin] = idx - when 'descripción' then columnas[:descripcion] = idx - when 'e' then columnas[:estado] = idx - end - end - - lineas_tabla.each do |linea| - next if linea.match?(/^[\|\s-]+$/) # Saltar separadores de tabla - - celdas = linea.split('|').map(&:strip).reject(&:empty?) - next if celdas.length < 3 # Mínimo: inicio, descripción, estado - - fin_valor = nil - if columnas[:fin] && celdas[columnas[:fin]] != '-' - fin_valor = celdas[columnas[:fin]] - end - - entrada = { - inicio: celdas[columnas[:inicio]], - fin: fin_valor, - descripcion: celdas[columnas[:descripcion]], - estado_modo: celdas[columnas[:estado]] - } - - # Parsear estado y modo (ej: "[P] ✅") - if entrada[:estado_modo] - estado_modo = parsear_estado_modo(entrada[:estado_modo]) - entrada[:estado] = estado_modo[:estado] - entrada[:modo] = estado_modo[:modo] - end - - entradas << entrada - end - - entradas - end - - # Parsea campo estado/modo (ej: "[P] ✅") - def parsear_estado_modo(campo) - estado = '⏳' - modo = 'P' - - # Buscar estado en el campo - ESTADOS_MD.each do |md_estado, bd_estado| - if campo.include?(md_estado) - estado = bd_estado - break - end - end - - # Buscar modo en el campo - MODOS_MD.each do |md_modo, bd_modo| - if campo.include?(md_modo) - modo = bd_modo - break - end - end - - { estado: estado, modo: modo } - end - - # Importa estructura parseada a base de datos - def importar_estructura(estructura, opciones) - errores = [] - - begin - # 1. Crear o actualizar bitácora - bitacora = @db.find_bitacora_by_fecha(estructura[:fecha]) - - if bitacora - @logger.info("Bitácora #{estructura[:fecha]} ya existe (ID: #{bitacora['id']})") - else - bitacora = @db.create_bitacora( - fecha: estructura[:fecha], - resumen: estructura[:resumen] - ) - @estadisticas[:bitacoras_creadas] += 1 - @logger.info("Bitácora creada: #{estructura[:fecha]} (ID: #{bitacora['id']})") - end - - bitacora_id = bitacora['id'] - - # 2. Procesar cada nodo - estructura[:nodos].each do |nombre_nodo, datos_nodo| - # Buscar o crear nodo - nodo = @db.find_nodo_by_nombre(nombre_nodo) - - if nodo.nil? && opciones[:crear_nodos] - tipo = inferir_tipo_nodo(nombre_nodo) - nodo = @db.create_nodo( - nombre: nombre_nodo, - tipo: tipo, - descripcion: "Importado desde bitácora #{estructura[:fecha]}" - ) - @estadisticas[:nodos_creados] += 1 - @logger.info("Nodo creado: #{nombre_nodo} (ID: #{nodo['id']})") - elsif nodo.nil? - @logger.warn("Nodo #{nombre_nodo} no existe y crear_nodos=false, omitiendo") - next - end - - nodo_id = nodo['id'] - - # 3. Procesar temas del nodo - datos_nodo[:temas].each do |id_tema, datos_tema| - # Buscar tema por id_tema y bitácora - temas = @db.list_temas(bitacora_id: bitacora_id, nodo_id: nodo_id, limit: 100) - tema_existente = temas.find { |t| t['id_tema'] == id_tema } - - if tema_existente - @logger.info("Tema #{id_tema} ya existe (ID: #{tema_existente['id']})") - tema_id = tema_existente['id'] - else - tema = @db.create_tema( - id_tema: id_tema, - titulo: datos_tema[:titulo], - estado: datos_tema[:estado], - descripcion: datos_tema[:descripcion], - bitacora_id: bitacora_id, - nodo_id: nodo_id - ) - tema_id = tema['id'] - @estadisticas[:temas_creados] += 1 - @logger.info("Tema creado: #{id_tema} (ID: #{tema_id})") - end - - # 4. Procesar entradas del tema - datos_tema[:entradas].each do |entrada_md| - # Validar campos requeridos - next unless entrada_md[:inicio] && entrada_md[:descripcion] - - # Crear entrada en BD - @db.create_entrada( - inicio: entrada_md[:inicio], - fin: entrada_md[:fin], - descripcion: entrada_md[:descripcion], - estado: entrada_md[:estado] || '⏳', - modo: entrada_md[:modo] || 'P', - es_ia: false, # Las importadas de .md no son IA - tema_id: tema_id, - bitacora_id: bitacora_id, - nodo_id: nodo_id - ) - @estadisticas[:entradas_creadas] += 1 - end - end - end - - rescue => e - error = "Error importando estructura: #{e.message}" - @logger.error(error) - errores << error - end - - { errores: errores } - end - - # Infiere tipo de nodo basado en su nombre - def inferir_tipo_nodo(nombre) - TIPOS_NODO.each do |patron, tipo| - return tipo if nombre.match?(patron) - end - 'servidor' # Tipo por defecto - end - - # Consolida resultados de múltiples importaciones - def consolidar_resultados(resultados) - totales = { - archivos: resultados.length, - exitosos: resultados.count { |r| r[:exitoso] == true }, - omitidos: resultados.count { |r| r[:skip] == true }, - errores: resultados.count { |r| r[:error] } - } - - estadisticas_consolidadas = { - archivos_procesados: resultados.length, - bitacoras_creadas: resultados.sum { |r| r.dig(:estadisticas, :bitacoras_creadas) || 0 }, - nodos_creados: resultados.sum { |r| r.dig(:estadisticas, :nodos_creados) || 0 }, - temas_creados: resultados.sum { |r| r.dig(:estadisticas, :temas_creados) || 0 }, - entradas_creadas: resultados.sum { |r| r.dig(:estadisticas, :entradas_creadas) || 0 }, - errores: resultados.flat_map { |r| r.dig(:estadisticas, :errores) || [] }.compact - } - - { - totales: totales, - estadisticas: estadisticas_consolidadas, - detalles: resultados - } - end - - # Logger por defecto - def default_logger - Class.new do - def info(msg); puts "[INFO] #{msg}"; end - def warn(msg); puts "[WARN] #{msg}"; end - def error(msg); puts "[ERROR] #{msg}"; end - end.new - end - end - end -end -```Ahora necesito actualizar el subcomando `migrar:md` en `subcomando_db.rb` para usar el importador MD. Primero debo leer el contenido actual del subcomando `migrar:md` y luego modificarlo. Voy a leer el archivo.<|end▁of▁thinking|> diff --git a/tools/probar_buscador.rb b/tools/probar_buscador.rb index 9a597a53..3fae6455 100644 --- a/tools/probar_buscador.rb +++ b/tools/probar_buscador.rb @@ -4,7 +4,7 @@ # tools/probar_buscador.rb — Script de prueba para sistema de búsqueda # ================================================================================ # Este script prueba la funcionalidad del sistema de búsqueda y filtrado -# implementado en tools/bitacoras-db/core/buscador_bd.rb +# implementado en tools/adn/db/core/buscador_bd.rb # # Uso: # ruby tools/probar_buscador.rb [OPCIONES] @@ -32,7 +32,7 @@ require 'optparse' require 'json' # Cargar módulos locales -$LOAD_PATH.unshift(File.join(__dir__, 'bitacoras-db', 'core')) +$LOAD_PATH.unshift(File.join(__dir__, 'adn', 'db', 'core')) require 'buscador_bd' class ProbadorBuscador diff --git a/tools/probar_buscador_simple.rb b/tools/probar_buscador_simple.rb index dc2a6fad..43d58b28 100644 --- a/tools/probar_buscador_simple.rb +++ b/tools/probar_buscador_simple.rb @@ -11,7 +11,7 @@ require 'yaml' require 'json' # Cargar módulos locales -$LOAD_PATH.unshift(File.join(__dir__, 'bitacoras-db', 'core')) +$LOAD_PATH.unshift(File.join(__dir__, 'adn', 'db', 'core')) require 'buscador_bd_simple' class ProbadorBuscadorSimple