Files
gridpilot.gg/core/media/domain/entities/Media.ts
2025-12-23 11:25:08 +01:00

95 lines
2.2 KiB
TypeScript

/**
* 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<string, any> | undefined;
}
export class Media implements IEntity<string> {
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<string, any> | 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<string, any>;
}): 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,
};
}
}