/** * Use Case: GetRaceProtestsUseCase * * Returns all protests filed for a specific race, with driver details. * Orchestrates domain logic and delegates presentation to the presenter. */ import { Result } from '@core/shared/domain/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { Driver } from '../../domain/entities/Driver'; import type { Protest } from '../../domain/entities/Protest'; import type { DriverRepository } from '../../domain/repositories/DriverRepository'; import type { ProtestRepository } from '../../domain/repositories/ProtestRepository'; export interface GetRaceProtestsInput { raceId: string; } export type GetRaceProtestsErrorCode = 'REPOSITORY_ERROR'; export interface GetRaceProtestsResult { protests: Protest[]; drivers: Driver[]; } export class GetRaceProtestsUseCase { constructor( private readonly protestRepository: ProtestRepository, private readonly driverRepository: DriverRepository, ) {} async execute( input: GetRaceProtestsInput, ): Promise>> { try { const protests = await this.protestRepository.findByRaceId(input.raceId); const driverIds = new Set(); protests.forEach((protest) => { driverIds.add(protest.protestingDriverId); driverIds.add(protest.accusedDriverId); if (protest.reviewedBy) { driverIds.add(protest.reviewedBy); } }); const drivers = await Promise.all( Array.from(driverIds).map((id) => this.driverRepository.findById(id)), ); const validDrivers = drivers.filter((driver): driver is NonNullable => driver !== null); const result: GetRaceProtestsResult = { protests, drivers: validDrivers, }; return Result.ok(result); } catch (error: unknown) { const message = error instanceof Error && error.message ? error.message : 'Failed to load race protests'; return Result.err({ code: 'REPOSITORY_ERROR', details: { message }, }); } } }