team rating
This commit is contained in:
100
core/racing/domain/value-objects/TeamDrivingReasonCode.ts
Normal file
100
core/racing/domain/value-objects/TeamDrivingReasonCode.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import type { IValueObject } from '@core/shared/domain';
|
||||
import { RacingDomainValidationError } from '../errors/RacingDomainError';
|
||||
|
||||
export interface TeamDrivingReasonCodeProps {
|
||||
value: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid reason codes for team driving rating events
|
||||
*/
|
||||
export const TEAM_DRIVING_REASON_CODES = [
|
||||
'RACE_PERFORMANCE',
|
||||
'RACE_GAIN_BONUS',
|
||||
'RACE_INCIDENTS',
|
||||
'RACE_DNF',
|
||||
'RACE_DSQ',
|
||||
'RACE_DNS',
|
||||
'RACE_AFK',
|
||||
'RACE_PACE',
|
||||
'RACE_DEFENSE',
|
||||
'RACE_OVERTAKE',
|
||||
'RACE_QUALIFYING',
|
||||
'RACE_CONSISTENCY',
|
||||
'RACE_TEAMWORK',
|
||||
'RACE_SPORTSMANSHIP',
|
||||
] as const;
|
||||
|
||||
export type TeamDrivingReasonCodeValue = (typeof TEAM_DRIVING_REASON_CODES)[number];
|
||||
|
||||
/**
|
||||
* Value object representing a team driving reason code
|
||||
*/
|
||||
export class TeamDrivingReasonCode implements IValueObject<TeamDrivingReasonCodeProps> {
|
||||
readonly value: TeamDrivingReasonCodeValue;
|
||||
|
||||
private constructor(value: TeamDrivingReasonCodeValue) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
static create(value: string): TeamDrivingReasonCode {
|
||||
if (!value || value.trim().length === 0) {
|
||||
throw new RacingDomainValidationError('Team driving reason code cannot be empty');
|
||||
}
|
||||
|
||||
// Strict validation: no leading/trailing whitespace allowed
|
||||
if (value !== value.trim()) {
|
||||
throw new RacingDomainValidationError(
|
||||
`Team driving reason code cannot have leading or trailing whitespace: "${value}"`
|
||||
);
|
||||
}
|
||||
|
||||
if (!TEAM_DRIVING_REASON_CODES.includes(value as TeamDrivingReasonCodeValue)) {
|
||||
throw new RacingDomainValidationError(
|
||||
`Invalid team driving reason code: ${value}. Valid options: ${TEAM_DRIVING_REASON_CODES.join(', ')}`
|
||||
);
|
||||
}
|
||||
|
||||
return new TeamDrivingReasonCode(value as TeamDrivingReasonCodeValue);
|
||||
}
|
||||
|
||||
get props(): TeamDrivingReasonCodeProps {
|
||||
return { value: this.value };
|
||||
}
|
||||
|
||||
equals(other: IValueObject<TeamDrivingReasonCodeProps>): boolean {
|
||||
return this.value === other.props.value;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is a performance-related reason
|
||||
*/
|
||||
isPerformance(): boolean {
|
||||
return ['RACE_PERFORMANCE', 'RACE_GAIN_BONUS', 'RACE_PACE', 'RACE_QUALIFYING', 'RACE_CONSISTENCY'].includes(this.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is a penalty-related reason
|
||||
*/
|
||||
isPenalty(): boolean {
|
||||
return ['RACE_INCIDENTS', 'RACE_DNF', 'RACE_DSQ', 'RACE_DNS', 'RACE_AFK'].includes(this.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is a positive reason
|
||||
*/
|
||||
isPositive(): boolean {
|
||||
return ['RACE_PERFORMANCE', 'RACE_GAIN_BONUS', 'RACE_OVERTAKE', 'RACE_DEFENSE', 'RACE_TEAMWORK', 'RACE_SPORTSMANSHIP'].includes(this.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is a negative reason
|
||||
*/
|
||||
isNegative(): boolean {
|
||||
return ['RACE_INCIDENTS', 'RACE_DNF', 'RACE_DSQ', 'RACE_DNS', 'RACE_AFK'].includes(this.value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user