wip league admin tools
This commit is contained in:
@@ -4,6 +4,7 @@ import { PenaltyService } from '../penalties/PenaltyService';
|
||||
import { DriverService } from '../drivers/DriverService';
|
||||
import { LeagueMembershipService } from './LeagueMembershipService';
|
||||
import { LeagueStewardingViewModel, RaceWithProtests } from '../../view-models/LeagueStewardingViewModel';
|
||||
import type { ProtestDetailViewModel } from '../../view-models/ProtestDetailViewModel';
|
||||
|
||||
/**
|
||||
* League Stewarding Service
|
||||
@@ -12,6 +13,39 @@ import { LeagueStewardingViewModel, RaceWithProtests } from '../../view-models/L
|
||||
* All dependencies are injected via constructor.
|
||||
*/
|
||||
export class LeagueStewardingService {
|
||||
private getPenaltyValueLabel(valueKind: string): string {
|
||||
switch (valueKind) {
|
||||
case 'seconds':
|
||||
return 'seconds';
|
||||
case 'grid_positions':
|
||||
return 'positions';
|
||||
case 'points':
|
||||
return 'points';
|
||||
case 'races':
|
||||
return 'races';
|
||||
case 'none':
|
||||
return '';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
private getFallbackDefaultPenaltyValue(valueKind: string): number {
|
||||
switch (valueKind) {
|
||||
case 'seconds':
|
||||
return 5;
|
||||
case 'grid_positions':
|
||||
return 3;
|
||||
case 'points':
|
||||
return 5;
|
||||
case 'races':
|
||||
return 1;
|
||||
case 'none':
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
constructor(
|
||||
private readonly raceService: RaceService,
|
||||
private readonly protestService: ProtestService,
|
||||
@@ -77,6 +111,58 @@ export class LeagueStewardingService {
|
||||
return new LeagueStewardingViewModel(racesWithData, driverMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get protest review details as a page-ready view model
|
||||
*/
|
||||
async getProtestDetailViewModel(leagueId: string, protestId: string): Promise<ProtestDetailViewModel> {
|
||||
const [protestData, penaltyTypesReference] = await Promise.all([
|
||||
this.protestService.getProtestById(leagueId, protestId),
|
||||
this.penaltyService.getPenaltyTypesReference(),
|
||||
]);
|
||||
|
||||
if (!protestData) {
|
||||
throw new Error('Protest not found');
|
||||
}
|
||||
|
||||
const penaltyUiDefaults: Record<string, { label: string; description: string; defaultValue: number }> = {
|
||||
time_penalty: { label: 'Time Penalty', description: 'Add seconds to race result', defaultValue: 5 },
|
||||
grid_penalty: { label: 'Grid Penalty', description: 'Grid positions for next race', defaultValue: 3 },
|
||||
points_deduction: { label: 'Points Deduction', description: 'Deduct championship points', defaultValue: 5 },
|
||||
disqualification: { label: 'Disqualification', description: 'Disqualify from race', defaultValue: 0 },
|
||||
warning: { label: 'Warning', description: 'Official warning only', defaultValue: 0 },
|
||||
license_points: { label: 'License Points', description: 'Safety rating penalty', defaultValue: 2 },
|
||||
};
|
||||
|
||||
const penaltyTypes = (penaltyTypesReference?.penaltyTypes ?? []).map((ref: any) => {
|
||||
const ui = penaltyUiDefaults[ref.type];
|
||||
const valueLabel = this.getPenaltyValueLabel(String(ref.valueKind ?? 'none'));
|
||||
const defaultValue = ui?.defaultValue ?? this.getFallbackDefaultPenaltyValue(String(ref.valueKind ?? 'none'));
|
||||
|
||||
return {
|
||||
type: String(ref.type),
|
||||
label: ui?.label ?? String(ref.type).replaceAll('_', ' '),
|
||||
description: ui?.description ?? '',
|
||||
requiresValue: Boolean(ref.requiresValue),
|
||||
valueLabel,
|
||||
defaultValue,
|
||||
};
|
||||
});
|
||||
|
||||
const timePenalty = penaltyTypes.find((p) => p.type === 'time_penalty');
|
||||
const initial = timePenalty ?? penaltyTypes[0];
|
||||
|
||||
return {
|
||||
protest: protestData.protest,
|
||||
race: protestData.race,
|
||||
protestingDriver: protestData.protestingDriver,
|
||||
accusedDriver: protestData.accusedDriver,
|
||||
penaltyTypes,
|
||||
defaultReasons: penaltyTypesReference?.defaultReasons ?? { upheld: '', dismissed: '' },
|
||||
initialPenaltyType: initial?.type ?? null,
|
||||
initialPenaltyValue: initial?.defaultValue ?? 0,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Review a protest
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user