This commit is contained in:
2025-12-16 21:05:01 +01:00
parent f61e3a4e5a
commit 7532c7ed6d
207 changed files with 7861 additions and 2606 deletions

View File

@@ -16,7 +16,23 @@ import type {
ChampionshipStandingsRowDTO,
} from '../dto/ChampionshipStandingsDTO';
export class RecalculateChampionshipStandingsUseCase {
import type { AsyncUseCase } from '@core/shared/application/AsyncUseCase';
import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
export interface RecalculateChampionshipStandingsParams {
seasonId: string;
championshipId: string;
}
type RecalculateChampionshipStandingsErrorCode =
| 'SEASON_NOT_FOUND'
| 'LEAGUE_SCORING_CONFIG_NOT_FOUND'
| 'CHAMPIONSHIP_CONFIG_NOT_FOUND';
export class RecalculateChampionshipStandingsUseCase
implements AsyncUseCase<RecalculateChampionshipStandingsParams, ChampionshipStandingsDTO, RecalculateChampionshipStandingsErrorCode>
{
constructor(
private readonly seasonRepository: ISeasonRepository,
private readonly leagueScoringConfigRepository: ILeagueScoringConfigRepository,
@@ -28,27 +44,24 @@ export class RecalculateChampionshipStandingsUseCase {
private readonly championshipAggregator: ChampionshipAggregator,
) {}
async execute(params: {
seasonId: string;
championshipId: string;
}): Promise<ChampionshipStandingsDTO> {
async execute(params: RecalculateChampionshipStandingsParams): Promise<Result<ChampionshipStandingsDTO, ApplicationErrorCode<RecalculateChampionshipStandingsErrorCode>>> {
const { seasonId, championshipId } = params;
const season = await this.seasonRepository.findById(seasonId);
if (!season) {
throw new Error(`Season not found: ${seasonId}`);
return Result.err({ code: 'SEASON_NOT_FOUND', details: { message: `Season not found: ${seasonId}` } });
}
const leagueScoringConfig =
await this.leagueScoringConfigRepository.findBySeasonId(seasonId);
if (!leagueScoringConfig) {
throw new Error(`League scoring config not found for season: ${seasonId}`);
return Result.err({ code: 'LEAGUE_SCORING_CONFIG_NOT_FOUND', details: { message: `League scoring config not found for season: ${seasonId}` } });
}
const championship = this.findChampionshipConfig(
leagueScoringConfig.championships,
championshipId,
);
const championship = leagueScoringConfig.championships.find((c) => c.id === championshipId);
if (!championship) {
return Result.err({ code: 'CHAMPIONSHIP_CONFIG_NOT_FOUND', details: { message: `Championship config not found: ${championshipId}` } });
}
const races = await this.raceRepository.findByLeagueId(season.leagueId);
@@ -101,19 +114,9 @@ export class RecalculateChampionshipStandingsUseCase {
rows,
};
return dto;
return Result.ok(dto);
}
private findChampionshipConfig(
configs: ChampionshipConfig[],
championshipId: string,
): ChampionshipConfig {
const found = configs.find((c) => c.id === championshipId);
if (!found) {
throw new Error(`Championship config not found: ${championshipId}`);
}
return found;
}
private mapRaceSessionType(sessionType: string): SessionType {
if (sessionType === 'race') {