/** * 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 { 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(); return new JoinRequest({ id, leagueId: props.leagueId, driverId: props.driverId, requestedAt, message: props.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'); } } }