mirror of
https://github.com/ershisan99/flashcards-api.git
synced 2025-12-17 05:09:26 +00:00
add file upload service
This commit is contained in:
@@ -10,7 +10,7 @@ import { JwtRefreshStrategy } from './modules/auth/strategies/jwt-refresh.strate
|
||||
import { CqrsModule } from '@nestjs/cqrs'
|
||||
import { DecksModule } from './modules/decks/decks.module'
|
||||
import { CardsModule } from './modules/cards/cards.module'
|
||||
import { LoggerMiddleware } from './infrastructure/middlewares/logs-middleware'
|
||||
import { FileUploadService } from './infrastructure/file-upload-service/file-upload.service'
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -21,7 +21,6 @@ import { LoggerMiddleware } from './infrastructure/middlewares/logs-middleware'
|
||||
DecksModule,
|
||||
CardsModule,
|
||||
PrismaModule,
|
||||
|
||||
MailerModule.forRoot({
|
||||
transport: {
|
||||
host: process.env.AWS_SES_SMTP_HOST,
|
||||
@@ -35,8 +34,8 @@ import { LoggerMiddleware } from './infrastructure/middlewares/logs-middleware'
|
||||
}),
|
||||
],
|
||||
controllers: [],
|
||||
providers: [JwtStrategy, JwtRefreshStrategy],
|
||||
exports: [CqrsModule],
|
||||
providers: [JwtStrategy, JwtRefreshStrategy, FileUploadService],
|
||||
exports: [CqrsModule, FileUploadService],
|
||||
})
|
||||
export class AppModule implements NestModule {
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
import { PrismaService } from '../../prisma.service'
|
||||
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
|
||||
|
||||
@Injectable()
|
||||
export class FileUploadService {
|
||||
constructor(private prismaService: PrismaService) {}
|
||||
|
||||
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)
|
||||
|
||||
const fileUrl = `https://${bucketName}.s3.${region}.amazonaws.com/${encodeFileName}`
|
||||
|
||||
const fileStorageInDB = {
|
||||
fileName,
|
||||
fileUrl,
|
||||
key,
|
||||
}
|
||||
|
||||
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,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import { CardsService } from './cards.service'
|
||||
import { UpdateCardDto } from './dto/update-card.dto'
|
||||
import { CommandBus } from '@nestjs/cqrs'
|
||||
import { DeleteCardByIdCommand, GetDeckByIdCommand } from './use-cases'
|
||||
import { DeleteCardByIdCommand, GetDeckByIdCommand, UpdateCardCommand } from './use-cases'
|
||||
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard'
|
||||
import { FileFieldsInterceptor } from '@nestjs/platform-express'
|
||||
|
||||
@@ -44,7 +44,9 @@ export class CardsController {
|
||||
) {
|
||||
console.log({ body })
|
||||
console.log(files)
|
||||
// return this.commandBus.execute(new UpdateCardCommand(id, body, req.user.id))
|
||||
return this.commandBus.execute(
|
||||
new UpdateCardCommand(id, body, req.user.id, files.answerImg[0], files.questionImg[0])
|
||||
)
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
|
||||
@@ -4,13 +4,14 @@ import { CardsController } from './cards.controller'
|
||||
import { CqrsModule } from '@nestjs/cqrs'
|
||||
import { DeleteCardByIdHandler, GetDeckByIdHandler, UpdateCardHandler } from './use-cases'
|
||||
import { CardsRepository } from './infrastructure/cards.repository'
|
||||
import { FileUploadService } from '../../infrastructure/file-upload-service/file-upload.service'
|
||||
|
||||
const commandHandlers = [GetDeckByIdHandler, DeleteCardByIdHandler, UpdateCardHandler]
|
||||
|
||||
@Module({
|
||||
imports: [CqrsModule],
|
||||
controllers: [CardsController],
|
||||
providers: [CardsService, CardsRepository, ...commandHandlers],
|
||||
providers: [CardsService, CardsRepository, FileUploadService, ...commandHandlers],
|
||||
exports: [CqrsModule],
|
||||
})
|
||||
export class CardsModule {}
|
||||
|
||||
@@ -2,18 +2,24 @@ import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'
|
||||
import { CardsRepository } from '../infrastructure/cards.repository'
|
||||
import { UpdateCardDto } from '../dto/update-card.dto'
|
||||
import { BadRequestException, NotFoundException } from '@nestjs/common'
|
||||
import { FileUploadService } from '../../../infrastructure/file-upload-service/file-upload.service'
|
||||
|
||||
export class UpdateCardCommand {
|
||||
constructor(
|
||||
public readonly cardId: string,
|
||||
public readonly card: UpdateCardDto,
|
||||
public readonly userId: string
|
||||
public readonly userId: string,
|
||||
public readonly answerImg?: Express.Multer.File,
|
||||
public readonly questionImg?: Express.Multer.File
|
||||
) {}
|
||||
}
|
||||
|
||||
@CommandHandler(UpdateCardCommand)
|
||||
export class UpdateCardHandler implements ICommandHandler<UpdateCardCommand> {
|
||||
constructor(private readonly cardsRepository: CardsRepository) {}
|
||||
constructor(
|
||||
private readonly cardsRepository: CardsRepository,
|
||||
private readonly fileUploadService: FileUploadService
|
||||
) {}
|
||||
|
||||
async execute(command: UpdateCardCommand) {
|
||||
const card = await this.cardsRepository.findCardById(command.cardId)
|
||||
@@ -24,6 +30,32 @@ export class UpdateCardHandler implements ICommandHandler<UpdateCardCommand> {
|
||||
throw new BadRequestException(`You can't change a card that you don't own`)
|
||||
}
|
||||
|
||||
return await this.cardsRepository.updateCardById(command.cardId, command.card)
|
||||
const addQuestionImagePromise = this.fileUploadService.uploadFile(
|
||||
command.questionImg.buffer,
|
||||
command.questionImg.originalname
|
||||
)
|
||||
const addAnswerImagePromise = this.fileUploadService.uploadFile(
|
||||
command.answerImg.buffer,
|
||||
command.answerImg.originalname
|
||||
)
|
||||
|
||||
let questionImg, answerImg
|
||||
|
||||
if (command.questionImg && command.answerImg) {
|
||||
const result = await Promise.all([addQuestionImagePromise, addAnswerImagePromise])
|
||||
questionImg = result[0].fileUrl
|
||||
answerImg = result[1].fileUrl
|
||||
} else if (command.answerImg) {
|
||||
const result = await addAnswerImagePromise
|
||||
answerImg = result.fileUrl
|
||||
} else if (command.questionImg) {
|
||||
const result = await addQuestionImagePromise
|
||||
questionImg = result.fileUrl
|
||||
}
|
||||
return await this.cardsRepository.updateCardById(command.cardId, {
|
||||
...command.card,
|
||||
answerImg,
|
||||
questionImg,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user