99 lines
3.1 KiB
TypeScript
99 lines
3.1 KiB
TypeScript
/**
|
|
* Domain Entity: LeagueScoringConfig
|
|
*
|
|
* Represents the scoring configuration for a league season.
|
|
*/
|
|
|
|
import type { IEntity } from '@core/shared/domain';
|
|
import { RacingDomainValidationError } from '../errors/RacingDomainError';
|
|
import type { ChampionshipConfig } from '../types/ChampionshipConfig';
|
|
import { SeasonId } from './season/SeasonId';
|
|
import { ScoringPresetId } from './ScoringPresetId';
|
|
import { LeagueScoringConfigId } from './LeagueScoringConfigId';
|
|
|
|
export interface LeagueScoringConfigProps {
|
|
id?: string;
|
|
seasonId: string;
|
|
scoringPresetId?: string;
|
|
championships: ChampionshipConfig[];
|
|
}
|
|
|
|
export interface LeagueScoringConfigRehydrateProps {
|
|
id: string;
|
|
seasonId: string;
|
|
scoringPresetId?: string;
|
|
championships: ChampionshipConfig[];
|
|
}
|
|
|
|
export class LeagueScoringConfig implements IEntity<LeagueScoringConfigId> {
|
|
readonly id: LeagueScoringConfigId;
|
|
readonly seasonId: SeasonId;
|
|
readonly scoringPresetId: ScoringPresetId | undefined;
|
|
readonly championships: ChampionshipConfig[];
|
|
|
|
private constructor(props: {
|
|
id: LeagueScoringConfigId;
|
|
seasonId: SeasonId;
|
|
scoringPresetId?: ScoringPresetId;
|
|
championships: ChampionshipConfig[];
|
|
}) {
|
|
this.id = props.id;
|
|
this.seasonId = props.seasonId;
|
|
this.scoringPresetId = props.scoringPresetId;
|
|
this.championships = props.championships;
|
|
}
|
|
|
|
static create(props: LeagueScoringConfigProps): LeagueScoringConfig {
|
|
this.validate(props);
|
|
|
|
const idString = props.id && props.id.trim().length > 0 ? props.id : this.generateId(props.seasonId);
|
|
const id = LeagueScoringConfigId.create(idString);
|
|
|
|
const seasonId = SeasonId.create(props.seasonId);
|
|
const scoringPresetId = props.scoringPresetId ? ScoringPresetId.create(props.scoringPresetId) : undefined;
|
|
|
|
return new LeagueScoringConfig({
|
|
id,
|
|
seasonId,
|
|
...(scoringPresetId ? { scoringPresetId } : {}),
|
|
championships: props.championships,
|
|
});
|
|
}
|
|
|
|
static rehydrate(props: LeagueScoringConfigRehydrateProps): LeagueScoringConfig {
|
|
this.validate(props);
|
|
|
|
if (!props.id || props.id.trim().length === 0) {
|
|
throw new RacingDomainValidationError('Scoring config ID is required');
|
|
}
|
|
|
|
const id = LeagueScoringConfigId.create(props.id);
|
|
const seasonId = SeasonId.create(props.seasonId);
|
|
const scoringPresetId = props.scoringPresetId ? ScoringPresetId.create(props.scoringPresetId) : undefined;
|
|
|
|
return new LeagueScoringConfig({
|
|
id,
|
|
seasonId,
|
|
...(scoringPresetId ? { scoringPresetId } : {}),
|
|
championships: props.championships,
|
|
});
|
|
}
|
|
|
|
private static validate(props: LeagueScoringConfigProps): void {
|
|
if (!props.seasonId || props.seasonId.trim().length === 0) {
|
|
throw new RacingDomainValidationError('Season ID is required');
|
|
}
|
|
|
|
if (!props.championships || props.championships.length === 0) {
|
|
throw new RacingDomainValidationError('At least one championship is required');
|
|
}
|
|
}
|
|
|
|
private static generateId(seasonId: string): string {
|
|
return `scoring-config-${seasonId}`;
|
|
}
|
|
|
|
equals(other: LeagueScoringConfig): boolean {
|
|
return !!other && this.id.equals(other.id);
|
|
}
|
|
} |