Files
gridpilot.gg/packages/racing/domain/value-objects/SeasonScoringConfig.ts
2025-12-12 14:23:40 +01:00

66 lines
1.9 KiB
TypeScript

import { RacingDomainValidationError } from '../errors/RacingDomainError';
import type { IValueObject } from '@gridpilot/shared/domain';
/**
* Value Object: SeasonScoringConfig
*
* Represents the scoring configuration owned by a Season.
* It is intentionally lightweight and primarily captures which
* preset (or custom mode) is applied for this Season.
*
* Detailed championship scoring rules are still modeled via
* `LeagueScoringConfig` and related types.
*/
export interface SeasonScoringConfigProps {
/**
* Identifier of the scoring preset applied to this Season.
* Examples:
* - 'sprint-main-driver'
* - 'club-default'
* - 'endurance-main-double'
* - 'custom'
*/
scoringPresetId: string;
/**
* Whether the Season uses custom scoring rather than a pure preset.
* When true, `scoringPresetId` acts as a label rather than a strict preset key.
*/
customScoringEnabled?: boolean;
}
export class SeasonScoringConfig
implements IValueObject<SeasonScoringConfigProps>
{
readonly scoringPresetId: string;
readonly customScoringEnabled: boolean;
constructor(params: SeasonScoringConfigProps) {
if (!params.scoringPresetId || params.scoringPresetId.trim().length === 0) {
throw new RacingDomainValidationError(
'SeasonScoringConfig.scoringPresetId must be a non-empty string',
);
}
this.scoringPresetId = params.scoringPresetId.trim();
this.customScoringEnabled = Boolean(params.customScoringEnabled);
}
get props(): SeasonScoringConfigProps {
return {
scoringPresetId: this.scoringPresetId,
...(this.customScoringEnabled
? { customScoringEnabled: this.customScoringEnabled }
: {}),
};
}
equals(other: IValueObject<SeasonScoringConfigProps>): boolean {
const a = this.props;
const b = other.props;
return (
a.scoringPresetId === b.scoringPresetId &&
Boolean(a.customScoringEnabled) === Boolean(b.customScoringEnabled)
);
}
}