62 lines
2.5 KiB
TypeScript
62 lines
2.5 KiB
TypeScript
import { app } from './app.js';
|
|
import { env } from './config/env.js';
|
|
import { tenantDb } from './config/database.js';
|
|
import { invalidateTenantCache } from './middlewares/plan-limits.middleware.js';
|
|
import { startSatSyncJob } from './jobs/sat-sync.job.js';
|
|
import { startWeeklyUpdateJob } from './jobs/weekly-update.job.js';
|
|
import { startMetricasInvalidationsJob } from './jobs/metricas-invalidations.job.js';
|
|
import { startNotificationsJob } from './jobs/notifications.job.js';
|
|
import { startSatSyncMonitorJob } from './jobs/sat-sync-monitor.job.js';
|
|
import { startRecordatoriosPeriodicosJob } from './jobs/recordatorios-periodicos.job.js';
|
|
|
|
const PORT = parseInt(env.PORT, 10);
|
|
|
|
const server = app.listen(PORT, '0.0.0.0', () => {
|
|
console.log(`API Server running on http://0.0.0.0:${PORT}`);
|
|
console.log(`Environment: ${env.NODE_ENV}`);
|
|
|
|
// Iniciar jobs programados.
|
|
// En dev, los crons se omiten por default para no consumir recursos ni
|
|
// disparar efectos (SAT queries, emails). Con ENABLE_CRONS_IN_DEV=1 se
|
|
// arrancan los crons seguros (SAT sync/retry, métricas); el weekly-update
|
|
// sigue siendo prod-only porque envía emails a owners reales.
|
|
const cronsEnabled = env.NODE_ENV === 'production' || process.env.ENABLE_CRONS_IN_DEV === '1';
|
|
const sendRealEmails = env.NODE_ENV === 'production';
|
|
if (cronsEnabled) {
|
|
startSatSyncJob();
|
|
startMetricasInvalidationsJob();
|
|
startSatSyncMonitorJob();
|
|
startRecordatoriosPeriodicosJob();
|
|
if (sendRealEmails) {
|
|
startWeeklyUpdateJob();
|
|
startNotificationsJob();
|
|
} else {
|
|
console.log('[Cron] weekly-update + notifications omitidos en dev (evita emails reales)');
|
|
}
|
|
console.log(`[Cron] SAT + metricas + SAT monitor activos (NODE_ENV=${env.NODE_ENV}, ENABLE_CRONS_IN_DEV=${process.env.ENABLE_CRONS_IN_DEV ?? 'unset'})`);
|
|
} else {
|
|
console.log('[Cron] Jobs omitidos en dev (usar ENABLE_CRONS_IN_DEV=1 para activar)');
|
|
}
|
|
});
|
|
|
|
// Graceful shutdown — close all tenant DB pools before exiting
|
|
const gracefulShutdown = async (signal: string) => {
|
|
console.log(`${signal} received. Shutting down gracefully...`);
|
|
server.close(() => {
|
|
console.log('HTTP server closed');
|
|
});
|
|
await tenantDb.shutdown();
|
|
process.exit(0);
|
|
};
|
|
|
|
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
|
|
process.on('SIGINT', () => gracefulShutdown('SIGINT'));
|
|
|
|
// PM2 cluster: cross-worker cache invalidation
|
|
process.on('message', (msg: any) => {
|
|
if (msg?.type === 'invalidate-tenant-cache' && msg.tenantId) {
|
|
tenantDb.invalidatePool(msg.tenantId);
|
|
invalidateTenantCache(msg.tenantId);
|
|
}
|
|
});
|