import fs from 'fs'; import { loadConfig, loadRequests, getMissingSecrets, describeJiraIdentity } from './lib/config.js'; import { createLogger } from './lib/logger.js'; import { createJiraClient } from './services/jiraClient.js'; import { createJiraService } from './services/jira.js'; import { createWebexService } from './services/webex.js'; import { createJiraProcessor } from './services/jiraProcessor.js'; import { createPendingApprovalsJob, cleanupOldLogs } from './jobs/pendingApprovals.js'; import { scheduleJobs } from './jobs/cron.js'; import { createWebhookRoutes } from './routes/webhooks.js'; import { createApp } from './app.js'; const config = loadConfig(); const requests = loadRequests(); const log = createLogger(config); if (!fs.existsSync('./logs')) { fs.mkdirSync('./logs', { recursive: true }); } const missingSecrets = getMissingSecrets(config); if (missingSecrets.length > 0) { log.writeLog('warn', 'startup', `Missing configuration — set env vars or config.json: ${missingSecrets.join(', ')}`); } if (process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0') { log.writeLog('warn', 'startup', 'NODE_TLS_REJECT_UNAUTHORIZED=0 is set — TLS certificate verification is disabled'); } log.logger('startup', `Jira identity: ${describeJiraIdentity(config)}`); const jiraClient = createJiraClient(config); const jiraService = createJiraService(jiraClient, log); const webexService = createWebexService(config, log); const jiraProcessor = createJiraProcessor({ config, requests, jiraService, webexService, log }); const pendingApprovalsJob = createPendingApprovalsJob({ jiraService, webexService, log }); scheduleJobs({ runPendingApprovals: pendingApprovalsJob.runPendingApprovals, cleanupOldLogs: () => cleanupOldLogs(log), log, }); const app = createApp(); const webhookRoutes = createWebhookRoutes({ config, jiraProcessor, webexService, log }); webhookRoutes.registerRoutes(app); const server = app.listen(config.server.port, () => { log.logger('startup', `${config.server.name} running on port ${config.server.port}.`); }); process.on('SIGINT', () => { server.close(() => { log.logger('shutdown', `${config.server.name} stopped!`); process.exit(); }); }); process.on('unhandledRejection', (reason) => { log.logError('process', 'Unhandled promise rejection', reason); }); process.on('uncaughtException', (err) => { log.logError('process', 'Uncaught exception — shutting down', err); process.exit(1); });