mirror of
https://github.com/ershisan99/flashcards-api.git
synced 2025-12-16 20:59:26 +00:00
add crete/get cards
This commit is contained in:
@@ -82,23 +82,23 @@ model Card {
|
|||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
deckId String
|
deckId String
|
||||||
userId String
|
userId String
|
||||||
question String
|
question String @db.Text
|
||||||
answer String
|
answer String @db.Text
|
||||||
grade Int
|
grade Int @default(0)
|
||||||
shots Int
|
shots Int @default(0)
|
||||||
questionImg String?
|
questionImg String?
|
||||||
answerImg String?
|
answerImg String?
|
||||||
answerVideo String?
|
answerVideo String?
|
||||||
questionVideo String?
|
questionVideo String?
|
||||||
comments String?
|
comments String?
|
||||||
type String?
|
type String?
|
||||||
rating Int
|
rating Int @default(0)
|
||||||
moreId String?
|
moreId String?
|
||||||
created DateTime @default(now())
|
created DateTime @default(now())
|
||||||
updated DateTime @updatedAt
|
updated DateTime @updatedAt
|
||||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
decks Deck @relation(fields: [deckId], references: [id], onDelete: Cascade)
|
decks Deck @relation(fields: [deckId], references: [id], onDelete: Cascade)
|
||||||
grades Grade[] // One-to-many relation
|
grades Grade[]
|
||||||
|
|
||||||
@@index([userId])
|
@@index([userId])
|
||||||
@@index([deckId])
|
@@index([deckId])
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import * as process from 'process'
|
|||||||
import { JwtRefreshStrategy } from './modules/auth/strategies/jwt-refresh.strategy'
|
import { JwtRefreshStrategy } from './modules/auth/strategies/jwt-refresh.strategy'
|
||||||
import { CqrsModule } from '@nestjs/cqrs'
|
import { CqrsModule } from '@nestjs/cqrs'
|
||||||
import { DecksModule } from './modules/decks/decks.module'
|
import { DecksModule } from './modules/decks/decks.module'
|
||||||
|
import { CardsModule } from './modules/cards/cards.module'
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -17,6 +18,7 @@ import { DecksModule } from './modules/decks/decks.module'
|
|||||||
UsersModule,
|
UsersModule,
|
||||||
AuthModule,
|
AuthModule,
|
||||||
DecksModule,
|
DecksModule,
|
||||||
|
CardsModule,
|
||||||
PrismaModule,
|
PrismaModule,
|
||||||
|
|
||||||
MailerModule.forRoot({
|
MailerModule.forRoot({
|
||||||
|
|||||||
29
src/modules/cards/cards.controller.ts
Normal file
29
src/modules/cards/cards.controller.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { Body, Controller, Delete, Get, Param, Patch, Req, UseGuards } from '@nestjs/common'
|
||||||
|
import { CardsService } from './cards.service'
|
||||||
|
import { UpdateCardDto } from './dto/update-card.dto'
|
||||||
|
import { CommandBus } from '@nestjs/cqrs'
|
||||||
|
import { DeleteDeckByIdCommand, GetDeckByIdCommand, UpdateDeckCommand } from './use-cases'
|
||||||
|
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard'
|
||||||
|
|
||||||
|
@Controller('cards')
|
||||||
|
export class CardsController {
|
||||||
|
constructor(private readonly decksService: CardsService, private commandBus: CommandBus) {}
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Get(':id')
|
||||||
|
findOne(@Param('id') id: string) {
|
||||||
|
return this.commandBus.execute(new GetDeckByIdCommand(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Patch(':id')
|
||||||
|
update(@Param('id') id: string, @Body() updateDeckDto: UpdateCardDto, @Req() req) {
|
||||||
|
return this.commandBus.execute(new UpdateDeckCommand(id, updateDeckDto, req.user.id))
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Delete(':id')
|
||||||
|
remove(@Param('id') id: string, @Req() req) {
|
||||||
|
return this.commandBus.execute(new DeleteDeckByIdCommand(id, req.user.id))
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/modules/cards/cards.module.ts
Normal file
28
src/modules/cards/cards.module.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import { Module } from '@nestjs/common'
|
||||||
|
import { CardsService } from './cards.service'
|
||||||
|
import { CardsController } from './cards.controller'
|
||||||
|
import { CqrsModule } from '@nestjs/cqrs'
|
||||||
|
import {
|
||||||
|
CreateCardHandler,
|
||||||
|
DeleteDeckByIdHandler,
|
||||||
|
GetDeckByIdHandler,
|
||||||
|
GetAllCardsInDeckHandler,
|
||||||
|
UpdateDeckHandler,
|
||||||
|
} from './use-cases'
|
||||||
|
import { CardsRepository } from './infrastructure/cards.repository'
|
||||||
|
|
||||||
|
const commandHandlers = [
|
||||||
|
CreateCardHandler,
|
||||||
|
GetAllCardsInDeckHandler,
|
||||||
|
GetDeckByIdHandler,
|
||||||
|
DeleteDeckByIdHandler,
|
||||||
|
UpdateDeckHandler,
|
||||||
|
]
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [CqrsModule],
|
||||||
|
controllers: [CardsController],
|
||||||
|
providers: [CardsService, CardsRepository, ...commandHandlers],
|
||||||
|
exports: [CqrsModule],
|
||||||
|
})
|
||||||
|
export class CardsModule {}
|
||||||
4
src/modules/cards/cards.service.ts
Normal file
4
src/modules/cards/cards.service.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import { Injectable } from '@nestjs/common'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CardsService {}
|
||||||
9
src/modules/cards/dto/create-card.dto.ts
Normal file
9
src/modules/cards/dto/create-card.dto.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { Length } from 'class-validator'
|
||||||
|
|
||||||
|
export class CreateCardDto {
|
||||||
|
@Length(3, 500)
|
||||||
|
question: string
|
||||||
|
|
||||||
|
@Length(3, 500)
|
||||||
|
answer: string
|
||||||
|
}
|
||||||
13
src/modules/cards/dto/get-all-cards.dto.ts
Normal file
13
src/modules/cards/dto/get-all-cards.dto.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { Length } from 'class-validator'
|
||||||
|
import { PaginationDto } from '../../../infrastructure/common/pagination/pagination.dto'
|
||||||
|
import { IsOptionalOrEmptyString } from '../../../infrastructure/decorators/is-optional-or-empty-string'
|
||||||
|
|
||||||
|
export class GetAllCardsInDeckDto extends PaginationDto {
|
||||||
|
@IsOptionalOrEmptyString()
|
||||||
|
@Length(1, 30)
|
||||||
|
question?: string
|
||||||
|
|
||||||
|
@IsOptionalOrEmptyString()
|
||||||
|
@Length(1, 30)
|
||||||
|
answer?: string
|
||||||
|
}
|
||||||
16
src/modules/cards/dto/update-card.dto.ts
Normal file
16
src/modules/cards/dto/update-card.dto.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { PartialType } from '@nestjs/mapped-types'
|
||||||
|
import { CreateCardDto } from './create-card.dto'
|
||||||
|
import { IsOptionalOrEmptyString } from '../../../infrastructure/decorators/is-optional-or-empty-string'
|
||||||
|
import { IsBoolean } from 'class-validator'
|
||||||
|
|
||||||
|
export class UpdateCardDto extends PartialType(CreateCardDto) {
|
||||||
|
@IsOptionalOrEmptyString()
|
||||||
|
name: string
|
||||||
|
|
||||||
|
@IsOptionalOrEmptyString()
|
||||||
|
@IsBoolean()
|
||||||
|
isPrivate: boolean
|
||||||
|
|
||||||
|
@IsOptionalOrEmptyString()
|
||||||
|
cover: string
|
||||||
|
}
|
||||||
1
src/modules/cards/entities/cards.entity.ts
Normal file
1
src/modules/cards/entities/cards.entity.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export class Card {}
|
||||||
109
src/modules/cards/infrastructure/cards.repository.ts
Normal file
109
src/modules/cards/infrastructure/cards.repository.ts
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
import { Injectable, InternalServerErrorException, Logger } from '@nestjs/common'
|
||||||
|
import { PrismaService } from '../../../prisma.service'
|
||||||
|
import { GetAllCardsInDeckDto } from '../dto/get-all-cards.dto'
|
||||||
|
import {
|
||||||
|
DEFAULT_PAGE_NUMBER,
|
||||||
|
DEFAULT_PAGE_SIZE,
|
||||||
|
} from '../../../infrastructure/common/pagination/pagination.constants'
|
||||||
|
import { CreateCardDto } from '../dto/create-card.dto'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CardsRepository {
|
||||||
|
constructor(private prisma: PrismaService) {}
|
||||||
|
private readonly logger = new Logger(CardsRepository.name)
|
||||||
|
async createCard(deckId: string, userId: string, card: CreateCardDto) {
|
||||||
|
try {
|
||||||
|
return await this.prisma.card.create({
|
||||||
|
data: {
|
||||||
|
user: {
|
||||||
|
connect: {
|
||||||
|
id: userId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
decks: {
|
||||||
|
connect: {
|
||||||
|
id: deckId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
...card,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.error(e?.message)
|
||||||
|
throw new InternalServerErrorException(e?.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async findCardsByDeckId(
|
||||||
|
deckId: string,
|
||||||
|
{
|
||||||
|
answer = undefined,
|
||||||
|
question = undefined,
|
||||||
|
currentPage = DEFAULT_PAGE_NUMBER,
|
||||||
|
pageSize = DEFAULT_PAGE_SIZE,
|
||||||
|
}: GetAllCardsInDeckDto
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
return await this.prisma.card.findMany({
|
||||||
|
where: {
|
||||||
|
decks: {
|
||||||
|
id: deckId,
|
||||||
|
},
|
||||||
|
question: {
|
||||||
|
contains: question || undefined,
|
||||||
|
},
|
||||||
|
answer: {
|
||||||
|
contains: answer || undefined,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
skip: (currentPage - 1) * pageSize,
|
||||||
|
take: pageSize,
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.error(e?.message)
|
||||||
|
throw new InternalServerErrorException(e?.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public async findDeckById(id: string) {
|
||||||
|
try {
|
||||||
|
return await this.prisma.deck.findUnique({
|
||||||
|
where: {
|
||||||
|
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({
|
||||||
|
where: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.error(e?.message)
|
||||||
|
throw new InternalServerErrorException(e?.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async updateDeckById(
|
||||||
|
id: string,
|
||||||
|
data: { name?: string; cover?: string; isPrivate?: boolean }
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
return await this.prisma.deck.update({
|
||||||
|
where: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.error(e?.message)
|
||||||
|
throw new InternalServerErrorException(e?.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/modules/cards/use-cases/delete-deck-by-id-use-case.ts
Normal file
21
src/modules/cards/use-cases/delete-deck-by-id-use-case.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'
|
||||||
|
import { CardsRepository } from '../infrastructure/cards.repository'
|
||||||
|
import { BadRequestException, NotFoundException } from '@nestjs/common'
|
||||||
|
|
||||||
|
export class DeleteDeckByIdCommand {
|
||||||
|
constructor(public readonly id: string, public readonly userId: string) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@CommandHandler(DeleteDeckByIdCommand)
|
||||||
|
export class DeleteDeckByIdHandler implements ICommandHandler<DeleteDeckByIdCommand> {
|
||||||
|
constructor(private readonly deckRepository: CardsRepository) {}
|
||||||
|
|
||||||
|
async execute(command: DeleteDeckByIdCommand) {
|
||||||
|
const deck = await this.deckRepository.findDeckById(command.id)
|
||||||
|
if (!deck) throw new NotFoundException(`Deck with id ${command.id} not found`)
|
||||||
|
if (deck.userId !== command.userId) {
|
||||||
|
throw new BadRequestException(`You can't delete a deck that you don't own`)
|
||||||
|
}
|
||||||
|
return await this.deckRepository.deleteDeckById(command.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/modules/cards/use-cases/get-deck-by-id-use-case.ts
Normal file
15
src/modules/cards/use-cases/get-deck-by-id-use-case.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'
|
||||||
|
import { CardsRepository } from '../infrastructure/cards.repository'
|
||||||
|
|
||||||
|
export class GetDeckByIdCommand {
|
||||||
|
constructor(public readonly id: string) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@CommandHandler(GetDeckByIdCommand)
|
||||||
|
export class GetDeckByIdHandler implements ICommandHandler<GetDeckByIdCommand> {
|
||||||
|
constructor(private readonly deckRepository: CardsRepository) {}
|
||||||
|
|
||||||
|
async execute(command: GetDeckByIdCommand) {
|
||||||
|
return await this.deckRepository.findDeckById(command.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
5
src/modules/cards/use-cases/index.ts
Normal file
5
src/modules/cards/use-cases/index.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export * from '../../decks/use-cases/create-card-use-case'
|
||||||
|
export * from '../../decks/use-cases/get-all-cards-in-deck-use-case'
|
||||||
|
export * from './get-deck-by-id-use-case'
|
||||||
|
export * from './delete-deck-by-id-use-case'
|
||||||
|
export * from './update-deck-use-case'
|
||||||
29
src/modules/cards/use-cases/update-deck-use-case.ts
Normal file
29
src/modules/cards/use-cases/update-deck-use-case.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
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'
|
||||||
|
|
||||||
|
export class UpdateDeckCommand {
|
||||||
|
constructor(
|
||||||
|
public readonly deckId: string,
|
||||||
|
public readonly deck: UpdateCardDto,
|
||||||
|
public readonly userId: string
|
||||||
|
) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@CommandHandler(UpdateDeckCommand)
|
||||||
|
export class UpdateDeckHandler implements ICommandHandler<UpdateDeckCommand> {
|
||||||
|
constructor(private readonly deckRepository: CardsRepository) {}
|
||||||
|
|
||||||
|
async execute(command: UpdateDeckCommand) {
|
||||||
|
const deck = await this.deckRepository.findDeckById(command.deckId)
|
||||||
|
|
||||||
|
if (!deck) throw new NotFoundException(`Deck with id ${command.deckId} not found`)
|
||||||
|
|
||||||
|
if (deck.userId !== command.userId) {
|
||||||
|
throw new BadRequestException(`You can't change a deck that you don't own`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return await this.deckRepository.updateDeckById(command.deckId, command.deck)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,12 +18,16 @@ import { CommandBus } from '@nestjs/cqrs'
|
|||||||
import {
|
import {
|
||||||
CreateDeckCommand,
|
CreateDeckCommand,
|
||||||
DeleteDeckByIdCommand,
|
DeleteDeckByIdCommand,
|
||||||
|
GetAllCardsInDeckCommand,
|
||||||
GetAllDecksCommand,
|
GetAllDecksCommand,
|
||||||
GetDeckByIdCommand,
|
GetDeckByIdCommand,
|
||||||
UpdateDeckCommand,
|
UpdateDeckCommand,
|
||||||
} from './use-cases'
|
} from './use-cases'
|
||||||
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard'
|
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard'
|
||||||
import { GetAllDecksDto } from './dto/get-all-decks.dto'
|
import { GetAllDecksDto } from './dto/get-all-decks.dto'
|
||||||
|
import { GetAllCardsInDeckDto } from '../cards/dto/get-all-cards.dto'
|
||||||
|
import { CreateCardCommand } from './use-cases/create-card-use-case'
|
||||||
|
import { CreateCardDto } from '../cards/dto/create-card.dto'
|
||||||
|
|
||||||
@Controller('decks')
|
@Controller('decks')
|
||||||
export class DecksController {
|
export class DecksController {
|
||||||
@@ -48,6 +52,18 @@ export class DecksController {
|
|||||||
return this.commandBus.execute(new GetDeckByIdCommand(id))
|
return this.commandBus.execute(new GetDeckByIdCommand(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Get(':id/cards')
|
||||||
|
findCardsInDeck(@Param('id') id: string, @Req() req, @Query() query: GetAllCardsInDeckDto) {
|
||||||
|
return this.commandBus.execute(new GetAllCardsInDeckCommand(req.user.id, id, query))
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Post(':id/cards')
|
||||||
|
createCardInDeck(@Param('id') id: string, @Req() req, @Body() card: CreateCardDto) {
|
||||||
|
return this.commandBus.execute(new CreateCardCommand(req.user.id, id, card))
|
||||||
|
}
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Patch(':id')
|
@Patch(':id')
|
||||||
update(@Param('id') id: string, @Body() updateDeckDto: UpdateDeckDto, @Req() req) {
|
update(@Param('id') id: string, @Body() updateDeckDto: UpdateDeckDto, @Req() req) {
|
||||||
|
|||||||
@@ -8,8 +8,11 @@ import {
|
|||||||
GetDeckByIdHandler,
|
GetDeckByIdHandler,
|
||||||
GetAllDecksHandler,
|
GetAllDecksHandler,
|
||||||
UpdateDeckHandler,
|
UpdateDeckHandler,
|
||||||
|
GetAllCardsInDeckHandler,
|
||||||
} from './use-cases'
|
} from './use-cases'
|
||||||
import { DecksRepository } from './infrastructure/decks.repository'
|
import { DecksRepository } from './infrastructure/decks.repository'
|
||||||
|
import { CardsRepository } from '../cards/infrastructure/cards.repository'
|
||||||
|
import { CreateCardHandler } from './use-cases/create-card-use-case'
|
||||||
|
|
||||||
const commandHandlers = [
|
const commandHandlers = [
|
||||||
CreateDeckHandler,
|
CreateDeckHandler,
|
||||||
@@ -17,12 +20,14 @@ const commandHandlers = [
|
|||||||
GetDeckByIdHandler,
|
GetDeckByIdHandler,
|
||||||
DeleteDeckByIdHandler,
|
DeleteDeckByIdHandler,
|
||||||
UpdateDeckHandler,
|
UpdateDeckHandler,
|
||||||
|
GetAllCardsInDeckHandler,
|
||||||
|
CreateCardHandler,
|
||||||
]
|
]
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [CqrsModule],
|
imports: [CqrsModule],
|
||||||
controllers: [DecksController],
|
controllers: [DecksController],
|
||||||
providers: [DecksService, DecksRepository, ...commandHandlers],
|
providers: [DecksService, DecksRepository, CardsRepository, ...commandHandlers],
|
||||||
exports: [CqrsModule],
|
exports: [CqrsModule],
|
||||||
})
|
})
|
||||||
export class DecksModule {}
|
export class DecksModule {}
|
||||||
|
|||||||
20
src/modules/decks/use-cases/create-card-use-case.ts
Normal file
20
src/modules/decks/use-cases/create-card-use-case.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'
|
||||||
|
import { CreateCardDto } from '../../cards/dto/create-card.dto'
|
||||||
|
import { CardsRepository } from '../../cards/infrastructure/cards.repository'
|
||||||
|
|
||||||
|
export class CreateCardCommand {
|
||||||
|
constructor(
|
||||||
|
public readonly userId: string,
|
||||||
|
public readonly deckId: string,
|
||||||
|
public readonly card: CreateCardDto
|
||||||
|
) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@CommandHandler(CreateCardCommand)
|
||||||
|
export class CreateCardHandler implements ICommandHandler<CreateCardCommand> {
|
||||||
|
constructor(private readonly cardsRepository: CardsRepository) {}
|
||||||
|
|
||||||
|
async execute(command: CreateCardCommand) {
|
||||||
|
return await this.cardsRepository.createCard(command.deckId, command.userId, command.card)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'
|
||||||
|
import { CardsRepository } from '../../cards/infrastructure/cards.repository'
|
||||||
|
import { GetAllCardsInDeckDto } from '../../cards/dto/get-all-cards.dto'
|
||||||
|
import { ForbiddenException, NotFoundException } from '@nestjs/common'
|
||||||
|
|
||||||
|
export class GetAllCardsInDeckCommand {
|
||||||
|
constructor(
|
||||||
|
public readonly userId: string,
|
||||||
|
public readonly deckId: string,
|
||||||
|
public readonly params: GetAllCardsInDeckDto
|
||||||
|
) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@CommandHandler(GetAllCardsInDeckCommand)
|
||||||
|
export class GetAllCardsInDeckHandler implements ICommandHandler<GetAllCardsInDeckCommand> {
|
||||||
|
constructor(private readonly cardsRepository: CardsRepository) {}
|
||||||
|
|
||||||
|
async execute(command: GetAllCardsInDeckCommand) {
|
||||||
|
const deck = await this.cardsRepository.findDeckById(command.deckId)
|
||||||
|
if (!deck) throw new NotFoundException(`Deck with id ${command.deckId} not found`)
|
||||||
|
|
||||||
|
if (deck.userId !== command.userId && deck.isPrivate) {
|
||||||
|
throw new ForbiddenException(`You can't get a private deck that you don't own`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return await this.cardsRepository.findCardsByDeckId(command.deckId, command.params)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,3 +3,4 @@ export * from './get-all-decks-use-case'
|
|||||||
export * from './get-deck-by-id-use-case'
|
export * from './get-deck-by-id-use-case'
|
||||||
export * from './delete-deck-by-id-use-case'
|
export * from './delete-deck-by-id-use-case'
|
||||||
export * from './update-deck-use-case'
|
export * from './update-deck-use-case'
|
||||||
|
export * from './get-all-cards-in-deck-use-case'
|
||||||
|
|||||||
Reference in New Issue
Block a user