C1: src/worker.ts and src/server.ts only imported 5 of 10 BullMQ workers. ai/bulk/maintenance/reports/webhooks were never started, so in production: webhooks never delivered, no maintenance crons (DB backups, session cleanup, retention sweeps, alerts, analytics refresh, calendar sync), no scheduled reports, no AI features, no async bulk. All 10 are now imported and held against GC. R2-C1: Bulk archive's runBulk callback discarded the return value from archiveClientWithDecisions, so Documenso envelopes marked for void in the wizard were never queued and next-in-line notifications never fired. Now we collect the per-archive (dossier, result) pairs and replay the same post-commit fan-out the single-client route uses. R2-C2: Archived-client header's Restore icon was hovering destructive- red because an unconditional hover:text-foreground was overriding the later conditional. Restore now hovers emerald; archive still hovers red. 1175/1175 vitest passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
60 lines
1.8 KiB
TypeScript
60 lines
1.8 KiB
TypeScript
/**
|
|
* Worker entry point for the crm-worker container.
|
|
*
|
|
* Imports all BullMQ workers and registers recurring job schedules.
|
|
* In production this runs as a separate process (Dockerfile.worker).
|
|
* In development, server.ts imports workers inline instead.
|
|
*/
|
|
|
|
import { logger } from '@/lib/logger';
|
|
import { registerRecurringJobs } from '@/lib/queue/scheduler';
|
|
|
|
// Import all workers - the act of importing starts them
|
|
import { emailWorker } from '@/lib/queue/workers/email';
|
|
import { documentsWorker } from '@/lib/queue/workers/documents';
|
|
import { notificationsWorker } from '@/lib/queue/workers/notifications';
|
|
import { importWorker } from '@/lib/queue/workers/import';
|
|
import { exportWorker } from '@/lib/queue/workers/export';
|
|
import { aiWorker } from '@/lib/queue/workers/ai';
|
|
import { bulkWorker } from '@/lib/queue/workers/bulk';
|
|
import { maintenanceWorker } from '@/lib/queue/workers/maintenance';
|
|
import { reportsWorker } from '@/lib/queue/workers/reports';
|
|
import { webhooksWorker } from '@/lib/queue/workers/webhooks';
|
|
|
|
// Keep references so workers aren't GC'd
|
|
const workers = [
|
|
emailWorker,
|
|
documentsWorker,
|
|
notificationsWorker,
|
|
importWorker,
|
|
exportWorker,
|
|
aiWorker,
|
|
bulkWorker,
|
|
maintenanceWorker,
|
|
reportsWorker,
|
|
webhooksWorker,
|
|
];
|
|
|
|
async function main(): Promise<void> {
|
|
logger.info({ workerCount: workers.length }, 'BullMQ workers started');
|
|
|
|
await registerRecurringJobs();
|
|
logger.info('Recurring jobs registered');
|
|
|
|
// Graceful shutdown
|
|
const shutdown = async () => {
|
|
logger.info('Shutting down workers...');
|
|
await Promise.all(workers.map((w) => w.close()));
|
|
logger.info('All workers closed');
|
|
process.exit(0);
|
|
};
|
|
|
|
process.on('SIGTERM', shutdown);
|
|
process.on('SIGINT', shutdown);
|
|
}
|
|
|
|
main().catch((err) => {
|
|
logger.error(err, 'Worker process failed to start');
|
|
process.exit(1);
|
|
});
|