import Fastify from 'fastify'; import cors from '@fastify/cors'; import jwt from '@fastify/jwt'; import multipart from '@fastify/multipart'; import cookie from '@fastify/cookie'; import session from '@fastify/session'; import { authenticate } from './middleware/auth.middleware.js'; import { env, validateEnv } from './config/env.js'; // Import routes import authRoute from './routes/auth.js'; import eventsRoute from './routes/events.js'; import galleryRoute from './routes/gallery.js'; import contentRoute from './routes/content.js'; import settingsRoute from './routes/settings.js'; import publishRoute from './routes/publish.js'; // Validate environment variables try { validateEnv(); } catch (error) { console.error('Environment validation failed:', error); process.exit(1); } const fastify = Fastify({ logger: { level: env.NODE_ENV === 'production' ? 'info' : 'debug', transport: env.NODE_ENV === 'development' ? { target: 'pino-pretty', options: { translateTime: 'HH:MM:ss Z', ignore: 'pid,hostname', }, } : undefined, }, }); // Register plugins fastify.register(cors, { origin: env.CORS_ORIGIN, credentials: true, }); fastify.register(cookie); fastify.register(session, { secret: env.SESSION_SECRET, cookie: { secure: env.NODE_ENV === 'production', httpOnly: true, maxAge: 600000, // 10 minutes (only needed for OAuth flow) }, }); fastify.register(jwt, { secret: env.JWT_SECRET, }); fastify.register(multipart, { limits: { fileSize: env.MAX_FILE_SIZE, }, }); // Decorate fastify with authenticate method fastify.decorate('authenticate', authenticate); // Register routes fastify.register(authRoute, { prefix: '/api' }); fastify.register(eventsRoute, { prefix: '/api' }); fastify.register(galleryRoute, { prefix: '/api' }); fastify.register(contentRoute, { prefix: '/api' }); fastify.register(settingsRoute, { prefix: '/api' }); fastify.register(publishRoute, { prefix: '/api' }); // Health check fastify.get('/health', async () => { return { status: 'ok', timestamp: new Date().toISOString(), environment: env.NODE_ENV, }; }); // Root endpoint fastify.get('/', async () => { return { name: 'Gallus Pub CMS Backend', version: '1.0.0', status: 'running', }; }); // Error handler fastify.setErrorHandler((error, request, reply) => { fastify.log.error(error); reply.status(error.statusCode || 500).send({ error: error.message || 'Internal Server Error', statusCode: error.statusCode || 500, }); }); // Start server const start = async () => { try { await fastify.listen({ port: env.PORT, host: '0.0.0.0' }); console.log(`🚀 Server listening on port ${env.PORT}`); console.log(`📝 Environment: ${env.NODE_ENV}`); console.log(`🔐 CORS Origin: ${env.CORS_ORIGIN}`); } catch (err) { fastify.log.error(err); process.exit(1); } }; start();