import { Result } from '@core/shared/application/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { IRaceRegistrationRepository } from '@core/racing/domain/repositories/IRaceRegistrationRepository'; import type { IRaceRepository } from '@core/racing/domain/repositories/IRaceRepository'; import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort'; import type { Logger } from '@core/shared/application/Logger'; export type WithdrawFromRaceInput = { raceId: string; driverId: string; }; export type WithdrawFromRaceResult = { raceId: string; driverId: string; status: 'withdrawn'; }; export type WithdrawFromRaceErrorCode = | 'RACE_NOT_FOUND' | 'REGISTRATION_NOT_FOUND' | 'WITHDRAWAL_NOT_ALLOWED' | 'REPOSITORY_ERROR'; /** * Use Case: Withdraw a driver from a race. */ export class WithdrawFromRaceUseCase { constructor( private readonly raceRepository: IRaceRepository, private readonly registrationRepository: IRaceRegistrationRepository, private readonly logger: Logger, private readonly output: UseCaseOutputPort, ) {} async execute(input: WithdrawFromRaceInput): Promise< Result> > { const { raceId, driverId } = input; try { const race = await this.raceRepository.findById(raceId); if (!race) { return Result.err({ code: 'RACE_NOT_FOUND', details: { message: `Race ${raceId} not found`, }, }); } const isRegistered = await this.registrationRepository.isRegistered(raceId, driverId); if (!isRegistered) { return Result.err({ code: 'REGISTRATION_NOT_FOUND', details: { message: `Driver ${driverId} is not registered for race ${raceId}`, }, }); } if (!race.isUpcoming()) { return Result.err({ code: 'WITHDRAWAL_NOT_ALLOWED', details: { message: 'Withdrawal is not allowed for this race', }, }); } await this.registrationRepository.withdraw(raceId, driverId); const result: WithdrawFromRaceResult = { raceId, driverId, status: 'withdrawn', }; this.output.present(result); return Result.ok(undefined); } catch (error) { const message = error instanceof Error ? error.message : 'Failed to withdraw from race'; this.logger.error('WithdrawFromRaceUseCase.execute failed', error instanceof Error ? error : undefined); return Result.err({ code: 'REPOSITORY_ERROR', details: { message, }, }); } } }