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 { TeamMembersOutputPort } from '../ports/output/TeamMembersOutputPort'; 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 members. */ export class GetTeamMembersUseCase implements AsyncUseCase<{ teamId: string }, TeamMembersOutputPort, '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 GetTeamMembersUseCase for teamId: ${input.teamId}`); try { const memberships = await this.membershipRepository.getTeamMembers(input.teamId); this.logger.info(`Found ${memberships.length} memberships for teamId: ${input.teamId}`); const driverNames: Record = {}; const avatarUrls: Record = {}; for (const membership of memberships) { this.logger.debug(`Processing membership for driverId: ${membership.driverId}`); const driver = await this.driverRepository.findById(membership.driverId); if (driver) { driverNames[membership.driverId] = driver.name.value; } else { this.logger.warn(`Driver with ID ${membership.driverId} not found while fetching team members for team ${input.teamId}.`); } const avatarResult = await this.getDriverAvatar({ driverId: membership.driverId }); avatarUrls[membership.driverId] = avatarResult.avatarUrl; } const members = memberships.map(membership => ({ driverId: membership.driverId, driverName: driverNames[membership.driverId] || 'Unknown', role: membership.role as 'owner' | 'manager' | 'member', joinedAt: membership.joinedAt instanceof Date ? membership.joinedAt : new Date(membership.joinedAt), isActive: membership.status === 'active', avatarUrl: avatarUrls[membership.driverId] || '', })); const outputPort: TeamMembersOutputPort = { members, totalCount: memberships.length, ownerCount: memberships.filter(m => m.role === 'owner').length, managerCount: memberships.filter(m => m.role === 'manager').length, memberCount: memberships.filter(m => m.role === 'member').length, }; return Result.ok(outputPort); } catch (error) { this.logger.error(`Error in GetTeamMembersUseCase for teamId: ${input.teamId}`, error as Error, { teamId: input.teamId }); return Result.err({ code: 'REPOSITORY_ERROR', details: { message: 'Failed to retrieve team members' } }); } } }