25 lines
2.2 KiB
TypeScript
25 lines
2.2 KiB
TypeScript
import Fastify from 'fastify';
|
|
import helmet from '@fastify/helmet';
|
|
import sensible from '@fastify/sensible';
|
|
import swagger from '@fastify/swagger';
|
|
import type { AppConfig } from './config.js';
|
|
import { Database } from './infrastructure/database.js';
|
|
import { newUlid } from './core/ids.js';
|
|
|
|
export interface BuildAppOptions { config: AppConfig; database?: Database }
|
|
|
|
export async function buildApp({ config, database = new Database(config.DATABASE_URL) }: BuildAppOptions) {
|
|
const app = Fastify({ logger: { level: config.LOG_LEVEL }, genReqId: (request) => request.headers['x-correlation-id']?.toString() ?? newUlid() });
|
|
await app.register(helmet);
|
|
await app.register(sensible);
|
|
await app.register(swagger, { openapi: { info: { title: 'Krona Staff API', version: '0.1.0' }, servers: [{ url: '/api/v1/staff' }] } });
|
|
|
|
app.get('/live', { schema: { tags: ['Operations'], response: { 200: { type: 'object', required: ['status'], properties: { status: { type: 'string', const: 'ok' } } } } } }, async () => ({ status: 'ok' }));
|
|
app.get('/ready', { schema: { tags: ['Operations'], response: { 200: { type: 'object', required: ['status'], properties: { status: { type: 'string', const: 'ready' } } } } } }, async () => { await database.ping(); return { status: 'ready' }; });
|
|
app.get('/version', { schema: { tags: ['Operations'], response: { 200: { type: 'object', required: ['name', 'version', 'mode'], properties: { name: { type: 'string' }, version: { type: 'string' }, mode: { type: 'string' } } } } } }, async () => ({ name: 'krona-staff', version: '0.1.0', mode: config.STAFF_RUNTIME_MODE }));
|
|
app.get('/openapi.json', async () => app.swagger());
|
|
app.get('/', async (_request, reply) => reply.type('text/html').send('<!doctype html><html lang="ru"><meta charset="utf-8"><title>Krona Staff</title><body><main><h1>Krona Staff</h1><p>Архитектурная основа модуля. Предметные функции ожидают требований владельца.</p><nav><a href="/openapi.json">OpenAPI</a> · <a href="/live">Live</a> · <a href="/ready">Ready</a> · <a href="/version">Version</a></nav></main></body></html>'));
|
|
|
|
app.addHook('onClose', async () => database.close());
|
|
return app;
|
|
}
|