98 lines
2.2 KiB
TypeScript
98 lines
2.2 KiB
TypeScript
/**
|
|
* Domain Value Object: SessionDuration
|
|
*
|
|
* Represents the duration of a racing session in minutes.
|
|
* Enforces reasonable limits for different session types.
|
|
*/
|
|
|
|
import type { ValueObject } from '@core/shared/domain/ValueObject';
|
|
import { RacingDomainValidationError } from '../errors/RacingDomainError';
|
|
|
|
export interface SessionDurationProps {
|
|
value: number;
|
|
}
|
|
|
|
export class SessionDuration implements ValueObject<SessionDurationProps> {
|
|
readonly value: number;
|
|
|
|
private constructor(value: number) {
|
|
this.value = value;
|
|
}
|
|
|
|
static create(value: number): SessionDuration {
|
|
if (!Number.isInteger(value) || value <= 0) {
|
|
throw new RacingDomainValidationError('Session duration must be a positive integer');
|
|
}
|
|
|
|
// Enforce reasonable limits
|
|
if (value < 15) {
|
|
throw new RacingDomainValidationError('Session duration must be at least 15 minutes');
|
|
}
|
|
|
|
if (value > 240) {
|
|
throw new RacingDomainValidationError('Session duration cannot exceed 240 minutes (4 hours)');
|
|
}
|
|
|
|
return new SessionDuration(value);
|
|
}
|
|
|
|
/**
|
|
* Check if duration is suitable for sprint racing
|
|
*/
|
|
isSprint(): boolean {
|
|
return this.value >= 15 && this.value <= 45;
|
|
}
|
|
|
|
/**
|
|
* Check if duration is suitable for standard racing
|
|
*/
|
|
isStandard(): boolean {
|
|
return this.value > 45 && this.value <= 90;
|
|
}
|
|
|
|
/**
|
|
* Check if duration is suitable for endurance racing
|
|
*/
|
|
isEndurance(): boolean {
|
|
return this.value > 90;
|
|
}
|
|
|
|
/**
|
|
* Get duration classification
|
|
*/
|
|
getClassification(): 'sprint' | 'standard' | 'endurance' {
|
|
if (this.isSprint()) return 'sprint';
|
|
if (this.isStandard()) return 'standard';
|
|
return 'endurance';
|
|
}
|
|
|
|
/**
|
|
* Check if duration is within specified range
|
|
*/
|
|
isWithinRange(min: number, max: number): boolean {
|
|
return this.value >= min && this.value <= max;
|
|
}
|
|
|
|
/**
|
|
* Get duration in hours
|
|
*/
|
|
inHours(): number {
|
|
return this.value / 60;
|
|
}
|
|
|
|
get props(): SessionDurationProps {
|
|
return { value: this.value };
|
|
}
|
|
|
|
equals(other: ValueObject<SessionDurationProps>): boolean {
|
|
return this.value === other.props.value;
|
|
}
|
|
|
|
toString(): string {
|
|
return `${this.value} minutes`;
|
|
}
|
|
|
|
toNumber(): number {
|
|
return this.value;
|
|
}
|
|
} |