import { REQUEST_ID_HEADER, ulid } from '@lingxi/shared'; import { Module } from '@nestjs/common'; import { LoggerModule } from 'nestjs-pino'; import { SecurityModule } from './common/security/security.module'; 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 { CatalogModule } from './modules/catalog/catalog.module'; import { ClientModule } from './modules/client/client.module'; import { IdentityModule } from './modules/identity/identity.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, SecurityModule, IdentityModule, ClientModule, CatalogModule, PlatformModule, ], }) export class AppModule {}