codigo0/backend/scripts/verify-content-missing.js

202 lines
5.7 KiB
JavaScript
Executable file
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

#!/usr/bin/env node
/**
* Script de verificación de contenido faltante
*
* Compara el contenido local (procedures.ts, drugs.ts, guides-index.ts, material-checklists.ts)
* con el contenido en la base de datos para identificar qué falta.
*
* Uso:
* node backend/scripts/verify-content-missing.js
*/
import dotenv from 'dotenv';
import { query } from '../config/database.js';
import { readFile } from 'fs/promises';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
dotenv.config();
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const REPO_ROOT = join(__dirname, '../..');
// IDs esperados basados en archivos locales
const EXPECTED_PROTOCOLS = [
'rcp-adulto-svb',
'rcp-adulto-sva',
'rcp-pediatrico',
'obstruccion-via-aerea',
'shock-hemorragico',
];
const EXPECTED_DRUGS = [
'oxigeno',
'adrenalina',
'amiodarona',
'atropina',
'midazolam',
'salbutamol',
];
const EXPECTED_GUIDES = [
'abcde-operativo',
'rcp-adulto-svb',
'desa-adulto',
'ovace-adulto',
'ovace-pediatrica',
'parada-respiratoria',
'pcr-traumatica',
'rcp-lactantes',
'rcp-pediatrica',
'reconocimiento-pcr',
];
const EXPECTED_CHECKLISTS = [
'inicio-turno-material',
'pre-escena-rapido',
'post-servicio-cierre',
];
async function getContentFromDB(type) {
const typeMap = {
protocol: 'protocol',
guide: 'guide',
checklist: 'checklist',
};
const dbType = typeMap[type] || type;
const result = await query(`
SELECT slug, title, status
FROM tes_content.content_items
WHERE type = $1::tes_content.content_type
AND version = latest_version
ORDER BY slug
`, [dbType]);
return result.rows.map(row => row.slug);
}
async function getDrugsFromDB() {
const result = await query(`
SELECT slug, generic_name, status
FROM tes_content.drugs
ORDER BY slug
`);
return result.rows.map(row => row.slug);
}
async function main() {
console.log('\n🔍 Verificando contenido faltante en la base de datos...\n');
try {
// Protocolos
console.log('📋 PROTOCOLOS:');
const dbProtocols = await getContentFromDB('protocol');
const missingProtocols = EXPECTED_PROTOCOLS.filter(id => !dbProtocols.includes(id));
const extraProtocols = dbProtocols.filter(id => !EXPECTED_PROTOCOLS.includes(id));
console.log(` Esperados: ${EXPECTED_PROTOCOLS.length}`);
console.log(` En DB: ${dbProtocols.length}`);
console.log(` Faltantes: ${missingProtocols.length}`);
if (missingProtocols.length > 0) {
console.log(` ❌ Faltantes: ${missingProtocols.join(', ')}`);
} else {
console.log(` ✅ Todos los protocolos están en la base de datos`);
}
if (extraProtocols.length > 0) {
console.log(` Extra en DB: ${extraProtocols.join(', ')}`);
}
// Fármacos
console.log('\n💊 FÁRMACOS:');
const dbDrugs = await getDrugsFromDB();
const missingDrugs = EXPECTED_DRUGS.filter(id => !dbDrugs.includes(id));
const extraDrugs = dbDrugs.filter(id => !EXPECTED_DRUGS.includes(id));
console.log(` Esperados: ${EXPECTED_DRUGS.length}`);
console.log(` En DB: ${dbDrugs.length}`);
console.log(` Faltantes: ${missingDrugs.length}`);
if (missingDrugs.length > 0) {
console.log(` ❌ Faltantes: ${missingDrugs.join(', ')}`);
} else {
console.log(` ✅ Todos los fármacos están en la base de datos`);
}
if (extraDrugs.length > 0) {
console.log(` Extra en DB: ${extraDrugs.join(', ')}`);
}
// Guías
console.log('\n📚 GUÍAS:');
const dbGuides = await getContentFromDB('guide');
const missingGuides = EXPECTED_GUIDES.filter(id => !dbGuides.includes(id));
const extraGuides = dbGuides.filter(id => !EXPECTED_GUIDES.includes(id));
console.log(` Esperados: ${EXPECTED_GUIDES.length}`);
console.log(` En DB: ${dbGuides.length}`);
console.log(` Faltantes: ${missingGuides.length}`);
if (missingGuides.length > 0) {
console.log(` ❌ Faltantes: ${missingGuides.join(', ')}`);
} else {
console.log(` ✅ Todas las guías están en la base de datos`);
}
if (extraGuides.length > 0) {
console.log(` Extra en DB: ${extraGuides.join(', ')}`);
}
// Checklists
console.log('\n✅ CHECKLISTS:');
const dbChecklists = await getContentFromDB('checklist');
const missingChecklists = EXPECTED_CHECKLISTS.filter(id => !dbChecklists.includes(id));
const extraChecklists = dbChecklists.filter(id => !EXPECTED_CHECKLISTS.includes(id));
console.log(` Esperados: ${EXPECTED_CHECKLISTS.length}`);
console.log(` En DB: ${dbChecklists.length}`);
console.log(` Faltantes: ${missingChecklists.length}`);
if (missingChecklists.length > 0) {
console.log(` ❌ Faltantes: ${missingChecklists.join(', ')}`);
} else {
console.log(` ✅ Todos los checklists están en la base de datos`);
}
if (extraChecklists.length > 0) {
console.log(` Extra en DB: ${extraChecklists.join(', ')}`);
}
// Resumen
const totalMissing =
missingProtocols.length +
missingDrugs.length +
missingGuides.length +
missingChecklists.length;
console.log('\n📊 RESUMEN:');
console.log(` Total faltante: ${totalMissing} items`);
if (totalMissing > 0) {
console.log('\n💡 Para sincronizar el contenido faltante, ejecuta:');
console.log(' node backend/scripts/sync-content-to-db.js\n');
} else {
console.log('\n✅ ¡Todo el contenido local está en la base de datos!\n');
}
} catch (error) {
console.error('\n❌ Error verificando contenido:', error.message);
console.error(error);
process.exit(1);
}
}
main();