114 lines
3.1 KiB
TypeScript
114 lines
3.1 KiB
TypeScript
/**
|
|
* Domain Entity: LeagueMembership
|
|
*
|
|
* Represents a driver's membership in a league.
|
|
*/
|
|
|
|
import { Entity } from '@core/shared/domain/Entity';
|
|
import { RacingDomainValidationError } from '../errors/RacingDomainError';
|
|
import { JoinedAt } from '../value-objects/JoinedAt';
|
|
import { DriverId } from './DriverId';
|
|
import { JoinRequest } from './JoinRequest';
|
|
import { LeagueId } from './LeagueId';
|
|
import { MembershipRole, MembershipRoleValue } from './MembershipRole';
|
|
import { MembershipStatus, MembershipStatusValue } from './MembershipStatus';
|
|
|
|
export interface LeagueMembershipProps {
|
|
id?: string;
|
|
leagueId: string;
|
|
driverId: string;
|
|
role: string;
|
|
status?: string;
|
|
joinedAt?: Date;
|
|
}
|
|
|
|
export class LeagueMembership extends Entity<string> {
|
|
readonly leagueId: LeagueId;
|
|
readonly driverId: DriverId;
|
|
readonly role: MembershipRole;
|
|
readonly status: MembershipStatus;
|
|
readonly joinedAt: JoinedAt;
|
|
|
|
private constructor(props: {
|
|
id: string;
|
|
leagueId: LeagueId;
|
|
driverId: DriverId;
|
|
role: MembershipRole;
|
|
status: MembershipStatus;
|
|
joinedAt: JoinedAt;
|
|
}) {
|
|
super(props.id);
|
|
|
|
this.leagueId = props.leagueId;
|
|
this.driverId = props.driverId;
|
|
this.role = props.role;
|
|
this.status = props.status;
|
|
this.joinedAt = props.joinedAt;
|
|
}
|
|
|
|
static create(props: LeagueMembershipProps): LeagueMembership {
|
|
this.validate(props);
|
|
|
|
const id =
|
|
props.id && props.id.trim().length > 0
|
|
? props.id
|
|
: `${props.leagueId}:${props.driverId}`;
|
|
|
|
const leagueId = LeagueId.create(props.leagueId);
|
|
const driverId = DriverId.create(props.driverId);
|
|
const role = MembershipRole.create(props.role as MembershipRoleValue);
|
|
const status = MembershipStatus.create((props.status ?? 'pending') as MembershipStatusValue);
|
|
const joinedAt = JoinedAt.create(props.joinedAt ?? new Date());
|
|
|
|
return new LeagueMembership({
|
|
id,
|
|
leagueId,
|
|
driverId,
|
|
role,
|
|
status,
|
|
joinedAt,
|
|
});
|
|
}
|
|
|
|
static rehydrate(props: {
|
|
id: string;
|
|
leagueId: string;
|
|
driverId: string;
|
|
role: MembershipRoleValue;
|
|
status: MembershipStatusValue;
|
|
joinedAt: Date;
|
|
}): LeagueMembership {
|
|
return new LeagueMembership({
|
|
id: props.id,
|
|
leagueId: LeagueId.create(props.leagueId),
|
|
driverId: DriverId.create(props.driverId),
|
|
role: MembershipRole.create(props.role),
|
|
status: MembershipStatus.create(props.status),
|
|
joinedAt: JoinedAt.create(props.joinedAt),
|
|
});
|
|
}
|
|
|
|
private static validate(props: LeagueMembershipProps): 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');
|
|
}
|
|
|
|
if (!props.role) {
|
|
throw new RacingDomainValidationError('Membership role is required');
|
|
}
|
|
}
|
|
|
|
equals(other: Entity<string>): boolean {
|
|
if (!(other instanceof LeagueMembership)) {
|
|
return false;
|
|
}
|
|
return this.id === other.id;
|
|
}
|
|
}
|
|
|
|
export { JoinRequest, MembershipRole, MembershipStatus };
|