Files
gridpilot.gg/core/racing/domain/entities/JoinRequest.ts
2025-12-23 11:25:08 +01:00

61 lines
1.8 KiB
TypeScript

/**
* Domain Entity: JoinRequest
*
* Represents a request to join a league.
*/
import type { IEntity } from '@core/shared/domain';
import { RacingDomainValidationError } from '../errors/RacingDomainError';
import { LeagueId } from './LeagueId';
import { LeagueOwnerId } from './LeagueOwnerId';
import { JoinedAt } from '../value-objects/JoinedAt';
export interface JoinRequestProps {
id?: string;
leagueId: string;
driverId: string;
requestedAt?: Date;
message?: string;
}
export class JoinRequest implements IEntity<string> {
readonly id: string;
readonly leagueId: LeagueId;
readonly driverId: LeagueOwnerId;
readonly requestedAt: JoinedAt;
readonly message: string | undefined;
private constructor(props: { id: string; leagueId: string; driverId: string; requestedAt: Date; message?: string }) {
this.id = props.id;
this.leagueId = LeagueId.create(props.leagueId);
this.driverId = LeagueOwnerId.create(props.driverId);
this.requestedAt = JoinedAt.create(props.requestedAt);
this.message = props.message;
}
static create(props: JoinRequestProps): JoinRequest {
this.validate(props);
const id = props.id && props.id.trim().length > 0 ? props.id : `${props.leagueId}:${props.driverId}`;
const requestedAt = props.requestedAt ?? new Date();
const message = props.message;
return new JoinRequest({
id,
leagueId: props.leagueId,
driverId: props.driverId,
requestedAt,
...(message !== undefined && { message }),
});
}
private static validate(props: JoinRequestProps): void {
if (!props.leagueId || props.leagueId.trim().length === 0) {
throw new RacingDomainValidationError('League ID is required');
}
if (!props.driverId || props.driverId.trim().length === 0) {
throw new RacingDomainValidationError('Driver ID is required');
}
}
}