84 lines
2.3 KiB
TypeScript
84 lines
2.3 KiB
TypeScript
import app from './app';
|
|
import environment from './config/environment';
|
|
import logger from './utils/logger';
|
|
import { testConnection, closePool, runMigrations } from './config/database';
|
|
import { startAuditCleanupJob, stopAuditCleanupJob } from './jobs/audit-cleanup.job';
|
|
|
|
const startServer = async (): Promise<void> => {
|
|
try {
|
|
// Test database connection
|
|
logger.info('Testing database connection...');
|
|
const dbConnected = await testConnection();
|
|
|
|
if (!dbConnected) {
|
|
logger.warn('Database connection failed - server will start but database operations may fail');
|
|
} else {
|
|
// Run pending migrations automatically on startup
|
|
await runMigrations();
|
|
}
|
|
|
|
// Start the GDPR IP anonymisation job
|
|
startAuditCleanupJob();
|
|
|
|
// Start the server
|
|
const server = app.listen(environment.port, () => {
|
|
logger.info('Server started successfully', {
|
|
port: environment.port,
|
|
environment: environment.nodeEnv,
|
|
database: dbConnected ? 'connected' : 'disconnected',
|
|
});
|
|
});
|
|
|
|
// Graceful shutdown handling
|
|
const gracefulShutdown = async (signal: string) => {
|
|
logger.info(`${signal} received. Starting graceful shutdown...`);
|
|
|
|
// Stop scheduled jobs first
|
|
stopAuditCleanupJob();
|
|
|
|
server.close(async () => {
|
|
logger.info('HTTP server closed');
|
|
|
|
// Close database connection
|
|
await closePool();
|
|
|
|
logger.info('Graceful shutdown completed');
|
|
process.exit(0);
|
|
});
|
|
|
|
// Force shutdown after 10 seconds
|
|
setTimeout(() => {
|
|
logger.error('Forced shutdown after timeout');
|
|
process.exit(1);
|
|
}, 10000);
|
|
};
|
|
|
|
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
|
|
process.on('SIGINT', () => gracefulShutdown('SIGINT'));
|
|
|
|
} catch (error) {
|
|
logger.error('Failed to start server', { error });
|
|
process.exit(1);
|
|
}
|
|
};
|
|
|
|
// Handle unhandled promise rejections
|
|
process.on('unhandledRejection', (reason: Error, _promise: Promise<any>) => {
|
|
logger.error('Unhandled Promise Rejection', {
|
|
reason: reason.message,
|
|
stack: reason.stack,
|
|
});
|
|
});
|
|
|
|
// Handle uncaught exceptions
|
|
process.on('uncaughtException', (error: Error) => {
|
|
logger.error('Uncaught Exception', {
|
|
message: error.message,
|
|
stack: error.stack,
|
|
});
|
|
process.exit(1);
|
|
});
|
|
|
|
// Start the server
|
|
startServer();
|