import { Logger, Module, OnApplicationBootstrap } from "@nestjs/common"; import { APP_FILTER } from "@nestjs/core"; import { ConfigModule, ConfigService } from "@nestjs/config"; import { ScheduleModule } from "@nestjs/schedule"; import { EventEmitterModule } from "@nestjs/event-emitter"; import { TypeOrmModule, TypeOrmModuleOptions } from "@nestjs/typeorm"; import { IamBaselineSeeder, IamSeedModule } from "@edr/iam-seed"; import { IamModule as TriaIamModule } from "@tria-plc/iamapi-common/iam.module"; import { SharedAuthModule } from "@tria-plc/api-common/modules/auth/shared-auth.module"; import { EDR_PASSENGER_APPLICATION, EDR_PASSENGER_PERMISSIONS, } from "./seed/edr-passenger.seed"; import { EdrPassengerOrgSeeder } from "./seed/edr-passenger-org.seeder"; import { PassengerStaffUsersSeeder } from "./seed/passenger-staff-users.seeder"; import { PrismaModule } from "./common/prisma.module"; import { AuditModule } from "./common/audit.module"; import { I18nModule } from "./common/i18n/i18n.module"; import { LocaleMiddleware } from "./common/i18n/locale.middleware"; import { DeleteExceptionFilter } from "./common/exceptions/delete-exception.filter"; import appConfig from "./config/app.config"; import dbConfig from "./config/database.config"; import iamDatabaseConfig from "./config/iam-database.config"; import telebirrConfig from "./config/telebirr.config"; import cbeConfig from "./config/cbe.config"; import cardConfig from "./config/card.config"; import waafiConfig from "./config/waafi.config"; import faydaConfig from "./config/fayda.config"; import rabbitmqConfig from "./config/rabbitmq.config"; import { AuthModule } from "./modules/auth/auth.module"; import { StationsModule } from "./modules/stations/stations.module"; import { FleetModule } from "./modules/fleet/fleet.module"; import { SchedulesModule } from "./modules/schedules/schedules.module"; import { SearchModule } from "./modules/search/search.module"; import { SeatsModule } from "./modules/seats/seats.module"; import { BookingsModule } from "./modules/bookings/bookings.module"; import { PaymentsModule } from "./modules/payments/payments.module"; import { TicketsModule } from "./modules/tickets/tickets.module"; import { PassengersModule } from "./modules/passengers/passengers.module"; import { NotificationsModule } from "./modules/notifications/notifications.module"; import { LoyaltyModule } from "./modules/loyalty/loyalty.module"; import { WalletModule } from "./modules/wallet/wallet.module"; import { PromosModule } from "./modules/promos/promos.module"; import { LiveModule } from "./modules/live/live.module"; import { SupportModule } from "./modules/support/support.module"; import { DashboardModule } from "./modules/dashboard/dashboard.module"; import { SegmentsModule } from "./modules/segments/segments.module"; import { AgentsModule } from "./modules/agents/agents.module"; import { ReportsModule } from "./modules/reports/reports.module"; import { FraudModule } from "./modules/fraud/fraud.module"; import { SeatClassesModule } from "./modules/seat-classes/seat-classes.module"; import { FareEngineModule } from "./modules/fare-engine/fare-engine.module"; import { VerifaydaModule } from "./modules/verifayda/verifayda.module"; import { AuditModuleFeature } from "./modules/audit/audit.module"; import { CurrenciesModule } from "./modules/currencies/currencies.module"; import { SystemConfigModule } from "./modules/system-config/system-config.module"; import { PackagesModule } from "./modules/packages/packages.module"; import { ExcessBaggageModule } from "./modules/excess-baggage/excess-baggage.module"; import { HealthModule } from "./modules/health/health.module"; import { TasksModule } from "./modules/tasks/tasks.module"; import { AppReleasesModule } from "./modules/app-releases/app-releases.module"; import { ConfigurableFareModule } from "./modules/configurable-fare/configurable-fare.module"; import { SegmentFareSeeder } from "./seed/segment-fare.seeder"; import { EOtpType } from "@tria-plc/iamapi-common"; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, load: [ appConfig, dbConfig, iamDatabaseConfig, telebirrConfig, cbeConfig, cardConfig, waafiConfig, faydaConfig, rabbitmqConfig, ], }), ScheduleModule.forRoot(), EventEmitterModule.forRoot(), TypeOrmModule.forRootAsync({ inject: [ConfigService], useFactory: (config: ConfigService): TypeOrmModuleOptions => config.get("iamDatabase")!, }), TriaIamModule.forRoot({ applications: [EDR_PASSENGER_APPLICATION], permissions: EDR_PASSENGER_PERMISSIONS, otpMessages: { [EOtpType.MFA_LOGIN]: ({ otp }) => `Your EDR Passenger login code is ${otp}. It will expire in 5 minutes.`, [EOtpType.VERIFY_PHONE_NUMBER]: ({ otp }) => `Your EDR Passenger phone verification code is ${otp}. It will expire in 5 minutes.`, [EOtpType.RESET_PASSWORD]: ({ route }) => `Reset your EDR Passenger password using this link: ${route}`, [EOtpType.SET_PASSWORD]: ({ route }) => `Set your EDR Passenger password using this link: ${route}`, }, }), // Replaces the package's DataSeeder. Shared with edr-freight-api, which // seeds the same `iam` schema — see packages/iam-seed. IamSeedModule.forRoot({ superAdmin: { username: "superadmin", name: { am: "ሱፐር አድሚን", en: "Super Admin" }, roleKey: "super_admin", organizationKey: "edr", fallbackEmail: "superadmin@tria.com", }, }), SharedAuthModule, PrismaModule, AuditModule, I18nModule, AuthModule, StationsModule, FleetModule, SchedulesModule, SearchModule, SeatsModule, BookingsModule, PaymentsModule, TicketsModule, PassengersModule, NotificationsModule, LoyaltyModule, WalletModule, PromosModule, LiveModule, SupportModule, DashboardModule, SegmentsModule, AgentsModule, ReportsModule, FraudModule, SeatClassesModule, FareEngineModule, VerifaydaModule, AuditModuleFeature, CurrenciesModule, SystemConfigModule, PackagesModule, ExcessBaggageModule, HealthModule, TasksModule, AppReleasesModule, ConfigurableFareModule, ], providers: [ { provide: APP_FILTER, useClass: DeleteExceptionFilter }, EdrPassengerOrgSeeder, PassengerStaffUsersSeeder, SegmentFareSeeder, ], }) export class AppModule implements OnApplicationBootstrap { private readonly logger = new Logger(AppModule.name); constructor( private readonly iamBaselineSeeder: IamBaselineSeeder, private readonly edrPassengerOrgSeeder: EdrPassengerOrgSeeder, private readonly passengerStaffUsersSeeder: PassengerStaffUsersSeeder, private readonly segmentFareSeeder: SegmentFareSeeder, ) {} async onApplicationBootstrap() { // Runs first so the roles it seeds exist before EdrPassengerOrgSeeder links // super_admin permissions. Its own super-admin account attaches to the `edr` // organization, which that seeder creates — so on a brand-new database the // account lands on the next boot; it logs a warning and skips until then. // Non-fatal internally, but the wrapper stays for symmetry with the rest. try { await this.iamBaselineSeeder.run(); } catch (err) { this.logger.error( "[IamBaselineSeeder] Seed failed (non-fatal):", (err as Error).message, ); } try { await this.edrPassengerOrgSeeder.run(); } catch (err) { this.logger.error( "[EdrPassengerOrgSeeder] Seed failed (non-fatal):", (err as Error).message, ); } try { await this.passengerStaffUsersSeeder.run(); } catch (err) { this.logger.error( "[PassengerStaffUsersSeeder] Seed failed (non-fatal):", (err as Error).message, ); } try { await this.segmentFareSeeder.run(); } catch (err) { this.logger.error( "[SegmentFareSeeder] Seed failed (non-fatal):", (err as Error).message, ); } } }