move to storage service

This commit is contained in:
2024-03-15 13:37:07 +01:00
parent b2a971fd30
commit 22bc42f635
11 changed files with 132 additions and 1295 deletions

View File

@@ -1,6 +1,7 @@
import { join } from 'path'
import * as process from 'process'
import { StorageModule } from '@it-incubator/storage-sdk'
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'
import { CqrsModule } from '@nestjs/cqrs'
import { ServeStaticModule } from '@nestjs/serve-static'
@@ -28,6 +29,12 @@ import { ConfigModule } from './settings/config.module'
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'client'),
}),
StorageModule.register({
baseURL: process.env.STORAGE_SERVICE_URL,
headers: {
'service-token': process.env.STORAGE_SERVICE_TOKEN,
},
}),
MailerModule.forRoot({
transport: {
host: process.env.AWS_SES_SMTP_HOST,

View File

@@ -1,46 +1,35 @@
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
import { CreateFileDto, FileType, StorageService } from '@it-incubator/storage-sdk'
import { Injectable } from '@nestjs/common'
import { v4 as uuid } from 'uuid'
import { PrismaService } from '../../prisma.service'
@Injectable()
export class FileUploadService {
constructor(private prismaService: PrismaService) {}
constructor(
private prismaService: PrismaService,
private storageService: StorageService
) {}
async uploadFile(dataBuffer: Buffer, fileName: string) {
const key = `${uuid()}-${fileName}`
const bucketName = process.env.AWS_BUCKET_NAME
const region = 'eu-central-1'
const s3 = new S3Client({
region,
credentials: {
accessKeyId: process.env.AWS_S3_ACCESS_KEY,
secretAccessKey: process.env.AWS_S3_SECRET_ACCESS_KEY,
},
})
const encodeFileName = encodeURIComponent(key)
private async uploadFileToStorageService(dto: CreateFileDto) {
return await this.storageService.create(dto).then(data => data.data)
}
const fileUrl = `https://${bucketName}.s3.${region}.amazonaws.com/${encodeFileName}`
async uploadFile(file: CreateFileDto['file']) {
try {
const savedFile = await this.uploadFileToStorageService({
fileType: FileType.Image,
file,
})
const fileStorageInDB = {
fileName,
fileUrl,
key,
return this.prismaService.fileEntity.create({
data: {
fileName: savedFile.name,
fileUrl: savedFile.url,
key: savedFile.url,
},
})
} catch (e) {
console.log(e)
}
const putCommand = new PutObjectCommand({
Bucket: bucketName,
Body: dataBuffer,
Key: key,
ContentDisposition: 'inline',
ContentType: `image/${fileName.split('.').at(-1)}`,
})
await s3.send(putCommand)
return this.prismaService.fileEntity.create({
data: fileStorageInDB,
})
}
}

View File

@@ -25,10 +25,7 @@ export class UpdateUserHandler implements ICommandHandler<UpdateUserCommand> {
let avatar: string | null
if (command.avatar) {
const addAvatarImagePromise = this.fileUploadService.uploadFile(
command.avatar?.buffer,
command.avatar?.originalname
)
const addAvatarImagePromise = this.fileUploadService.uploadFile(command.avatar)
const result = await addAvatarImagePromise

View File

@@ -35,32 +35,20 @@ export class UpdateCardHandler implements ICommandHandler<UpdateCardCommand> {
let questionImg, answerImg
if (command.questionImg && command.answerImg) {
const addQuestionImagePromise = this.fileUploadService.uploadFile(
command.questionImg?.buffer,
command.questionImg?.originalname
)
const addAnswerImagePromise = this.fileUploadService.uploadFile(
command.answerImg?.buffer,
command.answerImg?.originalname
)
const addQuestionImagePromise = this.fileUploadService.uploadFile(command.questionImg)
const addAnswerImagePromise = this.fileUploadService.uploadFile(command.answerImg)
const result = await Promise.all([addQuestionImagePromise, addAnswerImagePromise])
questionImg = result[0].fileUrl
answerImg = result[1].fileUrl
} else if (command.answerImg) {
const addAnswerImagePromise = this.fileUploadService.uploadFile(
command.answerImg?.buffer,
command.answerImg?.originalname
)
const addAnswerImagePromise = this.fileUploadService.uploadFile(command.answerImg)
const result = await addAnswerImagePromise
answerImg = result.fileUrl
} else if (command.questionImg) {
const addQuestionImagePromise = this.fileUploadService.uploadFile(
command.questionImg?.buffer,
command.questionImg?.originalname
)
const addQuestionImagePromise = this.fileUploadService.uploadFile(command.questionImg)
const result = await addQuestionImagePromise
questionImg = result.fileUrl

View File

@@ -43,6 +43,7 @@ import {
PaginatedDecksWithMaxCardsCount,
} from './entities/deck.entity'
import { MinMaxCards } from './entities/min-max-cards.entity'
import { DecksRepository } from './infrastructure/decks.repository'
import {
CreateCardCommand,
CreateDeckCommand,
@@ -60,7 +61,10 @@ import {
@ApiTags('Decks')
@Controller('decks')
export class DecksController {
constructor(private commandBus: CommandBus) {}
constructor(
private commandBus: CommandBus,
private decksRepository: DecksRepository
) {}
@HttpCode(HttpStatus.PARTIAL_CONTENT)
@ApiOperation({
@@ -89,6 +93,25 @@ export class DecksController {
return this.commandBus.execute(new GetAllDecksV2Command({ ...finalQuery, userId: req.user.id }))
}
@HttpCode(HttpStatus.PARTIAL_CONTENT)
@ApiOperation({ description: 'Retrieve paginated decks list.', summary: 'Paginated decks list' })
@ApiUnauthorizedResponse({ description: 'Unauthorized' })
@UseGuards(JwtAuthGuard)
@Version('2')
@Get('empty')
async findAllEmpty(@Query() query: GetAllDecksDto, @Req() req) {
const result: PaginatedDecks = await this.commandBus.execute(
new GetAllDecksV2Command({
itemsPerPage: 5000,
minCardsCount: 0,
maxCardsCount: 0,
userId: req.user.id,
})
)
return this.decksRepository.deleteManyById(result.items.map(({ id }) => id))
}
@HttpCode(HttpStatus.OK)
@ApiOperation({
description: 'Retrieve the minimum and maximum amount of cards in a deck.',

View File

@@ -294,6 +294,21 @@ LIMIT $${conditions.length + havingConditions.length + 1} OFFSET $${
}
}
public async deleteManyById(id: string[]) {
try {
return await this.prisma.deck.deleteMany({
where: {
id: {
in: id,
},
},
})
} catch (e) {
this.logger.error(e?.message)
throw new InternalServerErrorException(e?.message)
}
}
public async deleteDeckById(id: string) {
try {
return await this.prisma.deck.delete({

View File

@@ -38,32 +38,20 @@ export class CreateCardHandler implements ICommandHandler<CreateCardCommand> {
}
if (command.questionImg && command.answerImg) {
const addQuestionImagePromise = this.fileUploadService.uploadFile(
command.questionImg?.buffer,
command.questionImg?.originalname
)
const addAnswerImagePromise = this.fileUploadService.uploadFile(
command.answerImg?.buffer,
command.answerImg?.originalname
)
const addQuestionImagePromise = this.fileUploadService.uploadFile(command.questionImg)
const addAnswerImagePromise = this.fileUploadService.uploadFile(command.answerImg)
const result = await Promise.all([addQuestionImagePromise, addAnswerImagePromise])
questionImg = result[0].fileUrl
answerImg = result[1].fileUrl
} else if (command.answerImg) {
const addAnswerImagePromise = this.fileUploadService.uploadFile(
command.answerImg?.buffer,
command.answerImg?.originalname
)
const addAnswerImagePromise = this.fileUploadService.uploadFile(command.answerImg)
const result = await addAnswerImagePromise
answerImg = result.fileUrl
} else if (command.questionImg) {
const addQuestionImagePromise = this.fileUploadService.uploadFile(
command.questionImg?.buffer,
command.questionImg?.originalname
)
const addQuestionImagePromise = this.fileUploadService.uploadFile(command.questionImg)
const result = await addQuestionImagePromise
questionImg = result.fileUrl

View File

@@ -23,10 +23,7 @@ export class CreateDeckHandler implements ICommandHandler<CreateDeckCommand> {
let cover
if (command.cover) {
const result = await this.fileUploadService.uploadFile(
command.cover.buffer,
command.cover.originalname
)
const result = await this.fileUploadService.uploadFile(command.cover)
cover = result.fileUrl
}

View File

@@ -35,10 +35,7 @@ export class UpdateDeckHandler implements ICommandHandler<UpdateDeckCommand> {
let cover
if (command.cover) {
const result = await this.fileUploadService.uploadFile(
command.cover.buffer,
command.cover.originalname
)
const result = await this.fileUploadService.uploadFile(command.cover)
cover = result.fileUrl
} else if (command.deck.cover === '') {