import type { AsyncUseCase, Logger } from '@core/shared/application'; import { Result as SharedResult } from '@core/shared/application/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { ITeamMembershipRepository } from '../../domain/repositories/ITeamMembershipRepository'; import type { ITeamRepository } from '../../domain/repositories/ITeamRepository'; import type { TeamMembership, TeamMembershipStatus, TeamRole, } from '../../domain/types/TeamMembership'; import type { JoinTeamInputPort } from '../ports/input/JoinTeamInputPort'; type JoinTeamErrorCode = 'ALREADY_IN_TEAM' | 'ALREADY_MEMBER' | 'TEAM_NOT_FOUND' | 'REPOSITORY_ERROR'; type JoinTeamApplicationError = ApplicationErrorCode; export class JoinTeamUseCase implements AsyncUseCase { constructor( private readonly teamRepository: ITeamRepository, private readonly membershipRepository: ITeamMembershipRepository, private readonly logger: Logger, ) {} async execute(command: JoinTeamInputPort): Promise> { this.logger.debug('Attempting to join team', { command }); const { teamId, driverId } = command; try { const existingActive = await this.membershipRepository.getActiveMembershipForDriver( driverId, ); if (existingActive) { this.logger.warn('Driver already belongs to a team', { driverId, teamId }); return SharedResult.err({ code: 'ALREADY_IN_TEAM', details: { message: 'Driver already belongs to a team' } }); } const existingMembership = await this.membershipRepository.getMembership(teamId, driverId); if (existingMembership) { this.logger.warn('Driver already has a pending or active membership request', { driverId, teamId }); return SharedResult.err({ code: 'ALREADY_MEMBER', details: { message: 'Already a member or have a pending request' } }); } const team = await this.teamRepository.findById(teamId); if (!team) { this.logger.error('Team not found', { entity: 'team', id: teamId }); return SharedResult.err({ code: 'TEAM_NOT_FOUND', details: { message: `Team ${teamId} not found` } }); } const membership: TeamMembership = { teamId, driverId, role: 'driver' as TeamRole, status: 'active' as TeamMembershipStatus, joinedAt: new Date(), }; await this.membershipRepository.saveMembership(membership); this.logger.info('Driver successfully joined team', { driverId, teamId }); return SharedResult.ok(undefined); } catch (error) { this.logger.error('Failed to join team due to an unexpected error', error instanceof Error ? error : new Error('Unknown error')); return SharedResult.err({ code: 'REPOSITORY_ERROR', details: { message: error instanceof Error ? error.message : 'Unknown error' } }); } } }