import { Module } from '@nestjs/common'; import { APP_FILTER } from '@nestjs/core'; import { LoggerModule } from 'nestjs-pino'; import { AdminModule } from './admin/admin.module'; import { AuditModule } from './audit/audit.module'; import { AuthModule } from './auth/auth.module'; import { ApiExceptionFilter } from './common/api-exception.filter'; import { CommentsModule } from './comments/comments.module'; import { CompactionModule } from './compaction/compaction.module'; import { AppConfig } from './config/app-config.service'; import { ConfigModule } from './config/config.module'; import { FilesModule } from './files/files.module'; import { GrantsModule } from './grants/grants.module'; import { HealthModule } from './health/health.module'; import { ImportExportModule } from './import-export/import-export.module'; import { LabelsModule } from './labels/labels.module'; import { LegalModule } from './legal/legal.module'; import { LinksModule } from './links/links.module'; import { MailModule } from './mail/mail.module'; import { MembersModule } from './members/members.module'; import { PagesModule } from './pages/pages.module'; import { PermissionsModule } from './permissions/permissions.module'; import { PluginsModule } from './plugins/plugins.module'; import { PondsModule } from './ponds/ponds.module'; import { PrismaModule } from './prisma/prisma.module'; import { PublicModule } from './public/public.module'; import { RateLimitModule } from './rate-limit/rate-limit.module'; import { SearchModule } from './search/search.module'; import { SettingsModule } from './settings/settings.module'; import { SetupModule } from './setup/setup.module'; import { TrashModule } from './trash/trash.module'; import { UsersModule } from './users/users.module'; import { NotificationsModule } from './notifications/notifications.module'; import { WatchesModule } from './watches/watches.module'; import { VersionsModule } from './versions/versions.module'; @Module({ imports: [ ConfigModule, PrismaModule, AuditModule, RateLimitModule, MailModule, SettingsModule, // Before AuthModule: global guards run in registration order, and the // setup gate must win over AuthGuard's 401 while setup is pending. SetupModule, UsersModule, PermissionsModule, PondsModule, PagesModule, CommentsModule, WatchesModule, NotificationsModule, FilesModule, TrashModule, CompactionModule, VersionsModule, LabelsModule, LegalModule, LinksModule, SearchModule, GrantsModule, MembersModule, PublicModule, ImportExportModule, PluginsModule, AuthModule, AdminModule, 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 {}