MailService renders transactional mails (verify-email, reset-password) from the new de/en `mails` i18n namespace — text plus minimal HTML with escaped interpolation — and enqueues them into mail_outbox. MailWorker delivers pending rows every 15s through an injectable transport (nodemailer; faked in tests) with quadratic backoff and a permanent FAILED state after five attempts, logged as a warning. SMTP_* and APP_BASE_URL join the environment schema with defaults matching the new Mailpit container in the dev overlay. Closes #12 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
39 lines
1.4 KiB
TypeScript
39 lines
1.4 KiB
TypeScript
import { Module } from '@nestjs/common';
|
|
import { APP_FILTER } from '@nestjs/core';
|
|
import { LoggerModule } from 'nestjs-pino';
|
|
|
|
import { ApiExceptionFilter } from './common/api-exception.filter';
|
|
import { AppConfig } from './config/app-config.service';
|
|
import { ConfigModule } from './config/config.module';
|
|
import { HealthModule } from './health/health.module';
|
|
import { MailModule } from './mail/mail.module';
|
|
import { PrismaModule } from './prisma/prisma.module';
|
|
import { RateLimitModule } from './rate-limit/rate-limit.module';
|
|
import { UsersModule } from './users/users.module';
|
|
|
|
@Module({
|
|
imports: [
|
|
ConfigModule,
|
|
PrismaModule,
|
|
RateLimitModule,
|
|
MailModule,
|
|
UsersModule,
|
|
LoggerModule.forRootAsync({
|
|
inject: [AppConfig],
|
|
useFactory: (config: AppConfig) => ({
|
|
pinoHttp: {
|
|
level: config.env.LOG_LEVEL,
|
|
// Human-readable logs in local development, JSON everywhere else.
|
|
transport: config.env.NODE_ENV === 'development' ? { target: 'pino-pretty' } : undefined,
|
|
autoLogging: config.env.NODE_ENV !== 'test',
|
|
// Request bodies are never logged (operations.md logging rules).
|
|
redact: { paths: ['req.headers.authorization', 'req.headers.cookie'], remove: true },
|
|
},
|
|
}),
|
|
}),
|
|
HealthModule,
|
|
],
|
|
providers: [{ provide: APP_FILTER, useClass: ApiExceptionFilter }],
|
|
})
|
|
export class AppModule {}
|