import { ForbiddenException, Injectable, NotFoundException } from '@nestjs/common'; import { eq } from 'drizzle-orm'; import { DrizzleService } from '../../database/drizzle.service'; import { profile, profileMedia } from '../../database/schema'; import { StorageService } from '../../storage/storage.service'; @Injectable() export class MediaService { constructor( private readonly drizzleService: DrizzleService, private readonly storageService: StorageService, ) {} async upload( userId: string, profileId: string, file: { buffer: Buffer; originalname: string; mimetype: string }, type: 'photo' | 'video' | 'audio', ) { await this.assertOwnership(userId, profileId); const folder = type; const objectName = await this.storageService.uploadFile( file.buffer, file.originalname, file.mimetype, folder, ); const path = this.storageService.getPublicUrl(objectName); const existing = await this.drizzleService.db .select({ sortOrder: profileMedia.sortOrder }) .from(profileMedia) .where(eq(profileMedia.profileId, profileId)) .orderBy(profileMedia.sortOrder); const nextOrder = existing.length > 0 ? (existing[existing.length - 1].sortOrder ?? 0) + 1 : 0; const [newMedia] = await this.drizzleService.db .insert(profileMedia) .values({ profileId, path, type, sortOrder: nextOrder } as any) .returning(); return newMedia; } async getByProfileId(profileId: string) { return this.drizzleService.db .select() .from(profileMedia) .where(eq(profileMedia.profileId, profileId)) .orderBy(profileMedia.sortOrder); } async delete(userId: string, mediaId: string) { const [found] = await this.drizzleService.db .select() .from(profileMedia) .where(eq(profileMedia.id, mediaId)) .limit(1); if (!found) throw new NotFoundException('Media not found'); await this.assertOwnership(userId, found.profileId); const objectName = found.path.split('/').slice(-2).join('/'); await this.storageService.deleteFile(objectName).catch(() => {}); await this.drizzleService.db.delete(profileMedia).where(eq(profileMedia.id, mediaId)); return { message: 'Media deleted' }; } private async assertOwnership(userId: string, profileId: string) { const [found] = await this.drizzleService.db .select({ userId: profile.userId }) .from(profile) .where(eq(profile.id, profileId)) .limit(1); if (!found) throw new NotFoundException('Profile not found'); if (found.userId !== userId) throw new ForbiddenException('Profile does not belong to you'); } }