Files
gridpilot.gg/apps/api/src/domain/league/presenters/LeagueConfigPresenter.ts
2026-01-16 23:30:55 +01:00

100 lines
3.7 KiB
TypeScript

import type { GetLeagueFullConfigResult } from '@core/racing/application/use-cases/GetLeagueFullConfigUseCase';
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
import { LeagueConfigFormModelDTO } from '../dtos/LeagueConfigFormModelDTO';
export class LeagueConfigPresenter implements UseCaseOutputPort<GetLeagueFullConfigResult> {
private result: LeagueConfigFormModelDTO | null = null;
reset() {
this.result = null;
}
present(result: GetLeagueFullConfigResult): void {
const dto = result.config as unknown as {
league: { id: string; name: string; description: string; settings: { pointsSystem: string } };
activeSeason?: {
stewardingConfig?: {
decisionMode: string;
requireDefense: boolean;
defenseTimeLimit: number;
voteTimeLimit: number;
protestDeadlineHours: number;
stewardingClosesHours: number;
notifyAccusedOnProtest: boolean;
notifyOnVoteRequired: boolean;
requiredVotes?: number;
};
dropPolicy?: { strategy: string; n?: number };
schedule?: {
startDate?: Date;
timeOfDay?: { hour: number; minute: number };
};
};
scoringConfig?: { championships: { sessionTypes: string[]; pointsTableBySessionType: Record<string, { getPointsForPosition: (pos: number) => number }> }[] };
};
const league = dto.league;
const settings = league.settings;
const stewarding = dto.activeSeason?.stewardingConfig;
const dropPolicy = dto.activeSeason?.dropPolicy;
const schedule = dto.activeSeason?.schedule;
const scoringConfig = dto.scoringConfig;
const visibility: 'public' | 'private' = 'public';
const championships = scoringConfig?.championships ?? [];
const firstChampionship = championships[0];
const firstSessionType = firstChampionship?.sessionTypes[0];
const firstPointsTable = firstSessionType
? firstChampionship.pointsTableBySessionType[firstSessionType]
: undefined;
const pointsForWin = firstPointsTable?.getPointsForPosition(1) ?? 0;
const raceDayOfWeek = schedule?.startDate
? schedule.startDate.toLocaleDateString('en-US', { weekday: 'long' }).toLowerCase()
: 'sunday';
const raceTimeHour = schedule?.timeOfDay?.hour ?? 20;
const raceTimeMinute = schedule?.timeOfDay?.minute ?? 0;
this.result = {
leagueId: league.id,
basics: {
name: league.name,
description: league.description,
visibility,
},
structure: {
mode: 'solo',
},
championships,
scoring: {
type: settings.pointsSystem,
points: pointsForWin,
},
dropPolicy: {
strategy: dropPolicy?.strategy === 'none' ? 'none' : 'worst_n',
...(dropPolicy?.n !== undefined ? { n: dropPolicy.n } : {}),
},
timings: {
raceDayOfWeek,
raceTimeHour,
raceTimeMinute,
},
stewarding: {
decisionMode: stewarding?.decisionMode === 'steward_vote' ? 'committee_vote' : 'single_steward',
requireDefense: stewarding?.requireDefense ?? false,
defenseTimeLimit: stewarding?.defenseTimeLimit ?? 48,
voteTimeLimit: stewarding?.voteTimeLimit ?? 72,
protestDeadlineHours: stewarding?.protestDeadlineHours ?? 48,
stewardingClosesHours: stewarding?.stewardingClosesHours ?? 168,
notifyAccusedOnProtest: stewarding?.notifyAccusedOnProtest ?? true,
notifyOnVoteRequired: stewarding?.notifyOnVoteRequired ?? true,
...(stewarding?.requiredVotes !== undefined ? { requiredVotes: stewarding.requiredVotes } : {}),
},
};
}
getViewModel(): LeagueConfigFormModelDTO | null {
return this.result;
}
}