import type { TeamRatingEventRepository } from '@core/racing/domain/repositories/TeamRatingEventRepository'; import type { TeamRatingRepository } from '@core/racing/domain/repositories/TeamRatingRepository'; import { TeamDrivingRatingEventFactory } from '@core/racing/domain/services/TeamDrivingRatingEventFactory'; import type { TeamRaceResultsProvider } from '../ports/TeamRaceResultsProvider'; import { AppendTeamRatingEventsUseCase } from './AppendTeamRatingEventsUseCase'; /** * Integration Adapter: TeamRatingIntegrationAdapter * * Minimal integration with race flow. * Can be called from CompleteRaceUseCase to record team ratings. * * Usage in CompleteRaceUseCase: * ```typescript * // After race completion * const teamRatingAdapter = new TeamRatingIntegrationAdapter( * teamRaceResultsProvider, * ratingEventRepository, * ratingRepository * ); * * await teamRatingAdapter.recordTeamRatings(raceId); * ``` */ export class TeamRatingIntegrationAdapter { private appendUseCase: AppendTeamRatingEventsUseCase; constructor( private readonly teamRaceResultsProvider: TeamRaceResultsProvider, ratingEventRepository: TeamRatingEventRepository, ratingRepository: TeamRatingRepository, ) { this.appendUseCase = new AppendTeamRatingEventsUseCase( ratingEventRepository, ratingRepository ); } /** * Record team ratings for a completed race. * Returns true if successful, false otherwise. */ async recordTeamRatings(raceId: string): Promise { try { // Get team race results const teamRaceResults = await this.teamRaceResultsProvider.getTeamRaceResults(raceId); if (!teamRaceResults || teamRaceResults.results.length === 0) { return true; // No team results to process } // Create rating events const eventsByTeam = TeamDrivingRatingEventFactory.createDrivingEventsFromRace(teamRaceResults); if (eventsByTeam.size === 0) { return true; // No events generated } // Process each team for (const [teamId, events] of eventsByTeam) { try { await this.appendUseCase.execute(events); } catch (error) { console.error(`Failed to record team ratings for team ${teamId}:`, error); return false; } } return true; } catch (error) { console.error('Failed to record team ratings:', error); return false; } } /** * Record team ratings with detailed output. */ async recordTeamRatingsWithDetails(raceId: string): Promise<{ success: boolean; eventsCreated: number; teamsUpdated: string[]; errors: string[]; }> { const errors: string[] = []; const teamsUpdated: string[] = []; let totalEventsCreated = 0; try { const teamRaceResults = await this.teamRaceResultsProvider.getTeamRaceResults(raceId); if (!teamRaceResults || teamRaceResults.results.length === 0) { return { success: true, eventsCreated: 0, teamsUpdated: [], errors: [], }; } const eventsByTeam = TeamDrivingRatingEventFactory.createDrivingEventsFromRace(teamRaceResults); if (eventsByTeam.size === 0) { return { success: true, eventsCreated: 0, teamsUpdated: [], errors: [], }; } for (const [teamId, events] of eventsByTeam) { try { await this.appendUseCase.execute(events); teamsUpdated.push(teamId); totalEventsCreated += events.length; } catch (error) { const errorMsg = `Failed to process events for team ${teamId}: ${error instanceof Error ? error.message : 'Unknown error'}`; errors.push(errorMsg); } } return { success: errors.length === 0, eventsCreated: totalEventsCreated, teamsUpdated, errors, }; } catch (error) { const errorMsg = `Failed to record team ratings: ${error instanceof Error ? error.message : 'Unknown error'}`; errors.push(errorMsg); return { success: false, eventsCreated: 0, teamsUpdated: [], errors, }; } } }