Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 1 addition & 73 deletions backend/src/app.ts
Original file line number Diff line number Diff line change
@@ -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;
Loading