Files
dating-app-backend/src/modules/media/media.service.ts
Oscar bc3e48bcad upd
2026-06-02 16:22:53 +03:00

86 lines
2.6 KiB
TypeScript

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');
}
}