Some checks failed
CI / lint-typecheck (pull_request) Failing after 4m50s
CI / tests (pull_request) Has been skipped
CI / contract-tests (pull_request) Has been skipped
CI / e2e-tests (pull_request) Has been skipped
CI / comment-pr (pull_request) Has been skipped
CI / commit-types (pull_request) Has been skipped
117 lines
3.8 KiB
TypeScript
117 lines
3.8 KiB
TypeScript
/**
|
|
* Domain Entity: Track
|
|
*
|
|
* Represents a racing track/circuit in the GridPilot platform.
|
|
* Immutable entity with factory methods and domain validation.
|
|
*/
|
|
|
|
import { Entity } from '@core/shared/domain/Entity';
|
|
import { RacingDomainValidationError } from '../errors/RacingDomainError';
|
|
import { TrackCountry } from '../value-objects/TrackCountry';
|
|
import { TrackGameId } from '../value-objects/TrackGameId';
|
|
import { TrackImageUrl } from '../value-objects/TrackImageUrl';
|
|
import { TrackLength } from '../value-objects/TrackLength';
|
|
import { TrackName } from '../value-objects/TrackName';
|
|
import { TrackShortName } from '../value-objects/TrackShortName';
|
|
import { TrackTurns } from '../value-objects/TrackTurns';
|
|
|
|
export type TrackCategory = 'oval' | 'road' | 'street' | 'dirt';
|
|
export type TrackDifficulty = 'beginner' | 'intermediate' | 'advanced' | 'expert';
|
|
|
|
export class Track extends Entity<string> {
|
|
readonly name: TrackName;
|
|
readonly shortName: TrackShortName;
|
|
readonly country: TrackCountry;
|
|
readonly category: TrackCategory;
|
|
readonly difficulty: TrackDifficulty;
|
|
readonly lengthKm: TrackLength;
|
|
readonly turns: TrackTurns;
|
|
readonly imageUrl: TrackImageUrl;
|
|
readonly gameId: TrackGameId;
|
|
|
|
private constructor(props: {
|
|
id: string;
|
|
name: TrackName;
|
|
shortName: TrackShortName;
|
|
country: TrackCountry;
|
|
category: TrackCategory;
|
|
difficulty: TrackDifficulty;
|
|
lengthKm: TrackLength;
|
|
turns: TrackTurns;
|
|
imageUrl: TrackImageUrl;
|
|
gameId: TrackGameId;
|
|
}) {
|
|
super(props.id);
|
|
|
|
this.name = props.name;
|
|
this.shortName = props.shortName;
|
|
this.country = props.country;
|
|
this.category = props.category;
|
|
this.difficulty = props.difficulty;
|
|
this.lengthKm = props.lengthKm;
|
|
this.turns = props.turns;
|
|
this.imageUrl = props.imageUrl;
|
|
this.gameId = props.gameId;
|
|
}
|
|
|
|
/**
|
|
* Factory method to create a new Track entity
|
|
*/
|
|
static create(props: {
|
|
id: string;
|
|
name: string;
|
|
shortName?: string;
|
|
country: string;
|
|
category?: TrackCategory;
|
|
difficulty?: TrackDifficulty;
|
|
lengthKm: number;
|
|
turns: number;
|
|
imageUrl?: string;
|
|
gameId: string;
|
|
}): Track {
|
|
if (!props.id || props.id.trim().length === 0) {
|
|
throw new RacingDomainValidationError('Track ID is required');
|
|
}
|
|
|
|
const shortNameValue = props.shortName ?? props.name.slice(0, 3).toUpperCase();
|
|
|
|
return new Track({
|
|
id: props.id,
|
|
name: TrackName.create(props.name),
|
|
shortName: TrackShortName.create(shortNameValue),
|
|
country: TrackCountry.create(props.country),
|
|
category: props.category ?? 'road',
|
|
difficulty: props.difficulty ?? 'intermediate',
|
|
lengthKm: TrackLength.create(props.lengthKm),
|
|
turns: TrackTurns.create(props.turns),
|
|
imageUrl: TrackImageUrl.create(props.imageUrl),
|
|
gameId: TrackGameId.create(props.gameId),
|
|
});
|
|
}
|
|
|
|
update(props: Partial<{
|
|
name: string;
|
|
shortName: string;
|
|
country: string;
|
|
category: TrackCategory;
|
|
difficulty: TrackDifficulty;
|
|
lengthKm: number;
|
|
turns: number;
|
|
imageUrl: string;
|
|
gameId: string;
|
|
}>): Track {
|
|
return new Track({
|
|
id: this.id,
|
|
name: props.name ? TrackName.create(props.name) : this.name,
|
|
shortName: props.shortName ? TrackShortName.create(props.shortName) : this.shortName,
|
|
country: props.country ? TrackCountry.create(props.country) : this.country,
|
|
category: props.category ?? this.category,
|
|
difficulty: props.difficulty ?? this.difficulty,
|
|
lengthKm: props.lengthKm ? TrackLength.create(props.lengthKm) : this.lengthKm,
|
|
turns: props.turns ? TrackTurns.create(props.turns) : this.turns,
|
|
imageUrl: props.imageUrl ? TrackImageUrl.create(props.imageUrl) : this.imageUrl,
|
|
gameId: props.gameId ? TrackGameId.create(props.gameId) : this.gameId,
|
|
});
|
|
}
|
|
}
|