dependencies Legend  Declarations  Module  Bootstrap  Providers  Exports cluster_AppModule cluster_AppModule_imports cluster_AppModule_providers AiModule AiModule AppModule AppModule AiModule->AppModule AlertsModule AlertsModule AlertsModule->AppModule AnalyticsModule AnalyticsModule AnalyticsModule->AppModule AuthModule AuthModule AuthModule->AppModule BillingModule BillingModule BillingModule->AppModule ClientPortalModule ClientPortalModule ClientPortalModule->AppModule ClientsModule ClientsModule ClientsModule->AppModule DriversModule DriversModule DriversModule->AppModule HealthModule HealthModule HealthModule->AppModule LanesModule LanesModule LanesModule->AppModule LoadingBaysModule LoadingBaysModule LoadingBaysModule->AppModule MessagesModule MessagesModule MessagesModule->AppModule NotificationModule NotificationModule NotificationModule->AppModule OrdersModule OrdersModule OrdersModule->AppModule PrismaModule PrismaModule PrismaModule->AppModule StorageModule StorageModule StorageModule->AppModule TrackingModule TrackingModule TrackingModule->AppModule TransportersModule TransportersModule TransportersModule->AppModule TripsModule TripsModule TripsModule->AppModule UsersModule UsersModule UsersModule->AppModule VehiclesModule VehiclesModule VehiclesModule->AppModule WebhookModule WebhookModule WebhookModule->AppModule ZonesModule ZonesModule ZonesModule->AppModule AuditLogInterceptor AuditLogInterceptor AuditLogInterceptor->AppModule TenantContextInterceptor TenantContextInterceptor TenantContextInterceptor->AppModule TenantHeaderInterceptor TenantHeaderInterceptor TenantHeaderInterceptor->AppModule TenantLookupService TenantLookupService TenantLookupService->AppModule
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { LoggerModule } from 'nestjs-pino';
import { ScheduleModule } from '@nestjs/schedule';
import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
import { APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
import { AuditLogInterceptor } from './common/interceptors/audit-log.interceptor';
import { TenantContextInterceptor } from './common/interceptors/tenant-context.interceptor';
import { TenantHeaderInterceptor } from './common/interceptors/tenant-header.interceptor';
import { TenantLookupService } from './common/services/tenant-lookup.service';
import configuration from './config/configuration';
import { PrismaModule } from './prisma/prisma.module';
import { AuthModule } from './auth/auth.module';
import { UsersModule } from './users/users.module';
import { ClientsModule } from './clients/clients.module';
import { OrdersModule } from './orders/orders.module';
import { VehiclesModule } from './vehicles/vehicles.module';
import { DriversModule } from './drivers/drivers.module';
import { TripsModule } from './trips/trips.module';
import { AlertsModule } from './alerts/alerts.module';
import { AnalyticsModule } from './analytics/analytics.module';
import { TrackingModule } from './tracking/tracking.module';
import { WebhookModule } from './webhooks/webhook.module';
import { HealthModule } from './health/health.module';
import { NotificationModule } from './notifications/notification.module';
import { StorageModule } from './storage/storage.module';
import { AiModule } from './ai/ai.module';
import { BillingModule } from './billing/billing.module';
import { TransportersModule } from './transporters/transporters.module';
import { ZonesModule } from './zones/zones.module';
import { LanesModule } from './lanes/lanes.module';
import { LoadingBaysModule } from './loading-bays/loading-bays.module';
import { MessagesModule } from './messages/messages.module';
import { ClientPortalModule } from './client-portal/client-portal.module';

@Module({
  imports: [
    // Global configuration from .env
    ConfigModule.forRoot({
      isGlobal: true,
      envFilePath: '../../.env',
      load: [configuration],
    }),

    // Pino structured logging
    LoggerModule.forRoot({
      pinoHttp: {
        transport:
          process.env.NODE_ENV !== 'production'
            ? { target: 'pino-pretty', options: { colorize: true } }
            : undefined,
        level: process.env.NODE_ENV !== 'production' ? 'debug' : 'info',
      },
    }),

    // Rate limiting
    ThrottlerModule.forRoot([
      { name: 'short', ttl: 1000, limit: 3 },    // 3 requests per second
      { name: 'medium', ttl: 10000, limit: 20 },  // 20 per 10 seconds
      { name: 'long', ttl: 60000, limit: 100 },   // 100 per minute
    ]),

    // Cron / scheduled tasks
    ScheduleModule.forRoot(),

    // Core modules
    PrismaModule,
    NotificationModule,
    AiModule,
    StorageModule,

    // Health check (no auth required)
    HealthModule,

    // Feature modules
    AuthModule,
    UsersModule,
    ClientsModule,
    OrdersModule,
    VehiclesModule,
    DriversModule,
    TripsModule,
    AlertsModule,
    AnalyticsModule,
    TrackingModule,
    WebhookModule,
    BillingModule,
    TransportersModule,
    ZonesModule,
    LanesModule,
    LoadingBaysModule,
    MessagesModule,
    ClientPortalModule,
  ],
  controllers: [],
  providers: [
    { provide: APP_GUARD, useClass: ThrottlerGuard },
    TenantLookupService,
    // Order matters: NestJS runs APP_INTERCEPTOR providers in registration
    // order, with the FIRST registered being the OUTERMOST wrapper.
    //
    // 1) TenantHeaderInterceptor — runs first so a 403 mismatch aborts
    //    before any RLS tx is opened. Guards have already run by this point,
    //    so req.user is set for JWT-protected routes.
    // 2) TenantContextInterceptor — opens the $transaction and SETs the
    //    app.current_org_id GUC for RLS.
    // 3) AuditLogInterceptor — logs the request inside the tenant tx.
    { provide: APP_INTERCEPTOR, useClass: TenantHeaderInterceptor },
    { provide: APP_INTERCEPTOR, useClass: TenantContextInterceptor },
    { provide: APP_INTERCEPTOR, useClass: AuditLogInterceptor },
  ],
})
export class AppModule {}

results matching ""

    No results matching ""