import Fastify from 'fastify'; import cors from '@fastify/cors'; import * as path from 'path'; import * as fs from 'fs'; import { getFastifyLoggerConfig } from './utils/logger.js'; // Import routes {{ROUTE_IMPORTS}} // Import custom routes (statically registered at generation time) {{CUSTOM_ROUTE_IMPORTS}} // Import plugins import prismaPlugin from './plugins/prisma.js'; import swaggerPlugin from './plugins/swagger.js'; async function start() { const fastify = Fastify({ logger: getFastifyLoggerConfig(), requestIdLogLabel: 'reqId', genReqId: () => { // Generate unique request ID for correlation return `req-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; }, }); // Log startup fastify.log.info({ node_env: process.env.NODE_ENV || 'development', node_version: process.version, }, 'Starting DataBridge API server...'); // Register plugins await fastify.register(cors, { origin: process.env.CORS_ORIGIN || '*', credentials: true, }); await fastify.register(prismaPlugin); await fastify.register(swaggerPlugin); // Register routes {{ROUTE_REGISTRATIONS}} // Register custom routes (statically imported) {{CUSTOM_ROUTE_REGISTRATIONS}} // Auto-register custom routes added after generation (runtime fallback) const customRoutesDir = path.join(__dirname, 'routes', 'custom'); const registeredCustomRoutes = new Set([{{CUSTOM_ROUTE_FILES}}]); if (fs.existsSync(customRoutesDir)) { const customFiles = fs.readdirSync(customRoutesDir).filter(f => f.endsWith('.ts') || f.endsWith('.js')); for (const file of customFiles) { // Skip files already statically registered above const baseName = file.replace(/\.(ts|js)$/, ''); if (registeredCustomRoutes.has(baseName)) continue; try { const routePath = `./routes/custom/${file}`; const route = await import(routePath); await fastify.register(route.default || route); fastify.log.info(`Registered custom route: ${file}`); } catch (error) { fastify.log.error( { err: error instanceof Error ? error.message : String(error), file }, `Failed to register custom route: ${file}`, ); } } } // Health check endpoint fastify.get('/health', async (request, reply) => { const health: any = { status: 'ok', timestamp: new Date().toISOString(), uptime: process.uptime(), environment: process.env.NODE_ENV || 'development', version: process.env.npm_package_version || '1.0.0', }; // Check database connection try { await (fastify as any).prisma.$connect(); health.database = 'connected'; } catch (error) { health.database = 'disconnected'; health.status = 'degraded'; } return reply.send(health); }); // Metrics endpoint (for monitoring) fastify.get('/metrics', async () => { return { memory: process.memoryUsage(), uptime: process.uptime(), timestamp: new Date().toISOString(), }; }); // OpenAPI spec endpoint (for tools like Postman, Dredd) fastify.get('/openapi.json', async (request, reply) => { const fs = await import('fs'); const path = await import('path'); const specPath = path.join(__dirname, 'openapi.json'); try { const spec = fs.readFileSync(specPath, 'utf-8'); reply.type('application/json').send(spec); } catch (error) { reply.status(404).send({ error: 'OpenAPI spec not found' }); } }); // Graceful shutdown const signals = ['SIGTERM', 'SIGINT']; for (const signal of signals) { process.on(signal, async () => { fastify.log.info(`Received ${signal}, starting graceful shutdown...`); try { await fastify.close(); fastify.log.info('Server closed gracefully'); process.exit(0); } catch (error) { fastify.log.error(error, 'Error during shutdown'); process.exit(1); } }); } // Start server const port = parseInt(process.env.API_PORT || '{{PORT}}', 10); const host = process.env.API_HOST || '0.0.0.0'; try { await fastify.listen({ port, host }); fastify.log.info({ port, host, }, 'āœ… DataBridge API Server running'); console.log(`\nāœ… DataBridge API Server running on http://localhost:${port}\n`); console.log('Available routes:'); console.log(' GET /health'); console.log(' GET /metrics'); console.log(' GET /docs (Swagger UI - Interactive API documentation)'); console.log(' GET /openapi.json (OpenAPI 3.0 specification)'); {{ROUTE_LIST}} {{CUSTOM_ROUTE_LIST}} console.log(''); } catch (error) { fastify.log.error(error, 'Failed to start server'); process.exit(1); } } start();