mirror of
https://github.com/ershisan99/flashcards-api.git
synced 2025-12-16 20:59:26 +00:00
feat: update docs for favorites
This commit is contained in:
@@ -37,7 +37,12 @@ import { Card, CardWithGrade, PaginatedCardsWithGrade } from '../cards/entities/
|
|||||||
|
|
||||||
import { CreateDeckDto, GetAllDecksDto, UpdateDeckDto } from './dto'
|
import { CreateDeckDto, GetAllDecksDto, UpdateDeckDto } from './dto'
|
||||||
import { GetRandomCardDto } from './dto/get-random-card.dto'
|
import { GetRandomCardDto } from './dto/get-random-card.dto'
|
||||||
import { Deck, PaginatedDecks, PaginatedDecksWithMaxCardsCount } from './entities/deck.entity'
|
import {
|
||||||
|
Deck,
|
||||||
|
DeckWithFavorites,
|
||||||
|
PaginatedDecks,
|
||||||
|
PaginatedDecksWithMaxCardsCount,
|
||||||
|
} from './entities/deck.entity'
|
||||||
import { MinMaxCards } from './entities/min-max-cards.entity'
|
import { MinMaxCards } from './entities/min-max-cards.entity'
|
||||||
import {
|
import {
|
||||||
AddDeckToFavoritesCommand,
|
AddDeckToFavoritesCommand,
|
||||||
@@ -130,8 +135,8 @@ export class DecksController {
|
|||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
findOne(@Param('id') id: string): Promise<Deck> {
|
findOne(@Param('id') id: string, @Req() req): Promise<DeckWithFavorites> {
|
||||||
return this.commandBus.execute(new GetDeckByIdCommand(id))
|
return this.commandBus.execute(new GetDeckByIdCommand(id, req.user.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiConsumes('multipart/form-data')
|
@ApiConsumes('multipart/form-data')
|
||||||
@@ -259,7 +264,7 @@ export class DecksController {
|
|||||||
description: 'Add deck to favorites',
|
description: 'Add deck to favorites',
|
||||||
summary: 'Add deck to favorites',
|
summary: 'Add deck to favorites',
|
||||||
})
|
})
|
||||||
async addToFavorites(@Req() req, @Param('id') deckId: string): Promise<CardWithGrade> {
|
async addToFavorites(@Req() req, @Param('id') deckId: string): Promise<void> {
|
||||||
return await this.commandBus.execute(new AddDeckToFavoritesCommand(req.user.id, deckId))
|
return await this.commandBus.execute(new AddDeckToFavoritesCommand(req.user.id, deckId))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,13 +272,13 @@ export class DecksController {
|
|||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@ApiUnauthorizedResponse({ description: 'Unauthorized' })
|
@ApiUnauthorizedResponse({ description: 'Unauthorized' })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiNoContentResponse({ description: 'Added to favorites' })
|
@ApiNoContentResponse({ description: 'Removed from favorites' })
|
||||||
@Delete(':id/favorite')
|
@Delete(':id/favorite')
|
||||||
@ApiOperation({
|
@ApiOperation({
|
||||||
description: 'Add deck to favorites',
|
description: 'Remove deck from favorites',
|
||||||
summary: 'Add deck to favorites',
|
summary: 'Remove deck from favorites',
|
||||||
})
|
})
|
||||||
async removeFromFavorites(@Req() req, @Param('id') deckId: string): Promise<CardWithGrade> {
|
async removeFromFavorites(@Req() req, @Param('id') deckId: string): Promise<void> {
|
||||||
return await this.commandBus.execute(new RemoveDeckFromFavoritesCommand(req.user.id, deckId))
|
return await this.commandBus.execute(new RemoveDeckFromFavoritesCommand(req.user.id, deckId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,18 +15,26 @@ export class DeckWithAuthor extends Deck {
|
|||||||
author: DeckAuthor
|
author: DeckAuthor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class DeckWithAuthorAndFavorites extends DeckWithAuthor {
|
||||||
|
isFavorite: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DeckWithFavorites extends Deck {
|
||||||
|
isFavorite: boolean
|
||||||
|
}
|
||||||
|
|
||||||
export class DeckAuthor {
|
export class DeckAuthor {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PaginatedDecksWithMaxCardsCount {
|
export class PaginatedDecksWithMaxCardsCount {
|
||||||
items: DeckWithAuthor[]
|
items: DeckWithAuthorAndFavorites[]
|
||||||
pagination: Pagination
|
pagination: Pagination
|
||||||
maxCardsCount: number
|
maxCardsCount: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PaginatedDecks {
|
export class PaginatedDecks {
|
||||||
items: DeckWithAuthor[]
|
items: DeckWithAuthorAndFavorites[]
|
||||||
pagination: Pagination
|
pagination: Pagination
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ export class DecksRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findDeckById(id: string): Promise<Deck> {
|
public async findDeckById(id: string, userId: string): Promise<any> {
|
||||||
try {
|
try {
|
||||||
const result = await this.prisma.deck.findUnique({
|
const result = await this.prisma.deck.findUnique({
|
||||||
where: {
|
where: {
|
||||||
@@ -275,10 +275,20 @@ export class DecksRepository {
|
|||||||
card: true,
|
card: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
favoritedBy: {
|
||||||
|
where: {
|
||||||
|
userId,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
return omit({ ...result, cardsCount: result._count.card }, ['_count'])
|
const isFavorite = result.favoritedBy.length > 0
|
||||||
|
|
||||||
|
return omit({ ...result, cardsCount: result._count.card, isFavorite }, [
|
||||||
|
'_count',
|
||||||
|
'favoritedBy',
|
||||||
|
])
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logger.error(e?.message)
|
this.logger.error(e?.message)
|
||||||
throw new InternalServerErrorException(e?.message)
|
throw new InternalServerErrorException(e?.message)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export class AddDeckToFavoritesHandler implements ICommandHandler<AddDeckToFavor
|
|||||||
constructor(private readonly decksRepository: DecksRepository) {}
|
constructor(private readonly decksRepository: DecksRepository) {}
|
||||||
|
|
||||||
async execute(command: AddDeckToFavoritesCommand): Promise<void> {
|
async execute(command: AddDeckToFavoritesCommand): Promise<void> {
|
||||||
const deck = await this.decksRepository.findDeckById(command.deckId)
|
const deck = await this.decksRepository.findDeckById(command.deckId, command.userId)
|
||||||
|
|
||||||
if (!deck) {
|
if (!deck) {
|
||||||
throw new NotFoundException(`Deck with id ${command.deckId} not found`)
|
throw new NotFoundException(`Deck with id ${command.deckId} not found`)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export class CreateCardHandler implements ICommandHandler<CreateCardCommand> {
|
|||||||
async execute(command: CreateCardCommand): Promise<Card> {
|
async execute(command: CreateCardCommand): Promise<Card> {
|
||||||
let questionImg, answerImg
|
let questionImg, answerImg
|
||||||
|
|
||||||
const deck = await this.decksRepository.findDeckById(command.deckId)
|
const deck = await this.decksRepository.findDeckById(command.deckId, command.userId)
|
||||||
|
|
||||||
if (!deck) {
|
if (!deck) {
|
||||||
throw new NotFoundException(`Deck with id ${command.deckId} not found`)
|
throw new NotFoundException(`Deck with id ${command.deckId} not found`)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export class DeleteDeckByIdHandler implements ICommandHandler<DeleteDeckByIdComm
|
|||||||
constructor(private readonly deckRepository: DecksRepository) {}
|
constructor(private readonly deckRepository: DecksRepository) {}
|
||||||
|
|
||||||
async execute(command: DeleteDeckByIdCommand) {
|
async execute(command: DeleteDeckByIdCommand) {
|
||||||
const deck = await this.deckRepository.findDeckById(command.id)
|
const deck = await this.deckRepository.findDeckById(command.id, command.userId)
|
||||||
|
|
||||||
if (!deck) throw new NotFoundException(`Deck with id ${command.id} not found`)
|
if (!deck) throw new NotFoundException(`Deck with id ${command.id} not found`)
|
||||||
if (deck.userId !== command.userId) {
|
if (deck.userId !== command.userId) {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export class GetAllCardsInDeckHandler implements ICommandHandler<GetAllCardsInDe
|
|||||||
}
|
}
|
||||||
|
|
||||||
async execute(command: GetAllCardsInDeckCommand): Promise<PaginatedCards> {
|
async execute(command: GetAllCardsInDeckCommand): Promise<PaginatedCards> {
|
||||||
const deck = await this.decksRepository.findDeckById(command.deckId)
|
const deck = await this.decksRepository.findDeckById(command.deckId, command.userId)
|
||||||
|
|
||||||
if (!deck) throw new NotFoundException(`Deck with id ${command.deckId} not found`)
|
if (!deck) throw new NotFoundException(`Deck with id ${command.deckId} not found`)
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'
|
|||||||
import { DecksRepository } from '../infrastructure/decks.repository'
|
import { DecksRepository } from '../infrastructure/decks.repository'
|
||||||
|
|
||||||
export class GetDeckByIdCommand {
|
export class GetDeckByIdCommand {
|
||||||
constructor(public readonly id: string) {}
|
constructor(
|
||||||
|
public readonly id: string,
|
||||||
|
public readonly userId: string
|
||||||
|
) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@CommandHandler(GetDeckByIdCommand)
|
@CommandHandler(GetDeckByIdCommand)
|
||||||
@@ -11,6 +14,6 @@ export class GetDeckByIdHandler implements ICommandHandler<GetDeckByIdCommand> {
|
|||||||
constructor(private readonly deckRepository: DecksRepository) {}
|
constructor(private readonly deckRepository: DecksRepository) {}
|
||||||
|
|
||||||
async execute(command: GetDeckByIdCommand) {
|
async execute(command: GetDeckByIdCommand) {
|
||||||
return await this.deckRepository.findDeckById(command.id)
|
return await this.deckRepository.findDeckById(command.id, command.userId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export class GetRandomCardInDeckHandler implements ICommandHandler<GetRandomCard
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
async execute(command: GetRandomCardInDeckCommand) {
|
async execute(command: GetRandomCardInDeckCommand) {
|
||||||
const deck = await this.decksRepository.findDeckById(command.deckId)
|
const deck = await this.decksRepository.findDeckById(command.deckId, command.userId)
|
||||||
|
|
||||||
if (!deck) throw new NotFoundException(`Deck with id ${command.deckId} not found`)
|
if (!deck) throw new NotFoundException(`Deck with id ${command.deckId} not found`)
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export class RemoveDeckFromFavoritesHandler
|
|||||||
constructor(private readonly decksRepository: DecksRepository) {}
|
constructor(private readonly decksRepository: DecksRepository) {}
|
||||||
|
|
||||||
async execute(command: RemoveDeckFromFavoritesCommand): Promise<void> {
|
async execute(command: RemoveDeckFromFavoritesCommand): Promise<void> {
|
||||||
const deck = await this.decksRepository.findDeckById(command.deckId)
|
const deck = await this.decksRepository.findDeckById(command.deckId, command.userId)
|
||||||
|
|
||||||
if (!deck) {
|
if (!deck) {
|
||||||
throw new NotFoundException(`Deck with id ${command.deckId} not found`)
|
throw new NotFoundException(`Deck with id ${command.deckId} not found`)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export class UpdateDeckHandler implements ICommandHandler<UpdateDeckCommand> {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
async execute(command: UpdateDeckCommand): Promise<Deck> {
|
async execute(command: UpdateDeckCommand): Promise<Deck> {
|
||||||
const deck = await this.deckRepository.findDeckById(command.deckId)
|
const deck = await this.deckRepository.findDeckById(command.deckId, command.userId)
|
||||||
|
|
||||||
if (!deck) {
|
if (!deck) {
|
||||||
throw new NotFoundException(`Deck with id ${command.deckId} not found`)
|
throw new NotFoundException(`Deck with id ${command.deckId} not found`)
|
||||||
|
|||||||
Reference in New Issue
Block a user