import cors from '@fastify/cors'; import Fastify from 'fastify'; import { ZodError } from 'zod'; import { authPlugin } from './auth/plugin.js'; import { config } from './config.js'; import { pool } from './db/pool.js'; import { authRoutes } from './routes/auth.js'; import { courseRoutes } from './routes/courses.js'; import { manageCourseRoutes } from './routes/manage-courses.js'; export function buildApp() { const app = Fastify({ logger: true }); app.register(cors, { origin: config.FRONTEND_ORIGIN, methods: ['GET', 'POST', 'PATCH', 'DELETE'], }); app.setErrorHandler((error, _request, reply) => { if (error instanceof ZodError) { return reply.code(400).send({ error: 'Invalid request', details: error.flatten() }); } app.log.error(error); return reply.code(500).send({ error: 'Internal server error' }); }); app.get('/api/v1/health', async () => ({ status: 'ok' })); app.get('/api/v1/ready', async (_request, reply) => { try { await pool.query('select 1'); return { status: 'ready' }; } catch { return reply.code(503).send({ status: 'unavailable' }); } }); app.register(authPlugin); app.register(authRoutes, { prefix: '/api/v1/auth' }); app.register(courseRoutes, { prefix: '/api/v1/courses' }); app.register(manageCourseRoutes, { prefix: '/api/v1/manage/courses' }); return app; }