Files
dtic-DIIAA/dtic-BITACORAs/tools/sync_bitacora.js
T
Ricardo Monla 15725e0b3c 🚀 P02: Despliegue exitoso del sistema DASUTEN en pcv-dasu0
Infraestructura y Red:
- Tailscale v1.94.2 instalado en srv-dasu (IP: 100.116.210.36)
- Configurado como subnet router para 10.0.100.0/24
- Fix: Repositorios enterprise de Proxmox deshabilitados (.sources → .bak)

Despliegue del Sistema (pcv-dasu0):
- Transferencia SCP de runSysDasuten.zip via SSH puerto 7022
- Extracción en C:\Dasuten\runSysDasuten- Kermet.ini configurado: SERVER=sql-dasuten
- InstaladorComponentesKermet.exe (silent install)
- Fuentes TrueType registradas en Windows (Code39, I2OF5)
- Firewall TCP 1433 abierto en sql-dasuten
- Test-NetConnection: TcpTestSucceeded=True
- Login exitoso con usuario aalmiron 

ADN y Contexto:
- 05_ia.md: Regla 13 Auto-Contextualización Topológica
- 07_proyectos.md: Sección 'Topología y Red' obligatoria en manifiestos
- P2601_dasuten.md: Contexto de red documentado
- nodos/pcv-dasu0.md: Puerto SSH actualizado a 7022

Dashboard P2601:
- Hitos completados: 8 → 11 (P02.APP, NET01, TEST03)
- Progreso: 67% → 79%
- pcv-dasu0: Testing → Online
- Nuevo hito activo: UAT (verificación presencial)

Bitácoras y Documentación:
- Bitácora 04/03 y 05/03 completas
- Plan de despliegue en docs/plan/260305-1017
- Investigación de ingeniería inversa documentada
- ns8-candados: Instrucciones de uso para IA agregadas
- dtic-BITACORAs: CRUD completo, Dashboard P2601 integrado

Herramientas:
- w-zombi: Mejora anti-loop (max 5 ciclos)
- Payloads de despliegue SQL y sistema generados
2026-03-05 13:15:31 -03:00

95 lines
3.2 KiB
JavaScript

const fs = require('fs');
const { Pool } = require('pg');
const pool = new Pool({
connectionString: "postgres://dtic_user:dtic_pass_2026@localhost:5433/dtic_bitacoras"
});
async function syncFile(filePath) {
const content = fs.readFileSync(filePath, 'utf8');
const lines = content.split('\n');
const dateStr = filePath.match(/(\d{4}-\d{2}-\d{2})\.md/)[1];
console.log(`Sincronizando bitácora: ${dateStr}`);
// Asegurar bitácora
const bResult = await pool.query(
'INSERT INTO bitacoras.bitacoras (fecha) VALUES ($1) ON CONFLICT (fecha) DO UPDATE SET fecha = EXCLUDED.fecha RETURNING id',
[dateStr]
);
const bitacoraId = bResult.rows[0].id;
// Obtener mapeo de nodos
const { rows: nodos } = await pool.query('SELECT id, nombre FROM bitacoras.nodos');
const nodoMap = {};
nodos.forEach(n => { nodoMap[n.nombre] = n.id; });
// Limpiar entradas previas
await pool.query('DELETE FROM bitacoras.entradas WHERE bitacora_id = $1', [bitacoraId]);
let currentNodoId = null;
let inDetailedActivities = false;
let entriesFound = 0;
for (let line of lines) {
// Detectar inicio de sección de actividades detalladas
if (line.includes('Actividades Detalladas')) {
inDetailedActivities = true;
continue;
}
if (!inDetailedActivities) continue;
// Detectar cambio de nodo
if (line.startsWith('### ')) {
const nodoName = line.replace('### ', '').trim().split(' ')[0];
currentNodoId = nodoMap[nodoName] || null;
if (currentNodoId) console.log(`Cambiando a nodo: ${nodoName} (ID: ${currentNodoId})`);
continue;
}
if (!currentNodoId) continue;
// Detectar entrada de tabla
const regex = /\|\s*(\d{2}:\d{2})\s*\|\s*(\d{2}:\d{2})\s*\|\s*(.*?)\s*\|\s*(.*?)\s*\|/;
const match = line.match(regex);
if (match) {
let inicio = match[1];
let fin = match[2];
let descRaw = match[3];
let estadoRaw = match[4];
const esIA = descRaw.includes('(IA)');
let descripcion = descRaw.replace('(IA)', '').replace(/\*\*/g, '').replace(/__/g, '').trim();
// A veces el MD tiene ** al principio
if (descripcion.startsWith('**')) descripcion = descripcion.substring(2);
const statusMatch = estadoRaw.match(/\[([A-Z])\] (.*)/);
const modo = statusMatch ? statusMatch[1] : 'P';
const estado = statusMatch ? statusMatch[2] : estadoRaw;
await pool.query(
`INSERT INTO bitacoras.entradas (inicio, fin, descripcion, estado, modo, es_ia, bitacora_id, nodo_id)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
[inicio, fin, descripcion, estado, modo, esIA, bitacoraId, currentNodoId]
);
entriesFound++;
}
}
console.log(`Sincronización finalizada. Entradas cargadas: ${entriesFound}`);
await pool.end();
}
const file = process.argv[2];
if (!file) {
console.error('Uso: node sync_bitacora.js <path_to_md>');
process.exit(1);
}
syncFile(file).catch(err => {
console.error(err);
process.exit(1);
});