/** * Domain Entity: Sponsor */ import { RacingDomainValidationError } from '../errors/RacingDomainError'; * * Represents a sponsor that can sponsor leagues/seasons. * Aggregate root for sponsor information. */ export interface SponsorProps { id: string; name: string; contactEmail: string; logoUrl?: string; websiteUrl?: string; createdAt: Date; } export class Sponsor { readonly id: string; readonly name: string; readonly contactEmail: string; readonly logoUrl?: string; readonly websiteUrl?: string; readonly createdAt: Date; private constructor(props: SponsorProps) { this.id = props.id; this.name = props.name; this.contactEmail = props.contactEmail; this.logoUrl = props.logoUrl; this.websiteUrl = props.websiteUrl; this.createdAt = props.createdAt; } static create(props: Omit & { createdAt?: Date }): Sponsor { this.validate(props); return new Sponsor({ ...props, createdAt: props.createdAt ?? new Date(), }); } private static validate(props: Omit): void { if (!props.id || props.id.trim().length === 0) { throw new RacingDomainValidationError('Sponsor ID is required'); } if (!props.name || props.name.trim().length === 0) { throw new RacingDomainValidationError('Sponsor name is required'); } if (props.name.length > 100) { throw new RacingDomainValidationError('Sponsor name must be 100 characters or less'); } if (!props.contactEmail || props.contactEmail.trim().length === 0) { throw new RacingDomainValidationError('Sponsor contact email is required'); } // Basic email validation const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(props.contactEmail)) { throw new RacingDomainValidationError('Invalid sponsor contact email format'); } if (props.websiteUrl && props.websiteUrl.trim().length > 0) { try { new URL(props.websiteUrl); } catch { throw new RacingDomainValidationError('Invalid sponsor website URL'); } } } /** * Update sponsor information */ update(props: Partial<{ name: string; contactEmail: string; logoUrl: string | undefined; websiteUrl: string | undefined; }>): Sponsor { const updated = { id: this.id, name: props.name ?? this.name, contactEmail: props.contactEmail ?? this.contactEmail, logoUrl: props.logoUrl !== undefined ? props.logoUrl : this.logoUrl, websiteUrl: props.websiteUrl !== undefined ? props.websiteUrl : this.websiteUrl, createdAt: this.createdAt, }; Sponsor.validate(updated); return new Sponsor(updated); } }