docs: actualiza CAMBIOS-2026-05-04.md y commitea fixes pendientes

- Monitor de sincronización SAT (sat-sync-monitor.job + alerta por correo).
- Scraper de CSF más robusto (iframes, blobs, popups, validación PDF).
- Reactivación de contribuyentes desactivados y limpieza al desactivar.
- Timeout de constancia aumentado a 5 min.
- Variables de entorno SAT en .env.example y env.ts.
This commit is contained in:
Horux Dev
2026-06-25 02:09:58 +00:00
parent a1727321c3
commit 1130a1833c
14 changed files with 1108 additions and 95 deletions

View File

@@ -820,9 +820,12 @@ async function processMetadataRange(
}
/**
* Determina el tamaño de bloque óptimo consultando metadata del rango completo.
* Determina el tamaño de bloque óptimo consultando metadata en chunks de 1 año.
* <= 15,000 CFDIs → bloques de 6 meses
* > 15,000 CFDIs → bloques de 2 meses
* > 15,000 CFDIs → bloques de 3 meses
*
* El SAT no genera paquetes de metadata para rangos muy grandes (p. ej. 6 años),
* así que el sondeo se divide en bloques anuales.
*/
async function determineChunkMonths(
ctx: SyncContext,
@@ -851,17 +854,20 @@ async function determineChunkMonths(
}
const THRESHOLD = 15_000;
const probeChunks = generateChunks(fechaInicio, fechaFin, 12);
let totalCfdis = 0;
for (const tipo of ['emitidos', 'recibidos'] as const) {
try {
const { totalCfdis: count } = await requestAndDownload(
ctx, jobId, fechaInicio, fechaFin, tipo, 'metadata'
);
totalCfdis += count;
console.log(`[SAT] Sondeo metadata ${tipo}: ${count} CFDIs en rango completo`);
} catch (error: any) {
console.log(`[SAT] No se pudo sondear metadata ${tipo}: ${error.message}`);
for (const { start, end } of probeChunks) {
try {
const { totalCfdis: count } = await requestAndDownload(
ctx, jobId, start, end, tipo, 'metadata'
);
totalCfdis += count;
console.log(`[SAT] Sondeo metadata ${tipo} ${start.toISOString().slice(0, 10)}${end.toISOString().slice(0, 10)}: ${count} CFDIs`);
} catch (error: any) {
console.log(`[SAT] No se pudo sondear metadata ${tipo} ${start.toISOString().slice(0, 10)}${end.toISOString().slice(0, 10)}: ${error.message}`);
}
}
}
@@ -907,7 +913,7 @@ async function processInitialSync(
// Paso 1: Sondeo — determinar tamaño de bloque para XMLs
const chunkMonths = await determineChunkMonths(ctx, jobId, inicioHistorico, fechaFin);
const xmlChunks = generateChunks(inicioHistorico, fechaFin, chunkMonths);
const metaChunks = generateChunks(inicioHistorico, fechaFin, 36); // bloques de 3 años
const metaChunks = generateChunks(inicioHistorico, fechaFin, 12); // bloques de 1 año
console.log(`[SAT] Sincronización: ${xmlChunks.length} bloques XML (${chunkMonths}m) + ${metaChunks.length} bloques metadata (36m)`);