Files
lingxi/apps/api/src/app.module.ts
T
Stev_Wang 23067edb8f feat(api): 搭建 API 与 Worker 骨架及契约基线
NestJS 11 + Fastify 统一错误体与 trace_id,/health 真实探活 DB/Redis,OpenAPI 3.1 契约含 20 个错误码;shared 包提供错误码、权限点、ULID、分页与通用 schema;worker 完成队列进程骨架。
2026-11-02 17:20:46 +08:00

52 lines
1.8 KiB
TypeScript

import { REQUEST_ID_HEADER, ulid } from '@lingxi/shared';
import { Module } from '@nestjs/common';
import { LoggerModule } from 'nestjs-pino';
import { APP_CONFIG, AppConfigModule } from './config/config.module';
import type { AppConfig } from './config/env';
import { PrismaModule } from './infra/prisma/prisma.module';
import { RedisModule } from './infra/redis/redis.module';
import { PlatformModule } from './modules/platform/platform.module';
@Module({
imports: [
AppConfigModule,
LoggerModule.forRootAsync({
imports: [AppConfigModule],
inject: [APP_CONFIG],
useFactory: (config: AppConfig) => ({
pinoHttp: {
level: config.logLevel,
genReqId: (request, response) => {
const header = request.headers[REQUEST_ID_HEADER];
const existing = Array.isArray(header) ? header[0] : header;
const traceId = typeof existing === 'string' && existing.length > 0 ? existing : ulid();
response.setHeader(REQUEST_ID_HEADER, traceId);
return traceId;
},
customProps: (request) => ({ trace_id: request.id }),
redact: {
paths: ['req.headers.authorization', 'req.headers.cookie', 'res.headers["set-cookie"]'],
censor: '[redacted]',
},
autoLogging: {
ignore: (request) => request.url === '/health',
},
...(config.nodeEnv === 'development' && process.env.VITEST === undefined
? {
transport: {
target: 'pino-pretty',
options: { singleLine: true, translateTime: 'SYS:HH:MM:ss.l' },
},
}
: {}),
},
}),
}),
PrismaModule,
RedisModule,
PlatformModule,
],
})
export class AppModule {}