Stabilize logging, correlation IDs, service-account Jira auth, and direct approver reminder DMs while splitting the monolith into focused modules with Compose-based deployment. Co-authored-by: Cursor <cursoragent@cursor.com>
64 lines
2.4 KiB
JavaScript
64 lines
2.4 KiB
JavaScript
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);
|
|
});
|