import Fastify, { FastifyRequest, FastifyReply } from 'fastify' import jwt from '@fastify/jwt' import cookie from '@fastify/cookie' import cors from '@fastify/cors' import helmet from '@fastify/helmet' import rateLimit from '@fastify/rate-limit' import { config } from './config' import './types' // side-effect: augments fastify types import wsRoutes from './routes/ws' import authRoutes from './routes/auth' import hotelsRoutes from './routes/hotels' import roomsRoutes from './routes/rooms' import bookingsRoutes from './routes/bookings' import housekeepingRoutes from './routes/housekeeping' import channelsRoutes from './routes/channels' import usersRoutes from './routes/users' export async function buildApp() { const fastify = Fastify({ logger: { level: config.nodeEnv === 'production' ? 'warn' : 'info', ...(config.nodeEnv !== 'production' && { transport: { target: 'pino-pretty', options: { colorize: true } }, }), }, }) // ── Security ─────────────────────────────────────────────────────────────── await fastify.register(helmet, { contentSecurityPolicy: false }) await fastify.register(cors, { origin: config.cors.origins, credentials: true, methods: ['GET', 'POST', 'PATCH', 'DELETE', 'OPTIONS'], }) await fastify.register(rateLimit, { max: 200, timeWindow: '1 minute', }) // ── Cookies & JWT ────────────────────────────────────────────────────────── await fastify.register(cookie) await fastify.register(jwt, { secret: config.jwt.secret, }) // Authenticate decorator used as onRequest hook in routes fastify.decorate( 'authenticate', async (request: FastifyRequest, reply: FastifyReply) => { try { await request.jwtVerify() } catch (err) { reply.code(401).send({ error: 'Unauthorized' }) } }, ) // ── Health check ─────────────────────────────────────────────────────────── fastify.get('/health', async () => ({ status: 'ok', ts: new Date().toISOString() })) // ── Routes ───────────────────────────────────────────────────────────────── await fastify.register(wsRoutes) await fastify.register(authRoutes) await fastify.register(hotelsRoutes) await fastify.register(roomsRoutes) await fastify.register(bookingsRoutes) await fastify.register(housekeepingRoutes) await fastify.register(channelsRoutes) await fastify.register(usersRoutes) return fastify }