Files
cim_summary/backend/src/index.ts
Jon c67dab22b4 Add comprehensive CIM processing features and UI improvements
- Add new database migrations for analysis data and job tracking
- Implement enhanced document processing service with LLM integration
- Add processing progress and queue status components
- Create testing guides and utility scripts for CIM processing
- Update frontend components for better user experience
- Add environment configuration and backup files
- Implement job queue service and upload progress tracking
2025-07-27 20:25:46 -04:00

137 lines
3.6 KiB
TypeScript

import express from 'express';
import cors from 'cors';
import helmet from 'helmet';
import morgan from 'morgan';
import rateLimit from 'express-rate-limit';
import { config } from './config/env';
import { logger } from './utils/logger';
import authRoutes from './routes/auth';
import documentRoutes from './routes/documents';
import { errorHandler } from './middleware/errorHandler';
import { notFoundHandler } from './middleware/notFoundHandler';
import { jobQueueService } from './services/jobQueueService';
const app = express();
const PORT = config.port || 5000;
// Security middleware
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
scriptSrc: ["'self'"],
imgSrc: ["'self'", "data:", "https:"],
},
},
}));
// CORS configuration
app.use(cors({
origin: config.frontendUrl || 'http://localhost:3000',
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
}));
// Rate limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 1000, // limit each IP to 1000 requests per windowMs (increased for testing)
message: {
error: 'Too many requests from this IP, please try again later.',
},
standardHeaders: true,
legacyHeaders: false,
});
app.use(limiter);
// Body parsing middleware
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
// Logging middleware
app.use(morgan('combined', {
stream: {
write: (message: string) => logger.info(message.trim()),
},
}));
// Health check endpoint
app.get('/health', (_req, res) => { // _req to fix TS6133
res.status(200).json({
status: 'ok',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
environment: config.nodeEnv,
});
});
// API routes
app.use('/api/auth', authRoutes);
app.use('/api/documents', documentRoutes);
// API root endpoint
app.get('/api', (_req, res) => { // _req to fix TS6133
res.json({
message: 'CIM Document Processor API',
version: '1.0.0',
endpoints: {
auth: '/api/auth',
documents: '/api/documents',
health: '/health',
},
});
});
// 404 handler
app.use(notFoundHandler);
// Global error handler (must be last)
app.use(errorHandler);
// Start server
const server = app.listen(PORT, () => {
logger.info(`🚀 Server running on port ${PORT}`);
logger.info(`📊 Environment: ${config.nodeEnv}`);
logger.info(`🔗 API URL: http://localhost:${PORT}/api`);
logger.info(`🏥 Health check: http://localhost:${PORT}/health`);
});
// Start job queue service
jobQueueService.start();
logger.info('📋 Job queue service started');
// Graceful shutdown
const gracefulShutdown = (signal: string) => {
logger.info(`${signal} received, shutting down gracefully`);
// Stop accepting new connections
server.close(() => {
logger.info('HTTP server closed');
// Stop job queue service
jobQueueService.stop();
logger.info('Job queue service stopped');
// Stop upload progress service
const { uploadProgressService } = require('./services/uploadProgressService');
uploadProgressService.stop();
logger.info('Upload progress service stopped');
logger.info('Process terminated');
process.exit(0);
});
// Force close after 30 seconds
setTimeout(() => {
logger.error('Could not close connections in time, forcefully shutting down');
process.exit(1);
}, 30000);
};
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
process.on('SIGINT', () => gracefulShutdown('SIGINT'));
export default app;