refactor
This commit is contained in:
239
adapters/bootstrap/LeagueScoringPresets.ts
Normal file
239
adapters/bootstrap/LeagueScoringPresets.ts
Normal file
@@ -0,0 +1,239 @@
|
||||
import { PointsTable } from '@core/racing/domain/value-objects/PointsTable';
|
||||
import type { ChampionshipConfig } from '@core/racing/domain/types/ChampionshipConfig';
|
||||
import type { SessionType } from '@core/racing/domain/types/SessionType';
|
||||
import type { BonusRule } from '@core/racing/domain/types/BonusRule';
|
||||
import type { DropScorePolicy } from '@core/racing/domain/types/DropScorePolicy';
|
||||
import type { ChampionshipType } from '@core/racing/domain/types/ChampionshipType';
|
||||
import { LeagueScoringConfig } from '@core/racing/domain/entities/LeagueScoringConfig';
|
||||
|
||||
export type LeagueScoringPresetPrimaryChampionshipType =
|
||||
| 'driver'
|
||||
| 'team'
|
||||
| 'nations'
|
||||
| 'trophy';
|
||||
|
||||
export interface LeagueScoringPreset {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
primaryChampionshipType: LeagueScoringPresetPrimaryChampionshipType;
|
||||
dropPolicySummary: string;
|
||||
sessionSummary: string;
|
||||
bonusSummary: string;
|
||||
createConfig: (options: { seasonId: string }) => LeagueScoringConfig;
|
||||
}
|
||||
|
||||
const mainPointsSprintMain = new PointsTable({
|
||||
1: 25,
|
||||
2: 18,
|
||||
3: 15,
|
||||
4: 12,
|
||||
5: 10,
|
||||
6: 8,
|
||||
7: 6,
|
||||
8: 4,
|
||||
9: 2,
|
||||
10: 1,
|
||||
});
|
||||
|
||||
const sprintPointsSprintMain = new PointsTable({
|
||||
1: 8,
|
||||
2: 7,
|
||||
3: 6,
|
||||
4: 5,
|
||||
5: 4,
|
||||
6: 3,
|
||||
7: 2,
|
||||
8: 1,
|
||||
});
|
||||
|
||||
const clubMainPoints = new PointsTable({
|
||||
1: 20,
|
||||
2: 15,
|
||||
3: 12,
|
||||
4: 10,
|
||||
5: 8,
|
||||
6: 6,
|
||||
7: 4,
|
||||
8: 2,
|
||||
9: 1,
|
||||
});
|
||||
|
||||
const enduranceMainPoints = new PointsTable({
|
||||
1: 50,
|
||||
2: 36,
|
||||
3: 30,
|
||||
4: 24,
|
||||
5: 20,
|
||||
6: 16,
|
||||
7: 12,
|
||||
8: 8,
|
||||
9: 4,
|
||||
10: 2,
|
||||
});
|
||||
|
||||
export const leagueScoringPresets: LeagueScoringPreset[] = [
|
||||
{
|
||||
id: 'sprint-main-driver',
|
||||
name: 'Sprint + Main',
|
||||
description:
|
||||
'Short sprint race plus main race; sprint gives fewer points.',
|
||||
primaryChampionshipType: 'driver',
|
||||
dropPolicySummary: 'Best 6 results of 8 count towards the championship.',
|
||||
sessionSummary: 'Sprint + Main',
|
||||
bonusSummary: 'Fastest lap +1 point in main race if finishing P10 or better.',
|
||||
createConfig: ({ seasonId }) => {
|
||||
const fastestLapBonus: BonusRule = {
|
||||
id: 'fastest-lap-main',
|
||||
type: 'fastestLap',
|
||||
points: 1,
|
||||
requiresFinishInTopN: 10,
|
||||
};
|
||||
|
||||
const sessionTypes: SessionType[] = ['sprint', 'main'];
|
||||
|
||||
const pointsTableBySessionType: Record<SessionType, PointsTable> = {
|
||||
sprint: sprintPointsSprintMain,
|
||||
main: mainPointsSprintMain,
|
||||
practice: new PointsTable({}),
|
||||
qualifying: new PointsTable({}),
|
||||
q1: new PointsTable({}),
|
||||
q2: new PointsTable({}),
|
||||
q3: new PointsTable({}),
|
||||
timeTrial: new PointsTable({}),
|
||||
};
|
||||
|
||||
const bonusRulesBySessionType: Record<SessionType, BonusRule[]> = {
|
||||
sprint: [],
|
||||
main: [fastestLapBonus],
|
||||
practice: [],
|
||||
qualifying: [],
|
||||
q1: [],
|
||||
q2: [],
|
||||
q3: [],
|
||||
timeTrial: [],
|
||||
};
|
||||
|
||||
const dropScorePolicy: DropScorePolicy = {
|
||||
strategy: 'bestNResults',
|
||||
count: 6,
|
||||
};
|
||||
|
||||
const championship: ChampionshipConfig = {
|
||||
id: 'driver-champ-sprint-main',
|
||||
name: 'Driver Championship',
|
||||
type: 'driver' as ChampionshipType,
|
||||
sessionTypes,
|
||||
pointsTableBySessionType,
|
||||
bonusRulesBySessionType,
|
||||
dropScorePolicy,
|
||||
};
|
||||
|
||||
return LeagueScoringConfig.create({
|
||||
id: `lsc-${seasonId}-sprint-main-driver`,
|
||||
seasonId,
|
||||
scoringPresetId: 'sprint-main-driver',
|
||||
championships: [championship],
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'club-default',
|
||||
name: 'Club ladder',
|
||||
description:
|
||||
'Simple club ladder with a single main race and no bonuses or drop scores.',
|
||||
primaryChampionshipType: 'driver',
|
||||
dropPolicySummary: 'All race results count, no drop scores.',
|
||||
sessionSummary: 'Main race only',
|
||||
bonusSummary: 'No bonus points.',
|
||||
createConfig: ({ seasonId }) => {
|
||||
const sessionTypes: SessionType[] = ['main'];
|
||||
|
||||
const pointsTableBySessionType: Record<SessionType, PointsTable> = {
|
||||
sprint: new PointsTable({}),
|
||||
main: clubMainPoints,
|
||||
practice: new PointsTable({}),
|
||||
qualifying: new PointsTable({}),
|
||||
q1: new PointsTable({}),
|
||||
q2: new PointsTable({}),
|
||||
q3: new PointsTable({}),
|
||||
timeTrial: new PointsTable({}),
|
||||
};
|
||||
|
||||
const dropScorePolicy: DropScorePolicy = {
|
||||
strategy: 'none',
|
||||
};
|
||||
|
||||
const championship: ChampionshipConfig = {
|
||||
id: 'driver-champ-club-default',
|
||||
name: 'Driver Championship',
|
||||
type: 'driver' as ChampionshipType,
|
||||
sessionTypes,
|
||||
pointsTableBySessionType,
|
||||
dropScorePolicy,
|
||||
};
|
||||
|
||||
return LeagueScoringConfig.create({
|
||||
id: `lsc-${seasonId}-club-default`,
|
||||
seasonId,
|
||||
scoringPresetId: 'club-default',
|
||||
championships: [championship],
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'endurance-main-double',
|
||||
name: 'Endurance weekend',
|
||||
description:
|
||||
'Single main endurance race with double points and a simple drop policy.',
|
||||
primaryChampionshipType: 'driver',
|
||||
dropPolicySummary: 'Best 4 results of 6 count towards the championship.',
|
||||
sessionSummary: 'Main race only',
|
||||
bonusSummary: 'No bonus points.',
|
||||
createConfig: ({ seasonId }) => {
|
||||
const sessionTypes: SessionType[] = ['main'];
|
||||
|
||||
const pointsTableBySessionType: Record<SessionType, PointsTable> = {
|
||||
sprint: new PointsTable({}),
|
||||
main: enduranceMainPoints,
|
||||
practice: new PointsTable({}),
|
||||
qualifying: new PointsTable({}),
|
||||
q1: new PointsTable({}),
|
||||
q2: new PointsTable({}),
|
||||
q3: new PointsTable({}),
|
||||
timeTrial: new PointsTable({}),
|
||||
};
|
||||
|
||||
const dropScorePolicy: DropScorePolicy = {
|
||||
strategy: 'bestNResults',
|
||||
count: 4,
|
||||
};
|
||||
|
||||
const championship: ChampionshipConfig = {
|
||||
id: 'driver-champ-endurance-main-double',
|
||||
name: 'Driver Championship',
|
||||
type: 'driver' as ChampionshipType,
|
||||
sessionTypes,
|
||||
pointsTableBySessionType,
|
||||
dropScorePolicy,
|
||||
};
|
||||
|
||||
return {
|
||||
id: `lsc-${seasonId}-endurance-main-double`,
|
||||
seasonId,
|
||||
scoringPresetId: 'endurance-main-double',
|
||||
championships: [championship],
|
||||
};
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export function listLeagueScoringPresets(): LeagueScoringPreset[] {
|
||||
return [...leagueScoringPresets];
|
||||
}
|
||||
|
||||
export function getLeagueScoringPresetById(
|
||||
id: string,
|
||||
): LeagueScoringPreset | undefined {
|
||||
return leagueScoringPresets.find((preset) => preset.id === id);
|
||||
}
|
||||
82
adapters/bootstrap/ScoringDemoSetup.ts
Normal file
82
adapters/bootstrap/ScoringDemoSetup.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { Game } from '@core/racing/domain/entities/Game';
|
||||
import { Season } from '@core/racing/domain/entities/season/Season';
|
||||
import type { LeagueScoringConfig } from '@core/racing/domain/entities/LeagueScoringConfig';
|
||||
import { InMemoryGameRepository } from '../racing/persistence/inmemory/InMemoryScoringRepositories';
|
||||
import { InMemorySeasonRepository } from '../racing/persistence/inmemory/InMemoryScoringRepositories';
|
||||
import { InMemoryLeagueScoringConfigRepository } from '../racing/persistence/inmemory/InMemoryScoringRepositories';
|
||||
import { InMemoryChampionshipStandingRepository } from '../racing/persistence/inmemory/InMemoryScoringRepositories';
|
||||
import type { Logger } from '@core/shared/application';
|
||||
import { getLeagueScoringPresetById } from './LeagueScoringPresets';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
class SilentLogger implements Logger {
|
||||
debug(...args: unknown[]): void {
|
||||
// console.debug(...args);
|
||||
}
|
||||
info(...args: unknown[]): void {
|
||||
// console.info(...args);
|
||||
}
|
||||
warn(...args: unknown[]): void {
|
||||
// console.warn(...args);
|
||||
}
|
||||
error(...args: unknown[]): void {
|
||||
// console.error(...args);
|
||||
}
|
||||
}
|
||||
|
||||
export function createSprintMainDemoScoringSetup(params: {
|
||||
leagueId: string;
|
||||
seasonId?: string;
|
||||
}): {
|
||||
gameRepo: InMemoryGameRepository;
|
||||
seasonRepo: InMemorySeasonRepository;
|
||||
scoringConfigRepo: InMemoryLeagueScoringConfigRepository;
|
||||
championshipStandingRepo: InMemoryChampionshipStandingRepository;
|
||||
seasonId: string;
|
||||
championshipId: string;
|
||||
} {
|
||||
const { leagueId } = params;
|
||||
const seasonId = params.seasonId ?? 'season-sprint-main-demo';
|
||||
const championshipId = 'driver-champ';
|
||||
|
||||
const logger = new SilentLogger();
|
||||
|
||||
const game = Game.create({ id: 'iracing', name: 'iRacing' });
|
||||
|
||||
const season = Season.create({
|
||||
id: seasonId,
|
||||
leagueId,
|
||||
gameId: game.id.toString(),
|
||||
name: 'Sprint + Main Demo Season',
|
||||
year: 2025,
|
||||
order: 1,
|
||||
status: 'active',
|
||||
startDate: new Date('2025-01-01'),
|
||||
endDate: new Date('2025-12-31'),
|
||||
});
|
||||
|
||||
const preset = getLeagueScoringPresetById('sprint-main-driver');
|
||||
if (!preset) {
|
||||
throw new Error('Missing sprint-main-driver scoring preset');
|
||||
}
|
||||
|
||||
const leagueScoringConfig: LeagueScoringConfig = preset.createConfig({
|
||||
seasonId: season.id,
|
||||
});
|
||||
|
||||
const gameRepo = new InMemoryGameRepository(logger, [game]);
|
||||
const seasonRepo = new InMemorySeasonRepository(logger, [season]);
|
||||
const scoringConfigRepo = new InMemoryLeagueScoringConfigRepository(logger, [
|
||||
leagueScoringConfig,
|
||||
]);
|
||||
const championshipStandingRepo = new InMemoryChampionshipStandingRepository(logger);
|
||||
|
||||
return {
|
||||
gameRepo,
|
||||
seasonRepo,
|
||||
scoringConfigRepo,
|
||||
championshipStandingRepo,
|
||||
seasonId: season.id,
|
||||
championshipId,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user