-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.ts
More file actions
108 lines (90 loc) · 3.09 KB
/
index.ts
File metadata and controls
108 lines (90 loc) · 3.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/**
* Main Application Entry Point
*/
import express, { Express } from 'express';
import cors from 'cors';
import helmet from 'helmet';
import path from 'path';
import { config, validateConfig } from './config';
import { logger } from './utils/logger';
import uploadRoutes from './routes/upload.routes';
import searchRoutes from './routes/search.routes';
import adminRoutes from './routes/admin.routes';
import monitoringRoutes from './routes/monitoring.routes';
import documentsRoutes from './routes/documents.routes';
import { startDocumentProcessingWorkers } from './workers/document-processor.worker';
/**
* Initialize Express application
*/
function createApp(): Express {
const app = express();
// Security middleware
app.use(helmet({
contentSecurityPolicy: false, // Allow inline scripts for admin UI
}));
// CORS
app.use(cors());
// Body parsers
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
// Static files for admin UI and user interface
app.use('/admin', express.static(path.join(__dirname, '..', 'public')));
app.use(express.static(path.join(__dirname, '..', 'public')));
// Health check endpoint
app.get('/health', (_req, res) => {
res.json({ status: 'healthy', timestamp: new Date().toISOString() });
});
// API routes
app.use(`${config.apiPrefix}/upload`, uploadRoutes);
app.use(`${config.apiPrefix}/search`, searchRoutes);
app.use(`${config.apiPrefix}/admin`, adminRoutes);
app.use(`${config.apiPrefix}/monitoring`, monitoringRoutes);
app.use(`${config.apiPrefix}/documents`, documentsRoutes);
// 404 handler
app.use((_req, res) => {
res.status(404).json({ error: 'Not found' });
});
// Error handler
app.use((err: Error, _req: express.Request, res: express.Response, _next: express.NextFunction) => {
logger.error('Unhandled error:', err);
res.status(500).json({
error: 'Internal server error',
message: config.env === 'development' ? err.message : undefined
});
});
return app;
}
/**
* Start the server
*/
async function startServer(): Promise<void> {
try {
// Validate configuration
validateConfig();
// Create app
const app = createApp();
// Start background workers if enabled
if (config.processing.enableWorkers) {
logger.info('Starting background workers...');
await startDocumentProcessingWorkers();
logger.info('Background workers started');
} else {
logger.info('Background workers disabled (ENABLE_WORKERS=false)');
logger.info('Documents will be queued but not processed until workers are enabled');
}
// Start listening
app.listen(config.port, () => {
logger.info(`Server running on port ${config.port}`);
logger.info(`Environment: ${config.env}`);
logger.info(`API prefix: ${config.apiPrefix}`);
});
} catch (error) {
logger.error('Failed to start server:', error);
process.exit(1);
}
}
// Start the server if this file is run directly
if (require.main === module) {
startServer();
}
export { createApp, startServer };