[Dashboard] P2601 actualizado — Estructura de Ámbitos y Planes (ADN)
- adn/tools/db/migrations/004_create_planes.sql (NUEVO) Migración para tabla 'planes' dentro de ámbitos Reemplaza concepto anterior de 'fases' por 'planes' Incluye vista resumen_planes para métricas - servicios/nginx/dtic-bitacoras/tools/sync_dashboard_to_db.js Actualizado para usar Ámbito A04 (dtic-DASUTEN) en vez de 'P2601' Planes A04.P001 a A04.P006 en vez de 'fases 1-13' Migración automática de DB si tablas no existen 27 hitos organizados por plan (Legacy + Workgroup + Backups) - docs/ambito/dtic-DASUTEN/_hist/260415_dashboard_P2601_actualizacion.md Documentación completa de la actualización Incluye estructura de datos, métricas y referencias **Estructura ADN aplicada:** - Ámbito: A04 (dtic-DASUTEN) - Planes: A04.P001 (Red) a A04.P006 (Backups) - Hitos: 21 completados ✅, 3 pausados ⏸️, 6 legacy 🛑 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
faa5d7ad9a
commit
cafa07303b
@@ -1,4 +1,6 @@
|
||||
const { Client } = require('pg');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const client = new Client({
|
||||
user: 'dtic_user',
|
||||
@@ -12,75 +14,513 @@ async function run() {
|
||||
await client.connect();
|
||||
console.log("Connected to DB");
|
||||
|
||||
const codigo = 'P2601';
|
||||
|
||||
// Get Project ID
|
||||
const pRes = await client.query("SELECT id FROM bitacoras.proyectos WHERE codigo = $1", [codigo]);
|
||||
if (pRes.rowCount === 0) {
|
||||
console.error("Proyecto no encontrado");
|
||||
process.exit(1);
|
||||
// =========================================================================
|
||||
// MIGRACIÓN: Crear tabla planes si no existe
|
||||
// =========================================================================
|
||||
const migrationPath = path.join(__dirname, '../../../adn/tools/db/migrations/004_create_planes.sql');
|
||||
if (fs.existsSync(migrationPath)) {
|
||||
console.log("Running migration 004_create_planes.sql...");
|
||||
const migrationSQL = fs.readFileSync(migrationPath, 'utf8');
|
||||
await client.query(migrationSQL);
|
||||
console.log("Migration completed.");
|
||||
} else {
|
||||
console.log("Migration file not found, skipping...");
|
||||
}
|
||||
const pid = pRes.rows[0].id;
|
||||
|
||||
// Fases IDs
|
||||
const fRes = await client.query("SELECT id, numero FROM bitacoras.fases WHERE proyecto_id = $1", [pid]);
|
||||
const fases = {};
|
||||
fRes.rows.forEach(f => fases[f.numero] = f.id);
|
||||
// =========================================================================
|
||||
// ESTRUCTURA ACTUALIZADA: ÁMBITOS Y PLANES (Ecosistema ADN)
|
||||
// =========================================================================
|
||||
// Ámbito: A04 — dtic-DASUTEN
|
||||
// Planes: A04.P001 a A04.P006 (en lugar de "fases")
|
||||
// =========================================================================
|
||||
|
||||
const ambitoNombre = 'dtic-DASUTEN';
|
||||
const ambitoCodigo = 'A04';
|
||||
|
||||
// Verificar si la columna codigo existe en ambitos, si no, agregarla
|
||||
const colCheck = await client.query(`
|
||||
SELECT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = 'bitacoras' AND table_name = 'ambitos' AND column_name = 'codigo'
|
||||
) AS exists
|
||||
`);
|
||||
|
||||
if (!colCheck.rows[0].exists) {
|
||||
console.log("Adding 'codigo' column to ambitos...");
|
||||
await client.query("ALTER TABLE bitacoras.ambitos ADD COLUMN codigo VARCHAR(10)");
|
||||
await client.query("CREATE UNIQUE INDEX IF NOT EXISTS idx_ambitos_codigo ON bitacoras.ambitos(codigo)");
|
||||
}
|
||||
|
||||
// Get Ámbito ID
|
||||
let aRes = await client.query(
|
||||
"SELECT id FROM bitacoras.ambitos WHERE codigo = $1",
|
||||
[ambitoCodigo]
|
||||
);
|
||||
|
||||
// Si no existe por codigo, buscar por nombre
|
||||
if (aRes.rowCount === 0) {
|
||||
aRes = await client.query(
|
||||
"SELECT id FROM bitacoras.ambitos WHERE nombre = $1",
|
||||
[ambitoNombre]
|
||||
);
|
||||
}
|
||||
|
||||
// Si no existe el ámbito, crearlo
|
||||
if (aRes.rowCount === 0) {
|
||||
console.log("Creating Ámbito A04 (dtic-DASUTEN)...");
|
||||
await client.query(
|
||||
`INSERT INTO bitacoras.ambitos (codigo, nombre, descripcion, activo)
|
||||
VALUES ($1, $2, $3, $4)`,
|
||||
[ambitoCodigo, ambitoNombre, 'Infraestructura y Sistema DASUTEN', true]
|
||||
);
|
||||
const aRes2 = await client.query(
|
||||
"SELECT id FROM bitacoras.ambitos WHERE codigo = $1",
|
||||
[ambitoCodigo]
|
||||
);
|
||||
var ambitoId = aRes2.rows[0].id;
|
||||
} else {
|
||||
var ambitoId = aRes.rows[0].id;
|
||||
// Actualizar codigo si es null
|
||||
await client.query(
|
||||
"UPDATE bitacoras.ambitos SET codigo = $1 WHERE id = $2 AND codigo IS NULL",
|
||||
[ambitoCodigo, ambitoId]
|
||||
);
|
||||
}
|
||||
|
||||
// Planes IDs (reemplazan a "fases")
|
||||
const pRes = await client.query(
|
||||
"SELECT id, codigo FROM bitacoras.planes WHERE ambito_id = $1",
|
||||
[ambitoId]
|
||||
);
|
||||
const planes = {};
|
||||
pRes.rows.forEach(p => planes[p.codigo] = p.id);
|
||||
|
||||
// Nodos IDs
|
||||
const nRes = await client.query("SELECT id, nombre FROM bitacoras.nodos");
|
||||
const nodos = {};
|
||||
nRes.rows.forEach(n => nodos[n.nombre] = n.id);
|
||||
|
||||
// Updates a realizar según el HTML
|
||||
// =========================================================================
|
||||
// HITOS ORGANIZADOS POR PLANES (A04.P001 - A04.P006)
|
||||
// =========================================================================
|
||||
// Estructura:
|
||||
// - A04.P001: Red srv-dasu (23/02 - 27/03)
|
||||
// - A04.P002: Integración DASU-PC (Pausado)
|
||||
// - A04.P003: AD-Join (Pausado)
|
||||
// - A04.P004: Unificación de Redes (Pausado)
|
||||
// - A04.P005: DASUTEN sin DC - Workgroup (27/03 - 15/04) ✅ EXITOSO
|
||||
// - A04.P006: Backups y Refresco de BD (14-15/04) ✅
|
||||
// =========================================================================
|
||||
|
||||
const hitos = [
|
||||
{ fase: 1, id_hito: 'A00-A01', titulo: 'Acondicionamiento Hardware + Proxmox VE', desc: 'Instalación física del servidor srv-dasu y despliegue de Proxmox VE 9.1.', est: '✅', fec: '2026-02-23', h_p: 2.5, h_r: 0, nodo: 'srv-dasu' },
|
||||
{ fase: 2, id_hito: 'A05', titulo: 'VM Windows Server Core → DC', desc: 'Creación de VM, instalación de OS, promoción a Controlador de Dominio (dc-dasuten).', est: '✅', fec: '2026-02-24', h_p: 0.5, h_r: 14, nodo: 'dc-dasuten' },
|
||||
{ fase: 2, id_hito: 'A06', titulo: 'Dashboard P2601', desc: 'Despliegue del panel web con telemetría operativa, glassmorphism y métricas.', est: '✅', fec: '2026-02-24', h_p: 0, h_r: 2, nodo: 'srv-ns8' },
|
||||
{ fase: 3, id_hito: 'DB01', titulo: 'SQL Server 2019 en sql-dasuten', desc: 'Instalación de SQL Server 2019 con collation Modern_Spanish_CI_AS.', est: '✅', fec: '2026-02-25', h_p: 0, h_r: 8, nodo: 'sql-dasuten' },
|
||||
{ fase: 4, id_hito: 'SSH', titulo: 'OpenSSH Server en VMs Windows', desc: 'Despliegue de SSH nativo en dc-dasuten y sql-dasuten. Puerto 7022, firewall configurado.', est: '✅', fec: '2026-02-26', h_p: 0, h_r: 3, nodo: 'dc-dasuten' },
|
||||
{ fase: 4, id_hito: 'BKP', titulo: 'Resguardo VZDump', desc: 'Backup offline (stop mode) de las VMs DC y SQL vía VZDump.', est: '✅', fec: '2026-02-26', h_p: 0, h_r: 1, nodo: 'srv-dasu' },
|
||||
{ fase: 4, id_hito: 'TEST', titulo: 'VM de Pruebas pcv-dasu0', desc: 'Despliegue de Win 10 LTSC, SSH, toolkit W-Zombi. Unión al dominio.', est: '✅', fec: '2026-02-27', h_p: 0, h_r: 6, nodo: 'pcv-dasu0' },
|
||||
{ fase: 3, id_hito: 'P02.DB', titulo: 'Restauración Base de Datos', desc: 'Backup bksysdasuten_Full.bak (~9GB) restaurado. Login sysadmin creado.', est: '✅', fec: '2026-03-04', h_p: 0, h_r: 1, nodo: 'sql-dasuten' },
|
||||
{ fase: 5, id_hito: 'P02.APP', titulo: 'Despliegue del Sistema DASUTEN', desc: 'Configuración Kermet.ini, componentes y fuentes. Login exitoso con aalmiron.', est: '✅', fec: '2026-03-05', h_p: 1, h_r: 2, nodo: 'pcv-dasu0' },
|
||||
{ fase: 5, id_hito: 'NET01', titulo: 'Tailscale VPN en srv-dasu', desc: 'Instalación y configuración como subnet router para 10.0.100.0/24.', est: '✅', fec: '2026-03-05', h_p: 0, h_r: 0.5, nodo: 'srv-dasu' },
|
||||
{ fase: 5, id_hito: 'TEST03', titulo: 'Conectividad SQL desde Cliente', desc: 'Apertura de firewall TCP 1433 y validación ODBC.', est: '✅', fec: '2026-03-05', h_p: 0, h_r: 1, nodo: 'pcv-dasu0' },
|
||||
{ fase: 6, id_hito: 'UAT', titulo: 'Verificación Presencial por Usuario', desc: 'Validación funcional in-situ con Andrea Almirón. Resultado exitoso.', est: '✅', fec: '2026-03-05', h_p: 1, h_r: 0, nodo: 'pc-dasu0' },
|
||||
{ fase: 6, id_hito: 'FÍSICO', titulo: '🧱 Instalación Física de srv-dasu', desc: 'Traslado e instalación definitiva del servidor físico Proxmox.', est: '⏳', fec: null, h_p: 0, h_r: 0, nodo: 'srv-dasu' },
|
||||
{ fase: 6, id_hito: 'ADDOM', titulo: '🤝 AD-Join: pc-dasu0 al Dominio', desc: 'Unir la PC física del cliente local al directorio activo (dc-dasuten).', est: '⏳', fec: null, h_p: 0, h_r: 0, nodo: 'pc-dasu0' },
|
||||
{ fase: 6, id_hito: 'GPO', titulo: '🛡️ Políticas de Seguridad (GPO)', desc: 'Configuración de GPOs de dominio para restringir acceso y mapeos.', est: '⏳', fec: null, h_p: 0, h_r: 0, nodo: 'dc-dasuten' },
|
||||
{ fase: 6, id_hito: 'S02', titulo: '🔐 Hardenización SSH', desc: 'Llaves SSH, passphrases, auditoría y elevación de seguridad.', est: '⏳', fec: null, h_p: 0, h_r: 0, nodo: 'dc-dasuten' },
|
||||
{ fase: 6, id_hito: 'CLI', titulo: '💻 Configuración Final pc-dasu0', desc: 'PC física de la oficina DASUTeN como cliente del dominio.', est: '⏳', fec: null, h_p: 0, h_r: 0, nodo: 'pc-dasu0' }
|
||||
// =====================================================================
|
||||
// PLAN A04.P001: Red srv-dasu (Infraestructura Base)
|
||||
// =====================================================================
|
||||
{
|
||||
plan: 'A04.P001',
|
||||
id_hito: 'P001.01',
|
||||
titulo: '📦 Recepción y acondicionamiento de srv-dasu',
|
||||
desc: 'Hardware recibido y preparado para instalación de Proxmox VE 9.1.',
|
||||
est: '✅',
|
||||
fec: '2026-02-23',
|
||||
h_p: 2,
|
||||
h_r: 0,
|
||||
nodo: 'srv-dasu'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P001',
|
||||
id_hito: 'P001.02',
|
||||
titulo: '🔧 Instalación de Proxmox VE 9.1',
|
||||
desc: 'Hipervisor instalado. Bridge vmbr0 configurado (NAT 10.0.100.x inicial).',
|
||||
est: '✅',
|
||||
fec: '2026-02-23',
|
||||
h_p: 1,
|
||||
h_r: 0.5,
|
||||
nodo: 'srv-dasu'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P001',
|
||||
id_hito: 'P001.03',
|
||||
titulo: '📊 Dashboard P2601 Desplegado',
|
||||
desc: 'Panel web con telemetría en ns8.frlr.utn.edu.ar/P2601/',
|
||||
est: '✅',
|
||||
fec: '2026-02-24',
|
||||
h_p: 0,
|
||||
h_r: 2,
|
||||
nodo: 'srv-ns8'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P001',
|
||||
id_hito: 'P001.04',
|
||||
titulo: '🌐 Tailscale VPN en srv-dasu',
|
||||
desc: 'Instalación y configuración. Cuenta pcdasu0@frlr.utn.edu.ar.',
|
||||
est: '✅',
|
||||
fec: '2026-03-05',
|
||||
h_p: 0,
|
||||
h_r: 0.5,
|
||||
nodo: 'srv-dasu'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P001',
|
||||
id_hito: 'P001.05',
|
||||
titulo: '🔄 Reconfiguración vmbr0 (Pivot)',
|
||||
desc: '27/03: vmbr0 cambiado de NAT 10.0.100.x a DHCP directo del ISP (192.168.1.x).',
|
||||
est: '✅',
|
||||
fec: '2026-03-27',
|
||||
h_p: 0.5,
|
||||
h_r: 1,
|
||||
nodo: 'srv-dasu'
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// PLAN A04.P002: Integración DASU-PC (PAUSADO - Enfoque cambiado)
|
||||
// =====================================================================
|
||||
{
|
||||
plan: 'A04.P002',
|
||||
id_hito: 'P002.01',
|
||||
titulo: '⏸️ Plan Pausado: Integración DASU-PC',
|
||||
desc: 'Originalmente: Integración de PC física al dominio. Pausado por cambio a Workgroup.',
|
||||
est: '⏸️',
|
||||
fec: null,
|
||||
h_p: 0,
|
||||
h_r: 0,
|
||||
nodo: 'dasu-pc'
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// PLAN A04.P003: AD-Join (PAUSADO - Enfoque cambiado)
|
||||
// =====================================================================
|
||||
{
|
||||
plan: 'A04.P003',
|
||||
id_hito: 'P003.01',
|
||||
titulo: '⏸️ Plan Pausado: AD-Join al Dominio',
|
||||
desc: 'Originalmente: Unir PC física al dominio dc-dasuten. Pausado por cambio a Workgroup.',
|
||||
est: '⏸️',
|
||||
fec: null,
|
||||
h_p: 0,
|
||||
h_r: 0,
|
||||
nodo: 'dc-dasuten'
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// PLAN A04.P004: Unificación de Redes (PARCIAL - Implementado sin DC)
|
||||
// =====================================================================
|
||||
{
|
||||
plan: 'A04.P004',
|
||||
id_hito: 'P004.01',
|
||||
titulo: '⏸️ Plan Pausado: Unificación de Redes ISP',
|
||||
desc: 'Originalmente: Unificar red académica + ISP. Pausado: se adoptó red plana DHCP del ISP.',
|
||||
est: '⏸️',
|
||||
fec: null,
|
||||
h_p: 0,
|
||||
h_r: 0,
|
||||
nodo: 'srv-dasu'
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// PLAN A04.P005: DASUTEN sin Domain Controller (Workgroup) ✅ EXITOSO
|
||||
// =====================================================================
|
||||
// Legacy: Enfoque con DC (23/02 - 27/03) - Contexto histórico
|
||||
{
|
||||
plan: 'A04.P005',
|
||||
id_hito: 'P005.LEG.01',
|
||||
titulo: '🖥️ VM 100: dc-dasuten (DC - Legacy)',
|
||||
desc: '24/02: VM creada (2C/2GB/50GB). AD DS + DNS. 🛑 Apagada 27/03 por recursos.',
|
||||
est: '🛑',
|
||||
fec: '2026-02-24',
|
||||
h_p: 0.5,
|
||||
h_r: 2,
|
||||
nodo: 'dc-dasuten'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P005',
|
||||
id_hito: 'P005.LEG.02',
|
||||
titulo: '🗄️ VM 101: sql-dasuten (SQL - Legacy)',
|
||||
desc: '25/02: VM creada (2C/4GB/60+100GB). SQL 2019. 🛑 Apagada 27/03.',
|
||||
est: '🛑',
|
||||
fec: '2026-02-25',
|
||||
h_p: 0,
|
||||
h_r: 4,
|
||||
nodo: 'sql-dasuten'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P005',
|
||||
id_hito: 'P005.LEG.03',
|
||||
titulo: '🧪 VM 102: pcv-dasu0 (Pruebas - Legacy)',
|
||||
desc: '27/02: Win10 LTSC + SSH. Unión al dominio. 🛑 Apagada 27/03.',
|
||||
est: '🛑',
|
||||
fec: '2026-02-27',
|
||||
h_p: 0,
|
||||
h_r: 3,
|
||||
nodo: 'pcv-dasu0'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P005',
|
||||
id_hito: 'P005.LEG.04',
|
||||
titulo: '👤 Validación Usuaria (DC - Legacy)',
|
||||
desc: '05/03: Andrea Almirón valida login. Sistema operativo pero LENTO.',
|
||||
est: '⚠️',
|
||||
fec: '2026-03-05',
|
||||
h_p: 1,
|
||||
h_r: 2,
|
||||
nodo: 'pcv-dasu0'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P005',
|
||||
id_hito: 'P005.LEG.05',
|
||||
titulo: '⚠️ Caídas Intermitentes DC',
|
||||
desc: '11/03: RAM insuficiente (15GB vs 20GB requeridos). DC se cae frecuentemente.',
|
||||
est: '🔴',
|
||||
fec: '2026-03-11',
|
||||
h_p: 0,
|
||||
h_r: 2,
|
||||
nodo: 'dc-dasuten'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P005',
|
||||
id_hito: 'P005.LEG.06',
|
||||
titulo: '🔄 Pivot: Abandonar Enfoque DC',
|
||||
desc: '27/03: Decisión oficial. VMs legacy apagadas y preservadas.',
|
||||
est: '✅',
|
||||
fec: '2026-03-27',
|
||||
h_p: 1,
|
||||
h_r: 2,
|
||||
nodo: 'srv-dasu'
|
||||
},
|
||||
// Enfoque Workgroup exitoso (27/03 - 15/04)
|
||||
{
|
||||
plan: 'A04.P005',
|
||||
id_hito: 'P005.WG.01',
|
||||
titulo: '🖥️ VM 106: dasu-sql4 (SQL Workgroup)',
|
||||
desc: '09/04: VM creada (4C/4GB/60+120GB). WS2022 Español + SQL 2019. UTC-3 Argentina.',
|
||||
est: '✅',
|
||||
fec: '2026-04-09',
|
||||
h_p: 1,
|
||||
h_r: 4,
|
||||
nodo: 'dasu-sql4'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P005',
|
||||
id_hito: 'P005.WG.02',
|
||||
titulo: '🖥️ VM 107: dasu-pcv (Cliente Pruebas)',
|
||||
desc: '11/04: Restaurada desde backup. Desvinculada de dominio. Workgroup DASUTEN.',
|
||||
est: '✅',
|
||||
fec: '2026-04-11',
|
||||
h_p: 0.5,
|
||||
h_r: 2,
|
||||
nodo: 'dasu-pcv'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P005',
|
||||
id_hito: 'P005.WG.03',
|
||||
titulo: '💾 Migración de Base de Datos',
|
||||
desc: '11/04: RESTORE DATABASE en 26s (354 MB/s). DBCC CHECKDB sin errores.',
|
||||
est: '✅',
|
||||
fec: '2026-04-11',
|
||||
h_p: 0,
|
||||
h_r: 1.5,
|
||||
nodo: 'dasu-sql4'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P005',
|
||||
id_hito: 'P005.WG.04',
|
||||
titulo: '⚙️ Kermet.ini Configurado',
|
||||
desc: '11/04: UID=sa explícito. SERVER=dasu-sql4. Sin dependencia de AD.',
|
||||
est: '✅',
|
||||
fec: '2026-04-11',
|
||||
h_p: 0,
|
||||
h_r: 1,
|
||||
nodo: 'dasu-pcv'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P005',
|
||||
id_hito: 'P005.WG.05',
|
||||
titulo: '🖥️ dasu-pc: PC Física en Oficina',
|
||||
desc: '13/04: SysDasuten copiado. Usuario: aalmiron. Workgroup DASUTEN.',
|
||||
est: '✅',
|
||||
fec: '2026-04-13',
|
||||
h_p: 2,
|
||||
h_r: 1,
|
||||
nodo: 'dasu-pc'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P005',
|
||||
id_hito: 'P005.WG.06',
|
||||
titulo: '🖨️ Impresión Resuelta (Symlink)',
|
||||
desc: '14/04: mklink /D C:\\Sistema C:\\SysDasuten\\Sistema. Plantillas localizadas.',
|
||||
est: '✅',
|
||||
fec: '2026-04-14',
|
||||
h_p: 1,
|
||||
h_r: 2,
|
||||
nodo: 'dasu-pc'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P005',
|
||||
id_hito: 'P005.WG.07',
|
||||
titulo: '🕐 Zona Horaria Corregida',
|
||||
desc: '15/04: dasu-sql4: "Romance ST" → "Argentina ST" (UTC-3). Clave para datos.',
|
||||
est: '✅',
|
||||
fec: '2026-04-15',
|
||||
h_p: 0,
|
||||
h_r: 1,
|
||||
nodo: 'dasu-sql4'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P005',
|
||||
id_hito: 'P005.WG.08',
|
||||
titulo: '✅ Validación Final con Usuaria',
|
||||
desc: '15/04 17:00: Andrea Almirón confirma sistema 100% operativo. Datos del día visibles.',
|
||||
est: '✅',
|
||||
fec: '2026-04-15',
|
||||
h_p: 1,
|
||||
h_r: 1,
|
||||
nodo: 'dasu-pc'
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// PLAN A04.P006: Backups y Refresco de Base de Datos ✅
|
||||
// =====================================================================
|
||||
{
|
||||
plan: 'A04.P006',
|
||||
id_hito: 'P006.01',
|
||||
titulo: '🤖 Pipeline de Backups (Drones Atómicos)',
|
||||
desc: '14/04: 6 drones independientes (exportar→transferir→upload→download→restaurar→verificar).',
|
||||
est: '✅',
|
||||
fec: '2026-04-14',
|
||||
h_p: 1,
|
||||
h_r: 4,
|
||||
nodo: 'srv-ns8'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P006',
|
||||
id_hito: 'P006.02',
|
||||
titulo: '💾 Backup FULL Semanal',
|
||||
desc: '~1.3 GB, 35-40 min. ./adn/tools/run bkps run dasuten_full',
|
||||
est: '✅',
|
||||
fec: '2026-04-14',
|
||||
h_p: 0,
|
||||
h_r: 1,
|
||||
nodo: 'dasu-sql4'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P006',
|
||||
id_hito: 'P006.03',
|
||||
titulo: '📝 Backup Diferencial Diario',
|
||||
desc: '~0.4-10 MB, 5-10 min. ./adn/tools/run bkps run dasuten_diferencial',
|
||||
est: '✅',
|
||||
fec: '2026-04-14',
|
||||
h_p: 0,
|
||||
h_r: 1,
|
||||
nodo: 'dasu-sql4'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P006',
|
||||
id_hito: 'P006.04',
|
||||
titulo: '🔄 Refresco Final de BD',
|
||||
desc: '15/04: Último refresco desde srvv-fenix antes de validación.',
|
||||
est: '✅',
|
||||
fec: '2026-04-15',
|
||||
h_p: 0,
|
||||
h_r: 1,
|
||||
nodo: 'dasu-sql4'
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// DOCUMENTACIÓN Y LECCIONES APRENDIDAS (Transversal)
|
||||
// =====================================================================
|
||||
{
|
||||
plan: 'A04.P005',
|
||||
id_hito: 'P005.DOC.01',
|
||||
titulo: '📚 Lecciones Aprendidas (DC Legacy)',
|
||||
desc: '15/04: Documento _hist/P2601.legacy_lecciones_aprendidas.md creado.',
|
||||
est: '✅',
|
||||
fec: '2026-04-15',
|
||||
h_p: 1,
|
||||
h_r: 3,
|
||||
nodo: 'dtic-DIIAA'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P005',
|
||||
id_hito: 'P005.DOC.02',
|
||||
titulo: '🔄 Armonía Integral',
|
||||
desc: '15/04: IA.md, A04_dtic-DASUTEN.md, A04.P005 actualizados con caso de estudio.',
|
||||
est: '✅',
|
||||
fec: '2026-04-15',
|
||||
h_p: 0.5,
|
||||
h_r: 2,
|
||||
nodo: 'dtic-DIIAA'
|
||||
},
|
||||
{
|
||||
plan: 'A04.P006',
|
||||
id_hito: 'P006.DOC.01',
|
||||
titulo: '📄 A04.P006_Backups-DASUTEN.md',
|
||||
desc: '14/04: Documento de backups creado con pipeline completo y comandos.',
|
||||
est: '✅',
|
||||
fec: '2026-04-14',
|
||||
h_p: 0.5,
|
||||
h_r: 1,
|
||||
nodo: 'srv-ns8'
|
||||
},
|
||||
];
|
||||
|
||||
// Primero marcamos P02.DB, P02.APP viejos u otros como completados/borrados si es necesario
|
||||
await client.query("UPDATE bitacoras.hitos SET estado = '✅', fecha = '2026-03-04' WHERE id_hito = 'P02.DB'");
|
||||
await client.query("DELETE FROM bitacoras.hitos WHERE id_hito IN ('MIG', 'P02.APP')");
|
||||
// Crear planes si no existen
|
||||
const planTitles = {
|
||||
'A04.P001': 'Red srv-dasu',
|
||||
'A04.P002': 'Integración DASU-PC (Pausado)',
|
||||
'A04.P003': 'AD-Join (Pausado)',
|
||||
'A04.P004': 'Unificación de Redes (Pausado)',
|
||||
'A04.P005': 'DASUTEN sin Domain Controller',
|
||||
'A04.P006': 'Backups y Refresco de BD'
|
||||
};
|
||||
|
||||
for (const h of hitos) {
|
||||
if (!fases[h.fase]) {
|
||||
console.log(`Fase ${h.fase} no existe, creándola...`);
|
||||
const faseI = await client.query("INSERT INTO bitacoras.fases (proyecto_id, numero, titulo) VALUES ($1, $2, $3) RETURNING id", [pid, h.fase, `Fase ${h.fase}`]);
|
||||
fases[h.fase] = faseI.rows[0].id;
|
||||
}
|
||||
|
||||
const nodo_id = nodos[h.nodo] || null;
|
||||
|
||||
// Verificar si existe el hito
|
||||
const exRes = await client.query("SELECT id FROM bitacoras.hitos WHERE id_hito = $1 AND fase_id = $2", [h.id_hito, fases[h.fase]]);
|
||||
|
||||
if (exRes.rowCount > 0) {
|
||||
console.log(`Updating ${h.id_hito}...`);
|
||||
await client.query(`UPDATE bitacoras.hitos SET titulo=$1, descripcion=$2, estado=$3, fecha=$4, horas_presencial=$5, horas_remoto=$6, nodo_id=$7 WHERE id=$8`,
|
||||
[h.titulo, h.desc, h.est, h.fec, h.h_p, h.h_r, nodo_id, exRes.rows[0].id]);
|
||||
} else {
|
||||
console.log(`Inserting ${h.id_hito}...`);
|
||||
await client.query(`INSERT INTO bitacoras.hitos (fase_id, id_hito, titulo, descripcion, estado, fecha, horas_presencial, horas_remoto, nodo_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
|
||||
[fases[h.fase], h.id_hito, h.titulo, h.desc, h.est, h.fec, h.h_p, h.h_r, nodo_id]);
|
||||
for (const [codigo, titulo] of Object.entries(planTitles)) {
|
||||
if (!planes[codigo]) {
|
||||
console.log(`Creating Plan ${codigo}...`);
|
||||
const pI = await client.query(
|
||||
`INSERT INTO bitacoras.planes (ambito_id, codigo, titulo, estado)
|
||||
VALUES ($1, $2, $3, $4) RETURNING id`,
|
||||
[ambitoId, codigo, titulo, '✅']
|
||||
);
|
||||
planes[codigo] = pI.rows[0].id;
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Done");
|
||||
// Actualizar/Insertar hitos
|
||||
for (const h of hitos) {
|
||||
const plan_id = planes[h.plan] || null;
|
||||
const nodo_id = nodos[h.nodo] || null;
|
||||
|
||||
// Verificar si existe el hito
|
||||
const exRes = await client.query(
|
||||
"SELECT id FROM bitacoras.hitos WHERE id_hito = $1 AND plan_id = $2",
|
||||
[h.id_hito, plan_id]
|
||||
);
|
||||
|
||||
if (exRes.rowCount > 0) {
|
||||
console.log(`Updating ${h.id_hito} (${h.titulo})...`);
|
||||
await client.query(
|
||||
`UPDATE bitacoras.hitos SET
|
||||
titulo=$1, descripcion=$2, estado=$3, fecha=$4,
|
||||
horas_presencial=$5, horas_remoto=$6, nodo_id=$7
|
||||
WHERE id=$8`,
|
||||
[h.titulo, h.desc, h.est, h.fec, h.h_p, h.h_r, nodo_id, exRes.rows[0].id]
|
||||
);
|
||||
} else {
|
||||
console.log(`Inserting ${h.id_hito} (${h.titulo})...`);
|
||||
await client.query(
|
||||
`INSERT INTO bitacoras.hitos (
|
||||
plan_id, id_hito, titulo, descripcion, estado, fecha,
|
||||
horas_presencial, horas_remoto, nodo_id
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
|
||||
[plan_id, h.id_hito, h.titulo, h.desc, h.est, h.fec, h.h_p, h.h_r, nodo_id]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("\n✅ Done! Dashboard A04 (dtic-DASUTEN) actualizado con estructura de Ámbitos y Planes");
|
||||
console.log(" - Ámbito: A04");
|
||||
console.log(` - Planes: ${Object.keys(planes).length}`);
|
||||
console.log(` - Hitos: ${hitos.length}`);
|
||||
await client.end();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user