Replaced duplicated server setup code with createServiceApp() factory: - platform-service: 91 → 39 lines - billing-service: 105 → 51 lines (keeps service-specific internal key auth) - growth-service: 83 → 33 lines - tracker-service: 88 → 36 lines Enhanced fastify-core with optional Swagger + Prometheus metrics support. Total reduction: ~208 lines of duplicated boilerplate eliminated. All 246 tests pass.
51 lines
1.9 KiB
TypeScript
51 lines
1.9 KiB
TypeScript
/**
|
|
* 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 });
|