/** * Domain Entity: Media * * Represents a media file (image, video, etc.) stored in the system. */ import type { IEntity } from '@core/shared/domain'; import { MediaUrl } from '../value-objects/MediaUrl'; export type MediaType = 'image' | 'video' | 'document'; export interface MediaProps { id: string; filename: string; originalName: string; mimeType: string; size: number; url: string; type: MediaType; uploadedBy: string; uploadedAt: Date; metadata?: Record | undefined; } export class Media implements IEntity { readonly id: string; readonly filename: string; readonly originalName: string; readonly mimeType: string; readonly size: number; readonly url: MediaUrl; readonly type: MediaType; readonly uploadedBy: string; readonly uploadedAt: Date; readonly metadata?: Record | undefined; private constructor(props: MediaProps) { this.id = props.id; this.filename = props.filename; this.originalName = props.originalName; this.mimeType = props.mimeType; this.size = props.size; this.url = MediaUrl.create(props.url); this.type = props.type; this.uploadedBy = props.uploadedBy; this.uploadedAt = props.uploadedAt; this.metadata = props.metadata; } static create(props: { id: string; filename: string; originalName: string; mimeType: string; size: number; url: string; type: MediaType; uploadedBy: string; metadata?: Record; }): Media { if (!props.filename) { throw new Error('Filename is required'); } if (!props.url) { throw new Error('URL is required'); } if (!props.uploadedBy) { throw new Error('Uploaded by is required'); } return new Media({ ...props, uploadedAt: new Date(), }); } static reconstitute(props: MediaProps): Media { return new Media(props); } toProps(): MediaProps { return { id: this.id, filename: this.filename, originalName: this.originalName, mimeType: this.mimeType, size: this.size, url: this.url.value, type: this.type, uploadedBy: this.uploadedBy, uploadedAt: this.uploadedAt, metadata: this.metadata, }; } }