/** * Limpia el cache `metricas_mensuales` de TODOS los tenants activos. * * Ejecutar después de cambios fiscales en las fórmulas de ingresos/deducciones * (dashboard.service.ts) — los valores ya escritos en el cache reflejan la * fórmula vieja y muestran datos incorrectos para meses pasados hasta ser * recomputados. * * Estrategia: TRUNCATE (vía DELETE) por tenant. La próxima consulta a un * período pasado cae al path on-the-fly y rehidrata el cache con la fórmula * vigente. No bloquea uso normal — solo aumenta latencia de la primera lectura. * * Idempotente. Por-tenant try/catch para que un tenant que falla no tumbe el * resto. */ import { prisma, tenantDb } from '../src/config/database.js'; async function main() { const tenants = await prisma.tenant.findMany({ where: { active: true }, select: { id: true, nombre: true, rfc: true, databaseName: true }, orderBy: { rfc: 'asc' }, }); console.log(`[Cache Refresh] Iterando ${tenants.length} tenant(s) activo(s)...\n`); let totalRows = 0; let okTenants = 0; let failedTenants = 0; for (const t of tenants) { try { const pool = await tenantDb.getPool(t.id, t.databaseName); const result = await pool.query('DELETE FROM metricas_mensuales'); const rows = result.rowCount ?? 0; totalRows += rows; okTenants++; console.log(`✓ ${t.rfc.padEnd(15)} ${t.nombre.padEnd(40)} → ${rows.toLocaleString('es-MX')} filas borradas`); } catch (err: any) { failedTenants++; console.error(`✗ ${t.rfc.padEnd(15)} ${t.nombre.padEnd(40)} → ERROR: ${err.message || err}`); } } console.log(`\n[Cache Refresh] Completado:`); console.log(` Tenants OK: ${okTenants}`); console.log(` Tenants fallidos: ${failedTenants}`); console.log(` Total filas: ${totalRows.toLocaleString('es-MX')}`); console.log(`\nLa próxima consulta a un período en cache lo recomputará on-demand`); console.log(`con las fórmulas vigentes en dashboard.service.ts.`); await prisma.$disconnect(); process.exit(failedTenants > 0 ? 1 : 0); } main().catch(err => { console.error(err); process.exit(1); });