import Fastify from 'fastify' import { databasePlugin } from './plugins/database.js' import { redisPlugin } from './plugins/redis.js' import { corsPlugin } from './plugins/cors.js' import { errorHandlerPlugin } from './plugins/error-handler.js' import { authPlugin } from './plugins/auth.js' import { devAuthPlugin } from './plugins/dev-auth.js' import { healthRoutes } from './routes/v1/health.js' import { authRoutes } from './routes/v1/auth.js' import { accountRoutes } from './routes/v1/accounts.js' import { inventoryRoutes } from './routes/v1/inventory.js' export async function buildApp() { const app = Fastify({ logger: { level: process.env.LOG_LEVEL ?? 'info', ...(process.env.NODE_ENV === 'development' ? { transport: { target: 'pino-pretty' } } : {}), }, genReqId: () => crypto.randomUUID(), }) // Plugins await app.register(corsPlugin) await app.register(errorHandlerPlugin) await app.register(databasePlugin) await app.register(redisPlugin) // Auth — use JWT if secret is set, otherwise dev bypass if (process.env.JWT_SECRET) { await app.register(authPlugin) } else { await app.register(devAuthPlugin) } // Routes await app.register(healthRoutes, { prefix: '/v1' }) await app.register(authRoutes, { prefix: '/v1' }) await app.register(accountRoutes, { prefix: '/v1' }) await app.register(inventoryRoutes, { prefix: '/v1' }) return app } async function start() { const app = await buildApp() const port = parseInt(process.env.PORT ?? '8000', 10) const host = process.env.HOST ?? '0.0.0.0' try { await app.listen({ port, host }) } catch (err) { app.log.error(err) process.exit(1) } } // Only auto-start when not imported by tests if (process.env.NODE_ENV !== 'test') { start() }