86 lines
2.5 KiB
TypeScript
86 lines
2.5 KiB
TypeScript
/**
|
|
* Domain Entity: Driver
|
|
*
|
|
* Represents a driver profile in the GridPilot platform.
|
|
* Immutable entity with factory methods and domain validation.
|
|
*/
|
|
|
|
import { RacingDomainValidationError } from '../errors/RacingDomainError';
|
|
import type { IEntity } from '@core/shared/domain';
|
|
import { IRacingId } from '../value-objects/IRacingId';
|
|
import { DriverName } from '../value-objects/driver/DriverName';
|
|
import { CountryCode } from '../value-objects/CountryCode';
|
|
import { DriverBio } from '../value-objects/driver/DriverBio';
|
|
import { JoinedAt } from '../value-objects/JoinedAt';
|
|
|
|
export class Driver implements IEntity<string> {
|
|
readonly id: string;
|
|
readonly iracingId: IRacingId;
|
|
readonly name: DriverName;
|
|
readonly country: CountryCode;
|
|
readonly bio: DriverBio | undefined;
|
|
readonly joinedAt: JoinedAt;
|
|
|
|
private constructor(props: {
|
|
id: string;
|
|
iracingId: IRacingId;
|
|
name: DriverName;
|
|
country: CountryCode;
|
|
bio?: DriverBio;
|
|
joinedAt: JoinedAt;
|
|
}) {
|
|
this.id = props.id;
|
|
this.iracingId = props.iracingId;
|
|
this.name = props.name;
|
|
this.country = props.country;
|
|
this.bio = props.bio;
|
|
this.joinedAt = props.joinedAt;
|
|
}
|
|
|
|
/**
|
|
* Factory method to create a new Driver entity
|
|
*/
|
|
static create(props: {
|
|
id: string;
|
|
iracingId: string;
|
|
name: string;
|
|
country: string;
|
|
bio?: string;
|
|
joinedAt?: Date;
|
|
}): Driver {
|
|
if (!props.id || props.id.trim().length === 0) {
|
|
throw new RacingDomainValidationError('Driver ID is required');
|
|
}
|
|
|
|
return new Driver({
|
|
id: props.id,
|
|
iracingId: IRacingId.create(props.iracingId),
|
|
name: DriverName.create(props.name),
|
|
country: CountryCode.create(props.country),
|
|
...(props.bio !== undefined ? { bio: DriverBio.create(props.bio) } : {}),
|
|
joinedAt: JoinedAt.create(props.joinedAt ?? new Date()),
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Create a copy with updated properties
|
|
*/
|
|
update(props: Partial<{
|
|
name: string;
|
|
country: string;
|
|
bio: string | undefined;
|
|
}>): Driver {
|
|
const nextName = 'name' in props ? DriverName.create(props.name!) : this.name;
|
|
const nextCountry = 'country' in props ? CountryCode.create(props.country!) : this.country;
|
|
const nextBio = 'bio' in props ? (props.bio ? DriverBio.create(props.bio) : undefined) : this.bio;
|
|
|
|
return new Driver({
|
|
id: this.id,
|
|
iracingId: this.iracingId,
|
|
name: nextName,
|
|
country: nextCountry,
|
|
...(nextBio !== undefined ? { bio: nextBio } : {}),
|
|
joinedAt: this.joinedAt,
|
|
});
|
|
}
|
|
} |