import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core'; import { AuthModule } from './auth/auth.module'; import { JwtAuthGuard } from './auth/guards/jwt-auth.guard'; import { RolesGuard } from './auth/guards/roles.guard'; import { ForcePasswordChangeInterceptor } from './auth/interceptors/force-password-change.interceptor'; import { HealthModule } from './health/health.module'; import { LdapModule } from './ldap/ldap.module'; import { MailModule } from './mail/mail.module'; import { ModuleRegistryModule } from './module-registry/module-registry.module'; import { PrismaModule } from './prisma/prisma.module'; import { TenantMiddleware } from './tenant/tenant.middleware'; import { TenantModule } from './tenant/tenant.module'; import { UserModule } from './user/user.module'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true }), PrismaModule, AuthModule, UserModule, TenantModule, HealthModule, MailModule, LdapModule, ModuleRegistryModule, ], providers: [ // Global JWT guard: all routes require auth unless @Public() { provide: APP_GUARD, useClass: JwtAuthGuard, }, // Global roles guard: checks @Roles() decorator { provide: APP_GUARD, useClass: RolesGuard, }, // Global interceptor: forces password change if mustChangePassword=true (D-06 / Pitfall 5) { provide: APP_INTERCEPTOR, useClass: ForcePasswordChangeInterceptor, }, ], }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { // TenantMiddleware runs AFTER AuthGuard (guards run first in NestJS pipeline) consumer.apply(TenantMiddleware).forRoutes('*'); } }