/** * Billing & Entitlement Service — Fastify server entry point. * * Modules: subscriptions, usage, plans, licenses. * Port: 4002 (configurable via PORT env var). */ import { createServiceApp, startService } from '@bytelyst/fastify-core'; import { subscriptionRoutes } from './modules/subscriptions/routes.js'; import { usageRoutes } from './modules/usage/routes.js'; import { planRoutes } from './modules/plans/routes.js'; import { licenseRoutes } from './modules/licenses/routes.js'; import { stripeRoutes } from './modules/stripe/routes.js'; import { config } from './lib/config.js'; const app = await createServiceApp({ name: 'billing-service', version: '0.1.0', description: 'Subscriptions, payments, usage, licenses, plans, Stripe', corsOrigin: config.CORS_ORIGIN, swagger: { title: 'Billing & Entitlement Service', description: 'Subscriptions, payments, usage, licenses, plans, Stripe', port: config.PORT, }, metrics: true, }); // Internal API key auth (service-specific — skip health, webhook, and when key not configured) const INTERNAL_KEY = config.BILLING_INTERNAL_KEY; if (INTERNAL_KEY) { app.addHook('onRequest', async (req, reply) => { const path = req.url; // Skip auth for health check and Stripe webhook (has its own signature verification) if (path === '/health' || path.includes('/stripe/webhook')) return; const key = req.headers['x-internal-key']; if (key !== INTERNAL_KEY) { reply.code(401).send({ error: 'Unauthorized — missing or invalid X-Internal-Key' }); } }); } // Register route modules await app.register(subscriptionRoutes, { prefix: '/api' }); await app.register(usageRoutes, { prefix: '/api' }); await app.register(planRoutes, { prefix: '/api' }); await app.register(licenseRoutes, { prefix: '/api' }); await app.register(stripeRoutes, { prefix: '/api' }); await startService(app, { port: config.PORT, host: config.HOST });