/** * Domain Entity: Team * * Represents a racing team in the GridPilot platform. * Implements the shared IEntity contract and encapsulates * basic invariants around identity and core properties. */ import type { IEntity } from '@core/shared/domain'; import { RacingDomainValidationError } from '../errors/RacingDomainError'; import { TeamName } from '../value-objects/TeamName'; import { TeamTag } from '../value-objects/TeamTag'; import { TeamDescription } from '../value-objects/TeamDescription'; import { DriverId } from './DriverId'; import { LeagueId } from './LeagueId'; import { TeamCreatedAt } from '../value-objects/TeamCreatedAt'; export class Team implements IEntity { readonly id: string; readonly name: TeamName; readonly tag: TeamTag; readonly description: TeamDescription; readonly ownerId: DriverId; readonly leagues: LeagueId[]; readonly createdAt: TeamCreatedAt; private constructor(props: { id: string; name: TeamName; tag: TeamTag; description: TeamDescription; ownerId: DriverId; leagues: LeagueId[]; createdAt: TeamCreatedAt; }) { this.id = props.id; this.name = props.name; this.tag = props.tag; this.description = props.description; this.ownerId = props.ownerId; this.leagues = props.leagues; this.createdAt = props.createdAt; } /** * Factory method to create a new Team entity. */ static create(props: { id: string; name: string; tag: string; description: string; ownerId: string; leagues: string[]; createdAt?: Date; }): Team { if (!props.id || props.id.trim().length === 0) { throw new RacingDomainValidationError('Team ID is required'); } if (!Array.isArray(props.leagues)) { throw new RacingDomainValidationError('Team leagues must be an array'); } return new Team({ id: props.id, name: TeamName.create(props.name), tag: TeamTag.create(props.tag), description: TeamDescription.create(props.description), ownerId: DriverId.create(props.ownerId), leagues: props.leagues.map(leagueId => LeagueId.create(leagueId)), createdAt: TeamCreatedAt.create(props.createdAt ?? new Date()), }); } /** * Create a copy with updated properties. */ update(props: Partial<{ name: string; tag: string; description: string; ownerId: string; leagues: string[]; }>): Team { const nextName = 'name' in props ? TeamName.create(props.name!) : this.name; const nextTag = 'tag' in props ? TeamTag.create(props.tag!) : this.tag; const nextDescription = 'description' in props ? TeamDescription.create(props.description!) : this.description; const nextOwnerId = 'ownerId' in props ? DriverId.create(props.ownerId!) : this.ownerId; const nextLeagues = 'leagues' in props ? props.leagues!.map(leagueId => LeagueId.create(leagueId)) : this.leagues; return new Team({ id: this.id, name: nextName, tag: nextTag, description: nextDescription, ownerId: nextOwnerId, leagues: nextLeagues, createdAt: this.createdAt, }); } }