import express from 'express'; import cookieParser from 'cookie-parser'; import cors from 'cors'; import helmet from 'helmet'; import { pinoHttp } from 'pino-http'; import { prisma } from '@vector/db'; import { env } from './env.js'; import { logger } from './lib/logger.js'; import { requestId } from './middleware/request-id.js'; import { requireCsrf } from './middleware/csrf.js'; import { errorHandler } from './middleware/error.js'; import authRoutes from './routes/auth.js'; import userRoutes from './routes/users.js'; import manufacturerRoutes from './routes/manufacturers.js'; import partModelRoutes from './routes/part-models.js'; import siteRoutes from './routes/sites.js'; import roomRoutes from './routes/rooms.js'; import binRoutes from './routes/bins.js'; import partRoutes from './routes/parts.js'; import tagRoutes from './routes/tags.js'; import categoryRoutes from './routes/categories.js'; import hostRoutes from './routes/hosts.js'; import repairRoutes from './routes/repairs.js'; import custodyRoutes from './routes/custody.js'; import savedViewRoutes from './routes/saved-views.js'; import analyticsRoutes from './routes/analytics.js'; import webhookRoutes from './routes/webhooks.js'; import auditRoutes from './routes/audit.js'; export const app = express(); app.disable('x-powered-by'); app.set('trust proxy', 1); app.use(helmet({ contentSecurityPolicy: false, crossOriginResourcePolicy: { policy: 'same-site' } })); app.use( cors({ origin: env.CLIENT_ORIGIN, credentials: true, }), ); app.use(express.json({ limit: '1mb' })); app.use(cookieParser()); app.use(requestId); app.use( pinoHttp({ logger, customProps: (req) => ({ requestId: (req as express.Request).requestId }), customLogLevel: (_req, res, err) => { if (err || res.statusCode >= 500) return 'error'; if (res.statusCode >= 400) return 'warn'; return 'info'; }, }), ); app.get('/healthz', (_req, res) => { res.json({ status: 'ok' }); }); app.get('/readyz', async (_req, res) => { try { await prisma.$queryRaw`SELECT 1`; res.json({ status: 'ok', db: 'ok' }); } catch { res.status(503).json({ status: 'error', db: 'unreachable' }); } }); app.use('/api/auth', authRoutes); app.use('/api', requireCsrf); app.use('/api/users', userRoutes); app.use('/api/manufacturers', manufacturerRoutes); app.use('/api/part-models', partModelRoutes); app.use('/api/sites', siteRoutes); app.use('/api/rooms', roomRoutes); app.use('/api/bins', binRoutes); app.use('/api/parts', partRoutes); app.use('/api/tags', tagRoutes); app.use('/api/categories', categoryRoutes); app.use('/api/hosts', hostRoutes); app.use('/api/repairs', repairRoutes); app.use('/api/custody', custodyRoutes); app.use('/api/saved-views', savedViewRoutes); app.use('/api/analytics', analyticsRoutes); app.use('/api/admin/webhooks', webhookRoutes); app.use('/api/admin/audit', auditRoutes); app.use(errorHandler);