import { ApplyPenaltyCommandDTO } from '../../types'; export type PenaltyType = 'time_penalty' | 'grid_penalty' | 'points_deduction' | 'disqualification' | 'warning' | 'license_points'; export interface ProtestDecisionData { decision: 'uphold' | 'dismiss' | null; penaltyType: PenaltyType; penaltyValue: number; stewardNotes: string; } const DEFAULT_PROTEST_REASON = 'Protest upheld'; export class ProtestDecisionCommandModel { decision: 'uphold' | 'dismiss' | null = null; penaltyType: PenaltyType = 'time_penalty'; penaltyValue: number = 5; stewardNotes: string = ''; constructor(initial: Partial = {}) { this.decision = initial.decision ?? null; this.penaltyType = initial.penaltyType ?? 'time_penalty'; this.penaltyValue = initial.penaltyValue ?? 5; this.stewardNotes = initial.stewardNotes ?? ''; } get isValid(): boolean { return this.decision !== null && this.stewardNotes.trim().length > 0; } get canSubmit(): boolean { return this.isValid; } reset(): void { this.decision = null; this.penaltyType = 'time_penalty'; this.penaltyValue = 5; this.stewardNotes = ''; } toApplyPenaltyCommand(raceId: string, driverId: string, stewardId: string, protestId: string): ApplyPenaltyCommandDTO { const reason = this.decision === 'uphold' ? DEFAULT_PROTEST_REASON : 'Protest dismissed'; return { raceId, driverId, stewardId, type: this.penaltyType, value: this.getPenaltyValue(), reason, protestId, notes: this.stewardNotes, }; } private getPenaltyValue(): number { // Some penalties don't require a value const penaltiesWithoutValue: PenaltyType[] = ['disqualification', 'warning']; return penaltiesWithoutValue.includes(this.penaltyType) ? 0 : this.penaltyValue; } }