Files
gridpilot.gg/apps/api/src/domain/admin/AdminModule.ts
2026-01-16 22:32:55 +01:00

79 lines
2.8 KiB
TypeScript

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 {}