import type { ILeagueMembershipRepository } from '../../domain/repositories/ILeagueMembershipRepository'; import type { ILeagueRepository } from '../../domain/repositories/ILeagueRepository'; import { Result } from '@core/shared/application/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import { randomUUID } from 'crypto'; import { JoinedAt } from '../../domain/value-objects/JoinedAt'; import { LeagueId } from '../../domain/entities/LeagueId'; import { DriverId } from '../../domain/entities/DriverId'; import { MembershipRole } from '../../domain/entities/MembershipRole'; import { MembershipStatus } from '../../domain/entities/MembershipStatus'; export interface ApproveLeagueJoinRequestInput { leagueId: string; joinRequestId: string; } export interface ApproveLeagueJoinRequestResult { success: boolean; message: string; } export class ApproveLeagueJoinRequestUseCase { constructor( private readonly leagueMembershipRepository: ILeagueMembershipRepository, private readonly leagueRepository: ILeagueRepository, ) {} async execute( input: ApproveLeagueJoinRequestInput, ): Promise< Result< ApproveLeagueJoinRequestResult, ApplicationErrorCode< 'JOIN_REQUEST_NOT_FOUND' | 'LEAGUE_NOT_FOUND' | 'LEAGUE_AT_CAPACITY', { message: string } > > > { const requests = await this.leagueMembershipRepository.getJoinRequests(input.leagueId); const request = requests.find(r => r.id === input.joinRequestId); if (!request) { return Result.err({ code: 'JOIN_REQUEST_NOT_FOUND', details: { message: 'Join request not found' } }); } const league = await this.leagueRepository.findById(input.leagueId); if (!league) { return Result.err({ code: 'LEAGUE_NOT_FOUND', details: { message: 'League not found' } }); } const members = await this.leagueMembershipRepository.getLeagueMembers(input.leagueId); const maxDrivers = league.settings.maxDrivers ?? 32; if (members.length >= maxDrivers) { return Result.err({ code: 'LEAGUE_AT_CAPACITY', details: { message: 'League is at capacity' } }); } await this.leagueMembershipRepository.removeJoinRequest(input.joinRequestId); await this.leagueMembershipRepository.saveMembership({ id: randomUUID(), leagueId: LeagueId.create(input.leagueId), driverId: DriverId.create(request.driverId.toString()), role: MembershipRole.create('member'), status: MembershipStatus.create('active'), joinedAt: JoinedAt.create(new Date()), }); const result: ApproveLeagueJoinRequestResult = { success: true, message: 'Join request approved.' }; return Result.ok(result); } }