import type { ValueObject } from '@core/shared/domain/ValueObject'; import { IdentityDomainValidationError } from '../errors/IdentityDomainError'; export interface ExternalRatingProvenanceProps { source: string; lastSyncedAt: Date; verified?: boolean; } export class ExternalRatingProvenance implements ValueObject { readonly source: string; readonly lastSyncedAt: Date; readonly verified: boolean; private constructor(source: string, lastSyncedAt: Date, verified: boolean) { this.source = source; this.lastSyncedAt = lastSyncedAt; this.verified = verified; } static create(props: ExternalRatingProvenanceProps): ExternalRatingProvenance { if (!props.source || props.source.trim().length === 0) { throw new IdentityDomainValidationError('Provenance source cannot be empty'); } if (!props.lastSyncedAt || isNaN(props.lastSyncedAt.getTime())) { throw new IdentityDomainValidationError('Provenance lastSyncedAt must be a valid date'); } const trimmedSource = props.source.trim(); const verified = props.verified ?? false; return new ExternalRatingProvenance(trimmedSource, props.lastSyncedAt, verified); } static restore(props: ExternalRatingProvenanceProps): ExternalRatingProvenance { return new ExternalRatingProvenance(props.source, props.lastSyncedAt, props.verified ?? false); } get props(): ExternalRatingProvenanceProps { return { source: this.source, lastSyncedAt: this.lastSyncedAt, verified: this.verified, }; } equals(other: ValueObject): boolean { return ( this.source === other.props.source && this.lastSyncedAt.getTime() === other.props.lastSyncedAt.getTime() && this.verified === other.props.verified ); } toString(): string { return `${this.source}:${this.lastSyncedAt.toISOString()}:${this.verified ? 'verified' : 'unverified'}`; } markVerified(): ExternalRatingProvenance { return new ExternalRatingProvenance(this.source, this.lastSyncedAt, true); } updateLastSyncedAt(date: Date): ExternalRatingProvenance { return new ExternalRatingProvenance(this.source, date, this.verified); } }