- GET /api/diagnostics/flags — returns all feature flags - GET /api/diagnostics/telemetry — returns buffered telemetry events - POST /api/diagnostics/telemetry/flush — flush telemetry buffer - No auth required (diagnostics endpoints)
61 lines
2.5 KiB
TypeScript
61 lines
2.5 KiB
TypeScript
/**
|
|
* ChronoMind Backend — Fastify server entry point.
|
|
*
|
|
* Product-specific service for timers, routines, households, shared timers.
|
|
* Common platform features (auth, billing, flags, etc.) come from platform-service.
|
|
* Port: 4011 (configurable via PORT env var).
|
|
*/
|
|
|
|
import { createServiceApp, registerOptionalJwtContext, startService } from '@bytelyst/fastify-core';
|
|
import { timerRoutes } from './modules/timers/routes.js';
|
|
import { routineRoutes } from './modules/routines/routes.js';
|
|
import { householdRoutes } from './modules/households/routes.js';
|
|
import { sharedTimerRoutes } from './modules/shared-timers/routes.js';
|
|
import { webhookRoutes } from './modules/webhooks/routes.js';
|
|
import { initCosmosIfNeeded } from './lib/cosmos-init.js';
|
|
import { initDatastore } from './lib/datastore.js';
|
|
import { config } from './lib/config.js';
|
|
import { getAllFlags } from './lib/feature-flags.js';
|
|
import { getBufferedEvents, flushEvents } from './lib/telemetry.js';
|
|
|
|
import { jwtVerify } from 'jose';
|
|
import type { JwtPayload } from './lib/request-context.js';
|
|
|
|
const jwtSecret = new TextEncoder().encode(config.JWT_SECRET);
|
|
|
|
await initCosmosIfNeeded();
|
|
initDatastore();
|
|
|
|
const app = await createServiceApp({
|
|
name: 'chronomind-backend',
|
|
version: '0.1.0',
|
|
description: 'ChronoMind product-specific backend — timers, routines, households, shared timers, webhooks',
|
|
corsOrigin: config.CORS_ORIGIN,
|
|
swagger: {
|
|
title: 'ChronoMind Backend',
|
|
description: 'Timers, routines, households, shared timers, webhooks',
|
|
port: config.PORT,
|
|
},
|
|
metrics: true,
|
|
});
|
|
|
|
await registerOptionalJwtContext(app, {
|
|
verifyToken: async (token: string) => {
|
|
const { payload } = await jwtVerify(token, jwtSecret, { issuer: 'bytelyst-platform' });
|
|
return payload as unknown as JwtPayload;
|
|
},
|
|
});
|
|
|
|
await app.register(timerRoutes, { prefix: '/api' });
|
|
await app.register(routineRoutes, { prefix: '/api' });
|
|
await app.register(householdRoutes, { prefix: '/api' });
|
|
await app.register(sharedTimerRoutes, { prefix: '/api' });
|
|
await app.register(webhookRoutes, { prefix: '/api' });
|
|
|
|
// ── Diagnostics routes (no auth) ────────────────────────────────
|
|
app.get('/api/diagnostics/flags', async () => getAllFlags());
|
|
app.get('/api/diagnostics/telemetry', async () => ({ events: getBufferedEvents() }));
|
|
app.post('/api/diagnostics/telemetry/flush', async () => ({ flushed: flushEvents().length }));
|
|
|
|
await startService(app, { port: config.PORT, host: config.HOST });
|