import { ListUsersUseCase } from '@core/admin/application/use-cases/ListUsersUseCase'; import type { AdminUserRepository } from '@core/admin/domain/repositories/AdminUserRepository'; import type { Provider } from '@nestjs/common'; import { Module } from '@nestjs/common'; import { InMemoryAdminPersistenceModule } from '../../persistence/inmemory/InMemoryAdminPersistenceModule'; import { InitializationLogger } from '../../shared/logging/InitializationLogger'; import { AuthModule } from '../auth/AuthModule'; import { AdminController } from './AdminController'; import { AdminService } from './AdminService'; import { GetDashboardStatsUseCase } from './use-cases/GetDashboardStatsUseCase'; export const ADMIN_USER_REPOSITORY_TOKEN = 'IAdminUserRepository'; const initLogger = InitializationLogger.getInstance(); const adminProviders: Provider[] = [ AdminService, { provide: ListUsersUseCase, useFactory: ( repository: AdminUserRepository, ) => new ListUsersUseCase(repository), inject: [ADMIN_USER_REPOSITORY_TOKEN], }, { provide: GetDashboardStatsUseCase, useFactory: ( repository: AdminUserRepository, ) => new GetDashboardStatsUseCase(repository), inject: [ADMIN_USER_REPOSITORY_TOKEN], }, ]; // Diagnostics: Nest will crash with "metatype is not a constructor" if any provider resolves // to a non-constructable value (e.g. undefined import, object, etc.). for (const provider of adminProviders) { // Class providers are functions at runtime. if (typeof provider === 'function') { continue; } // Custom providers should be objects with a `provide` token. if (!provider || typeof provider !== 'object' || !('provide' in provider)) { initLogger.error( `[AdminModule] Invalid provider entry (expected class or provider object): ${String(provider)}`, ); continue; } const token = (provider as { provide: unknown }).provide; const tokenLabel = typeof token === 'function' ? token.name : String(token); if ('useClass' in provider) { const useClass = (provider as { useClass?: unknown }).useClass; if (typeof useClass !== 'function') { initLogger.error( `[AdminModule] Provider "${tokenLabel}" has non-constructable useClass: ${String(useClass)}`, ); } } if ('useExisting' in provider) { const useExisting = (provider as { useExisting?: unknown }).useExisting; if (typeof useExisting !== 'function' && typeof useExisting !== 'string' && typeof useExisting !== 'symbol') { initLogger.warn( `[AdminModule] Provider "${tokenLabel}" has suspicious useExisting: ${String(useExisting)}`, ); } } } @Module({ imports: [InMemoryAdminPersistenceModule, AuthModule], controllers: [AdminController], providers: [...adminProviders], exports: [AdminService], }) export class AdminModule {}