59 lines
1.7 KiB
TypeScript
59 lines
1.7 KiB
TypeScript
import type { ValueObject } from '@core/shared/domain/ValueObject';
|
|
import { RacingDomainValidationError } from '../errors/RacingDomainError';
|
|
|
|
export type SeasonDropStrategy = 'none' | 'bestNResults' | 'dropWorstN';
|
|
|
|
export interface SeasonDropPolicyProps {
|
|
strategy: SeasonDropStrategy;
|
|
/**
|
|
* Number of results to consider for strategies that require a count.
|
|
* - bestNResults: keep best N
|
|
* - dropWorstN: drop worst N
|
|
*/
|
|
n?: number;
|
|
}
|
|
|
|
export class SeasonDropPolicy implements ValueObject<SeasonDropPolicyProps> {
|
|
readonly strategy: SeasonDropStrategy;
|
|
readonly n?: number;
|
|
|
|
constructor(props: SeasonDropPolicyProps) {
|
|
if (!props.strategy) {
|
|
throw new RacingDomainValidationError(
|
|
'SeasonDropPolicy.strategy is required',
|
|
);
|
|
}
|
|
|
|
if (props.strategy === 'bestNResults' || props.strategy === 'dropWorstN') {
|
|
if (props.n === undefined || !Number.isInteger(props.n) || props.n <= 0) {
|
|
throw new RacingDomainValidationError(
|
|
'SeasonDropPolicy.n must be a positive integer when using bestNResults or dropWorstN',
|
|
);
|
|
}
|
|
}
|
|
|
|
if (props.strategy === 'none' && props.n !== undefined) {
|
|
throw new RacingDomainValidationError(
|
|
'SeasonDropPolicy.n must be undefined when strategy is none',
|
|
);
|
|
}
|
|
|
|
this.strategy = props.strategy;
|
|
if (props.n !== undefined) {
|
|
this.n = props.n;
|
|
}
|
|
}
|
|
|
|
get props(): SeasonDropPolicyProps {
|
|
return {
|
|
strategy: this.strategy,
|
|
...(this.n !== undefined ? { n: this.n } : {}),
|
|
};
|
|
}
|
|
|
|
equals(other: ValueObject<SeasonDropPolicyProps>): boolean {
|
|
const a = this.props;
|
|
const b = other.props;
|
|
return a.strategy === b.strategy && a.n === b.n;
|
|
}
|
|
} |