Files
gridpilot.gg/core/racing/application/use-cases/RecordTeamRaceRatingEventsUseCase.ts
2026-01-16 21:35:35 +01:00

91 lines
2.9 KiB
TypeScript

import { TeamDrivingRatingEventFactory } from '@core/racing/domain/services/TeamDrivingRatingEventFactory';
import { RecordTeamRaceRatingEventsInput, RecordTeamRaceRatingEventsOutput } from '../dtos/RecordTeamRaceRatingEventsDto';
import type { TeamRaceResultsProvider } from '../ports/TeamRaceResultsProvider';
import { AppendTeamRatingEventsUseCase } from './AppendTeamRatingEventsUseCase';
/**
* Use Case: RecordTeamRaceRatingEventsUseCase
*
* Records rating events for a completed team race.
* Mirrors user slice 3 pattern in core/racing/.
*
* Flow:
* 1. Load team race results from racing context
* 2. Factory creates team rating events
* 3. Append to ledger via AppendTeamRatingEventsUseCase
* 4. Recompute snapshots
*/
export class RecordTeamRaceRatingEventsUseCase {
constructor(
private readonly teamRaceResultsProvider: TeamRaceResultsProvider,
private readonly appendTeamRatingEventsUseCase: AppendTeamRatingEventsUseCase,
) {}
async execute(input: RecordTeamRaceRatingEventsInput): Promise<RecordTeamRaceRatingEventsOutput> {
const errors: string[] = [];
const teamsUpdated: string[] = [];
let totalEventsCreated = 0;
try {
// 1. Load team race results
const teamRaceResults = await this.teamRaceResultsProvider.getTeamRaceResults(input.raceId);
if (!teamRaceResults) {
return {
success: false,
raceId: input.raceId,
eventsCreated: 0,
teamsUpdated: [],
errors: ['Team race results not found'],
};
}
// 2. Create rating events using factory
const eventsByTeam = TeamDrivingRatingEventFactory.createDrivingEventsFromRace(teamRaceResults);
if (eventsByTeam.size === 0) {
return {
success: true,
raceId: input.raceId,
eventsCreated: 0,
teamsUpdated: [],
errors: [],
};
}
// 3. Process each team's events
for (const [teamId, events] of eventsByTeam) {
try {
// Use AppendTeamRatingEventsUseCase to handle ledger and snapshot
await this.appendTeamRatingEventsUseCase.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,
raceId: input.raceId,
eventsCreated: totalEventsCreated,
teamsUpdated,
errors,
};
} catch (error) {
const errorMsg = `Failed to record team race rating events: ${error instanceof Error ? error.message : 'Unknown error'}`;
errors.push(errorMsg);
return {
success: false,
raceId: input.raceId,
eventsCreated: 0,
teamsUpdated: [],
errors,
};
}
}
}