Files
dtic-DIIAA/adn/tools/db/cli/verificar_migracion.rb

122 lines
4.4 KiB
Ruby
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# frozen_string_literal: true
# adn/tools/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 adn/tools/db/cli/verificar_migracion.rb
# — o vía enjambre —
# ./adn/tools/run db verificar
require 'date'
require_relative '../core/bitacora_db'
module BitacorasDB
module CLI
class VerificarMigracion
COLORES = {
reset: "\e[0m", bold: "\e[1m", red: "\e[31m",
green: "\e[32m", yellow: "\e[33m", cyan: "\e[36m", dim: "\e[2m"
}.freeze
def initialize(bitacoras_dir)
@bitacoras_dir = bitacoras_dir
@resultados = { ok: [], sin_entradas: [], no_migrada: [], sin_md: [] }
end
def ejecutar
puts "#{COLORES[:cyan]}🔍 Verificación de migración MD ↔ DB#{COLORES[:reset]}\n\n"
archivos_md = Dir.glob(File.join(@bitacoras_dir, '*.md')).sort
puts "#{COLORES[:dim]}Archivos MD encontrados: #{archivos_md.size}#{COLORES[:reset]}"
BitacorasDB::BitacoraDB.with_connection do |db|
# 1. Validar cada MD contra la DB
archivos_md.each do |archivo|
fecha = File.basename(archivo, '.md')
bitacora = db.find_bitacora_by_fecha(fecha)
unless bitacora
@resultados[:no_migrada] << fecha
next
end
entradas = db.execute(
"SELECT COUNT(*) as total FROM bitacoras.entradas WHERE bitacora_id = $1",
[bitacora['id']]
)
total = entradas.first['total'].to_i
if total > 0
@resultados[:ok] << { fecha: fecha, entradas: total }
else
@resultados[:sin_entradas] << fecha
end
end
# 2. Bitácoras en DB que no tienen MD
todas_db = db.list_bitacoras(limit: 500)
fechas_md = archivos_md.map { |a| File.basename(a, '.md') }
todas_db.each do |b|
f = b['fecha'].to_s
f = f.split('T').first if f.include?('T') # por si viene con timestamp
@resultados[:sin_md] << f unless fechas_md.include?(f)
end
end
mostrar_resultados
end
private
def mostrar_resultados
puts "\n#{COLORES[:bold]}📊 Resultado de verificación:#{COLORES[:reset]}\n"
# OK
puts "#{COLORES[:green]}✅ Migradas correctamente: #{@resultados[:ok].size}#{COLORES[:reset]}"
@resultados[:ok].each do |r|
puts " #{COLORES[:dim]}#{r[:fecha]} (#{r[:entradas]} entradas)#{COLORES[:reset]}"
end
# Sin entradas
if @resultados[:sin_entradas].any?
puts "\n#{COLORES[:yellow]}⚠ En DB pero sin entradas: #{@resultados[:sin_entradas].size}#{COLORES[:reset]}"
@resultados[:sin_entradas].each { |f| puts " #{f}" }
end
# No migradas
if @resultados[:no_migrada].any?
puts "\n#{COLORES[:red]}❌ No migradas (MD existe, DB no): #{@resultados[:no_migrada].size}#{COLORES[:reset]}"
@resultados[:no_migrada].each { |f| puts " #{f}" }
puts " #{COLORES[:dim]}Ejecuta: ./adn/tools/run db migrar:md FECHA#{COLORES[:reset]}"
end
# Sin MD
if @resultados[:sin_md].any?
puts "\n#{COLORES[:cyan]} En DB sin archivo MD: #{@resultados[:sin_md].size}#{COLORES[:reset]}"
@resultados[:sin_md].each { |f| puts " #{f}" }
puts " #{COLORES[:dim]}Ejecuta: ./adn/tools/run db exportar:md FECHA#{COLORES[:reset]}"
end
total = @resultados[:ok].size + @resultados[:sin_entradas].size
total_md = @resultados[:ok].size + @resultados[:sin_entradas].size + @resultados[:no_migrada].size
pct = total_md > 0 ? ((@resultados[:ok].size.to_f / total_md) * 100).round(1) : 0
puts "\n#{COLORES[:bold]}📈 Cobertura: #{pct}% (#{@resultados[:ok].size}/#{total_md})#{COLORES[:reset]}"
if @resultados[:no_migrada].empty? && @resultados[:sin_entradas].empty?
puts "#{COLORES[:green]}#{COLORES[:bold]}🎉 ¡Migración completa! Todas las bitácoras están en la DB.#{COLORES[:reset]}"
end
end
end
end
end
# Ejecución directa
if __FILE__ == $0
bitacoras_dir = File.expand_path('../../../docs/bitacoras', __dir__)
BitacorasDB::CLI::VerificarMigracion.new(bitacoras_dir).ejecutar
end