91 lines
2.9 KiB
TypeScript
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,
|
|
};
|
|
}
|
|
}
|
|
} |