Initial commit - Horux Despachos NL

This commit is contained in:
2026-05-03 16:47:53 -06:00
commit b00b677c54
647 changed files with 133843 additions and 0 deletions

57
apps/api/src/index.ts Normal file
View File

@@ -0,0 +1,57 @@
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';
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();
if (sendRealEmails) {
startWeeklyUpdateJob();
startNotificationsJob();
} else {
console.log('[Cron] weekly-update + notifications omitidos en dev (evita emails reales)');
}
console.log(`[Cron] SAT + metricas 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);
}
});