This commit is contained in:
Oscar
2026-06-02 16:22:53 +03:00
parent dc44cdd639
commit bc3e48bcad
37 changed files with 973 additions and 1894 deletions

View File

@@ -1,7 +1,7 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { ForbiddenException, Injectable, NotFoundException } from '@nestjs/common';
import { eq } from 'drizzle-orm';
import { DrizzleService } from '../../database/drizzle.service';
import { media } from '../../database/schema';
import { profile, profileMedia } from '../../database/schema';
import { StorageService } from '../../storage/storage.service';
@Injectable()
@@ -11,50 +11,75 @@ export class MediaService {
private readonly storageService: StorageService,
) {}
async uploadMedia(
async upload(
userId: string,
profileId: string,
file: { buffer: Buffer; originalname: string; mimetype: string },
type: 'photo' | 'video',
type: 'photo' | 'video' | 'audio',
) {
const folder = type === 'photo' ? 'photos' : 'videos';
await this.assertOwnership(userId, profileId);
const folder = type;
const objectName = await this.storageService.uploadFile(
file.buffer,
file.originalname,
file.mimetype,
folder,
);
const publicUrl = this.storageService.getPublicUrl(objectName);
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(media)
.values({ userId, path: publicUrl, type })
.insert(profileMedia)
.values({ profileId, path, type, sortOrder: nextOrder } as any)
.returning();
return newMedia;
}
async getByUserId(userId: string) {
async getByProfileId(profileId: string) {
return this.drizzleService.db
.select()
.from(media)
.where(eq(media.userId, userId));
.from(profileMedia)
.where(eq(profileMedia.profileId, profileId))
.orderBy(profileMedia.sortOrder);
}
async deleteMedia(userId: string, mediaId: string) {
async delete(userId: string, mediaId: string) {
const [found] = await this.drizzleService.db
.select()
.from(media)
.where(eq(media.id, mediaId))
.from(profileMedia)
.where(eq(profileMedia.id, mediaId))
.limit(1);
if (!found || found.userId !== userId) {
throw new NotFoundException('Media not found');
}
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));
await this.drizzleService.db.delete(media).where(eq(media.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');
}
}