Files
gridpilot.gg/apps/api/src/domain/admin/AdminService.ts
Marc Mintel f06a00da1b
Some checks failed
CI / lint-typecheck (push) Failing after 1m15s
CI / tests (push) Has been skipped
CI / contract-tests (push) Has been skipped
CI / e2e-tests (push) Has been skipped
CI / comment-pr (push) Has been skipped
CI / commit-types (push) Has been skipped
api tests
2026-01-25 18:26:44 +01:00

86 lines
3.3 KiB
TypeScript

import { ListUsersInput, ListUsersResult, ListUsersUseCase } from '@core/admin/application/use-cases/ListUsersUseCase';
import type { AdminUser } from '@core/admin/domain/entities/AdminUser';
import { Injectable } from '@nestjs/common';
import { DashboardStatsResponseDto } from './dtos/DashboardStatsResponseDto';
import { UserListResponseDto, UserResponseDto } from './dtos/UserResponseDto';
import { GetDashboardStatsInput, GetDashboardStatsUseCase } from './use-cases/GetDashboardStatsUseCase';
@Injectable()
export class AdminService {
constructor(
private readonly listUsersUseCase: ListUsersUseCase,
private readonly getDashboardStatsUseCase: GetDashboardStatsUseCase,
) {}
async listUsers(input: ListUsersInput): Promise<UserListResponseDto> {
const result = await this.listUsersUseCase.execute(input);
if (result.isErr()) {
const error = result.unwrapErr();
throw new Error(`${error.code}: ${error.details.message}`);
}
const data = result.unwrap();
return this.toListResponseDto(data);
}
async getDashboardStats(input: GetDashboardStatsInput): Promise<DashboardStatsResponseDto> {
const result = await this.getDashboardStatsUseCase.execute(input);
if (result.isErr()) {
const error = result.unwrapErr();
throw new Error(`${error.code}: ${error.details.message}`);
}
const data = result.unwrap();
return data;
}
private toListResponseDto(result: ListUsersResult): UserListResponseDto {
return {
users: result.users.map(user => this.toUserResponse(user)),
total: result.total,
page: result.page,
limit: result.limit,
totalPages: result.totalPages,
};
}
private toUserResponse(user: AdminUser | Record<string, unknown>): UserResponseDto {
// Handle both domain objects and plain objects
if (user.id && typeof user.id === 'object' && 'value' in (user.id as Record<string, unknown>)) {
// Domain object
const domainUser = user as AdminUser;
const response: UserResponseDto = {
id: domainUser.id.value,
email: domainUser.email.value,
displayName: domainUser.displayName,
roles: domainUser.roles.map(r => r.value),
status: domainUser.status.value,
isSystemAdmin: domainUser.isSystemAdmin(),
createdAt: domainUser.createdAt,
updatedAt: domainUser.updatedAt,
};
if (domainUser.lastLoginAt) response.lastLoginAt = domainUser.lastLoginAt;
if (domainUser.primaryDriverId) response.primaryDriverId = domainUser.primaryDriverId;
return response;
} else {
// Plain object (for tests)
const plainUser = user as Record<string, unknown>;
const response: UserResponseDto = {
id: plainUser.id as string,
email: plainUser.email as string,
displayName: plainUser.displayName as string,
roles: plainUser.roles as string[],
status: plainUser.status as string,
isSystemAdmin: plainUser.isSystemAdmin as boolean,
createdAt: plainUser.createdAt as Date,
updatedAt: plainUser.updatedAt as Date,
};
if (plainUser.lastLoginAt) response.lastLoginAt = plainUser.lastLoginAt as Date;
if (plainUser.primaryDriverId) response.primaryDriverId = plainUser.primaryDriverId as string;
return response;
}
}
}