import type { ITeamMembershipRepository } from '../../domain/repositories/ITeamMembershipRepository'; import type { IDriverRepository } from '../../domain/repositories/IDriverRepository'; import type { GetDriverAvatarInputPort } from '../ports/input/GetDriverAvatarInputPort'; import type { GetDriverAvatarOutputPort } from '../ports/output/GetDriverAvatarOutputPort'; import type { TeamJoinRequestsOutputPort } from '../ports/output/TeamJoinRequestsOutputPort'; import { Result } from '@core/shared/application/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { AsyncUseCase } from '@core/shared/application'; import type { Logger } from '@core/shared/application'; /** * Use Case for retrieving team join requests. */ export class GetTeamJoinRequestsUseCase implements AsyncUseCase<{ teamId: string }, TeamJoinRequestsOutputPort, 'REPOSITORY_ERROR'> { constructor( private readonly membershipRepository: ITeamMembershipRepository, private readonly driverRepository: IDriverRepository, private readonly getDriverAvatar: (input: GetDriverAvatarInputPort) => Promise, private readonly logger: Logger, ) {} async execute(input: { teamId: string }): Promise>> { this.logger.debug('Executing GetTeamJoinRequestsUseCase', { teamId: input.teamId }); try { const requests = await this.membershipRepository.getJoinRequests(input.teamId); this.logger.info('Successfully retrieved team join requests', { teamId: input.teamId, count: requests.length }); const driverNames: Record = {}; const avatarUrls: Record = {}; for (const request of requests) { const driver = await this.driverRepository.findById(request.driverId); if (driver) { driverNames[request.driverId] = driver.name.value; } else { this.logger.warn(`Driver not found for ID: ${request.driverId} during join request processing.`); } const avatarResult = await this.getDriverAvatar({ driverId: request.driverId }); avatarUrls[request.driverId] = avatarResult.avatarUrl; this.logger.debug('Processed driver details for join request', { driverId: request.driverId }); } const requestsViewModel = requests.map(request => ({ requestId: request.id, driverId: request.driverId, driverName: driverNames[request.driverId] || 'Unknown', teamId: request.teamId, status: request.status as 'pending' | 'approved' | 'rejected', requestedAt: request.requestedAt instanceof Date ? request.requestedAt : new Date(request.requestedAt), avatarUrl: avatarUrls[request.driverId] || '', })); const outputPort: TeamJoinRequestsOutputPort = { requests: requestsViewModel, pendingCount: requests.filter(r => r.status === 'pending').length, totalCount: requests.length, }; return Result.ok(outputPort); } catch (error) { this.logger.error('Error retrieving team join requests', { teamId: input.teamId, err: error }); return Result.err({ code: 'REPOSITORY_ERROR', details: { message: 'Failed to retrieve team join requests' } }); } } }