/** * Use Case: UploadMediaUseCase * * Handles the business logic for uploading media files. */ import type { IMediaRepository } from '../../domain/repositories/IMediaRepository'; import type { MediaStoragePort } from '../ports/MediaStoragePort'; import type { Logger } from '@core/shared/application'; import { Media } from '../../domain/entities/Media'; import type { IUploadMediaPresenter } from '../presenters/IUploadMediaPresenter'; import { v4 as uuidv4 } from 'uuid'; export interface UploadMediaInput { file: Express.Multer.File; uploadedBy: string; metadata?: Record; } export interface UploadMediaResult { success: boolean; mediaId?: string; url?: string; errorMessage?: string; } export interface IUploadMediaPresenter { present(result: UploadMediaResult): void; } export class UploadMediaUseCase { constructor( private readonly mediaRepo: IMediaRepository, private readonly mediaStorage: MediaStoragePort, private readonly logger: Logger, ) {} async execute( input: UploadMediaInput, presenter: IUploadMediaPresenter, ): Promise { try { this.logger.info('[UploadMediaUseCase] Starting media upload', { filename: input.file.originalname, size: input.file.size, uploadedBy: input.uploadedBy, }); // Upload file to storage service const uploadResult = await this.mediaStorage.uploadMedia(input.file.buffer, { filename: input.file.originalname, mimeType: input.file.mimetype, metadata: input.metadata, }); if (!uploadResult.success) { presenter.present({ success: false, errorMessage: uploadResult.errorMessage || 'Failed to upload media', }); return; } // Determine media type const mediaType: 'image' | 'video' | 'document' = input.file.mimetype.startsWith('image/') ? 'image' : input.file.mimetype.startsWith('video/') ? 'video' : 'document'; // Create media entity const mediaId = uuidv4(); const media = Media.create({ id: mediaId, filename: uploadResult.filename || input.file.originalname, originalName: input.file.originalname, mimeType: input.file.mimetype, size: input.file.size, url: uploadResult.url, type: mediaType, uploadedBy: input.uploadedBy, metadata: input.metadata, }); // Save to repository await this.mediaRepo.save(media); presenter.present({ success: true, mediaId, url: uploadResult.url, }); this.logger.info('[UploadMediaUseCase] Media uploaded successfully', { mediaId, url: uploadResult.url, }); } catch (error) { this.logger.error('[UploadMediaUseCase] Error uploading media', { error: error instanceof Error ? error.message : 'Unknown error', filename: input.file.originalname, }); presenter.present({ success: false, errorMessage: 'Internal error occurred during media upload', }); } } }