diff --git a/backend/src/app.ts b/backend/src/app.ts index cf86f63..d31cef5 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -1,73 +1 @@ -import express from 'express'; -import cors from 'cors'; -import helmet from 'helmet'; -import rateLimit from 'express-rate-limit'; -import { env } from './config/env'; -import { errorHandler } from './middleware/errorHandler'; -import { latencyMiddleware, getLatencyStats } from './middleware/latency'; -import { runMigrations } from './db/migrate'; - -import healthRouter from './routes/health'; -import authRouter from './routes/auth'; -import sourcesRouter from './routes/sources'; -import analyticsRouter from './routes/analytics'; -import alertsRouter from './routes/alerts'; -import pipelineRouter from './pipeline/routes'; - -const app = express(); - -// ── Security middleware -app.use(helmet()); -app.use(cors({ origin: env.CORS_ORIGINS, credentials: true })); -app.use(express.json({ limit: '2mb' })); - -// Request ID -app.use((req, _res, next) => { - (req as any).id = crypto.randomUUID(); - next(); -}); - -// Global latency tracking -app.use(latencyMiddleware(500)); - -// Rate limiter on auth endpoints -const authLimiter = rateLimit({ - windowMs: env.RATE_LIMIT_WINDOW_MS, - max: env.RATE_LIMIT_MAX_REQUESTS, - standardHeaders: true, - legacyHeaders: false, -}); - -// ── Routes -app.use('/api', healthRouter); -app.use('/api/auth', authLimiter, authRouter); -app.use('/api/sources', sourcesRouter); -app.use('/api/analytics', analyticsRouter); -app.use('/api/alerts', alertsRouter); - -// Pipeline routes (ingestion, heatmap, trends, summary) -app.use('/', pipelineRouter); - -// ── Metrics endpoint (latency stats + pipeline metrics) -app.get('/api/metrics', (_req, res) => { - res.json({ - latency: getLatencyStats(), - timestamp: new Date().toISOString(), - }); -}); - -// ── Error handler (must be last) -app.use(errorHandler); - -// ── Boot -if (require.main === module) { - runMigrations() - .then(() => { - app.listen(env.PORT, () => { - console.log(`\u2705 CIVWATCH backend running on :${env.PORT} [${env.NODE_ENV}]`); - }); - }) - .catch((e) => { console.error('Migration failed', e); process.exit(1); }); -} - -export default app; +import express from 'express';\nimport cors from 'cors';\nimport helmet from 'helmet';\nimport rateLimit from 'express-rate-limit';\nimport { env } from './config/env';\nimport { errorHandler } from './middleware/errorHandler';\nimport { latencyMiddleware, getLatencyStats } from './middleware/latency';\nimport { runMigrations } from './db/migrate';\n\nimport healthRouter from './routes/health';\nimport authRouter from './routes/auth';\nimport sourcesRouter from './routes/sources';\nimport analyticsRouter from './routes/analytics';\nimport alertsRouter from './routes/alerts';\nimport pipelineRouter from './pipeline/routes';\nimport ingestRouter from './routes/ingest';\nimport anomaliesRouter from './routes/anomalies';\n\nconst app = express();\n\n// ── Security middleware\napp.use(helmet());\napp.use(cors({ origin: env.CORS_ORIGINS, credentials: true }));\napp.use(express.json({ limit: '2mb' }));\n\n// Request ID\napp.use((req, _res, next) => {\n (req as any).id = crypto.randomUUID();\n next();\n});\n\n// Global latency tracking\napp.use(latencyMiddleware(500));\n\n// Rate limiter on auth endpoints\nconst authLimiter = rateLimit({\n windowMs: env.RATE_LIMIT_WINDOW_MS,\n max: env.RATE_LIMIT_MAX_REQUESTS,\n standardHeaders: true,\n legacyHeaders: false,\n});\n\n// ── Routes\napp.use('/api', healthRouter);\napp.use('/api/auth', authLimiter, authRouter);\napp.use('/api/sources', sourcesRouter);\napp.use('/api/analytics', analyticsRouter);\napp.use('/api/alerts', alertsRouter);\napp.use('/api/ingest', ingestRouter);\napp.use('/api/anomalies', anomaliesRouter);\n\n// Pipeline routes (ingestion, heatmap, trends, summary)\napp.use('/', pipelineRouter);\n\n// ── Metrics endpoint (latency stats + pipeline metrics)\napp.get('/api/metrics', (_req, res) => {\n res.json({\n latency: getLatencyStats(),\n timestamp: new Date().toISOString(),\n });\n});\n\n// ── Error handler (must be last)\napp.use(errorHandler);\n\n// ── Boot\nif (require.main === module) {\n runMigrations()\n .then(() => {\n app.listen(env.PORT, () => {\n console.log(`✅ CIVWATCH backend running on :${env.PORT} [${env.NODE_ENV}]`);\n });\n })\n .catch((e) => {\n console.error('Migration failed', e);\n process.exit(1);\n });\n}\n\nexport default app;