Re_Backend/src/server.ts

99 lines
3.4 KiB
TypeScript

import http from 'http';
import dotenv from 'dotenv';
import path from 'path';
// Load environment variables from .env file FIRST
dotenv.config({ path: path.resolve(__dirname, '../.env') });
// Stop queue metrics collection on shutdown
// Note: This is imported statically but doesn't trigger database/queue activity until called
import { stopQueueMetrics } from './utils/queueMetrics';
const PORT: number = parseInt(process.env.PORT || '5000', 10);
// Start server
const startServer = async (): Promise<void> => {
try {
// Initialize Google Secret Manager before starting server
// This will merge secrets from GCS into process.env if enabled
const { initializeGoogleSecretManager } = require('./services/googleSecretManager.service');
console.log('🔐 Initializing secrets...');
await initializeGoogleSecretManager();
const { default: app, initializeAppDatabase } = require('./app');
const { initSocket } = require('./realtime/socket');
// Initialize database connection explicitly after secrets are loaded
await initializeAppDatabase();
require('./queues/tatWorker'); // Initialize TAT worker
const { logTatConfig } = require('./config/tat.config');
const { logSystemConfig } = require('./config/system.config');
const { initializeHolidaysCache } = require('./utils/tatTimeUtils');
const { seedDefaultConfigurations } = require('./services/configSeed.service');
const { startPauseResumeJob } = require('./jobs/pauseResumeJob');
require('./queues/pauseResumeWorker'); // Initialize pause resume worker
const { initializeQueueMetrics } = require('./utils/queueMetrics');
const { emailService } = require('./services/email.service');
// Initialize email service after secrets are loaded
try {
await emailService.initialize();
console.log('📧 Email service initialized');
} catch (error) {
console.warn('⚠️ Email service initialization warning (will use test account if SMTP not configured):', error);
}
const server = http.createServer(app);
initSocket(server);
// Seed default configurations if table is empty
try {
await seedDefaultConfigurations();
} catch (error) {
console.error('⚠️ Configuration seeding error:', error);
}
// Seed default activity types if table is empty
const { seedDefaultActivityTypes } = require('./services/activityTypeSeed.service');
try {
await seedDefaultActivityTypes();
} catch (error) {
console.error('⚠️ Activity type seeding error:', error);
}
// Initialize holidays cache for TAT calculations
try {
await initializeHolidaysCache();
} catch (error) {
// Silently fall back to weekends-only TAT calculation
}
// Start scheduled jobs
startPauseResumeJob();
// Initialize queue metrics collection for Prometheus
initializeQueueMetrics();
server.listen(PORT, () => {
console.log(`🚀 Server running on port ${PORT} | ${process.env.NODE_ENV || 'development'}`);
});
} catch (error) {
console.error('❌ Unable to start server:', error);
process.exit(1);
}
};
// Graceful shutdown
process.on('SIGTERM', () => {
console.log('🛑 SIGTERM signal received: closing HTTP server');
stopQueueMetrics();
process.exit(0);
});
process.on('SIGINT', () => {
console.log('🛑 SIGINT signal received: closing HTTP server');
stopQueueMetrics();
process.exit(0);
});
startServer();