mirror of
https://github.com/ershisan99/flashcards-api.git
synced 2025-12-16 12:33:17 +00:00
fix: count attempts per user instead of globally
This commit is contained in:
@@ -45,6 +45,7 @@ model user {
|
||||
RefreshToken refreshToken[]
|
||||
resetPassword resetPassword?
|
||||
favoriteDecks favoriteDeck[]
|
||||
attempts cardAttempt[]
|
||||
|
||||
@@index([email])
|
||||
@@index([id])
|
||||
@@ -101,6 +102,7 @@ model card {
|
||||
author user @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
decks deck @relation(fields: [deckId], references: [id], onDelete: Cascade)
|
||||
grades grade[]
|
||||
attempts cardAttempt[]
|
||||
|
||||
@@index([userId])
|
||||
@@index([deckId])
|
||||
@@ -175,3 +177,17 @@ model favoriteDeck {
|
||||
@@index([userId])
|
||||
@@index([deckId])
|
||||
}
|
||||
|
||||
model cardAttempt {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
cardId String
|
||||
attemptCount Int @default(1)
|
||||
lastAttempt DateTime @default(now())
|
||||
user user @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
card card @relation(fields: [cardId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([userId, cardId])
|
||||
@@index([userId])
|
||||
@@index([cardId])
|
||||
}
|
||||
|
||||
@@ -97,9 +97,10 @@ export class CardsRepository {
|
||||
const whereClause = whereParts.join(' OR ')
|
||||
|
||||
const sqlQuery = `
|
||||
SELECT c.*, g.grade as "userGrade"
|
||||
SELECT c.*, g.grade as "userGrade", COALESCE(a."attemptCount", 0) as "totalAttempts"
|
||||
FROM flashcards.card AS c
|
||||
LEFT JOIN flashcards.grade AS g ON c.id = g."cardId" AND g."userId" = $1
|
||||
LEFT JOIN flashcards.cardAttempt AS a ON c.id = a."cardId" AND a."userId" = $1
|
||||
WHERE c."deckId" = $2 AND (${whereClause})
|
||||
ORDER BY g."grade" ${direction === 'asc' ? 'ASC NULLS FIRST' : 'DESC NULLS LAST'}
|
||||
LIMIT $${queryParams.length + 1} OFFSET $${queryParams.length + 2}
|
||||
@@ -113,13 +114,14 @@ export class CardsRepository {
|
||||
...queryParams
|
||||
)) satisfies Array<any>
|
||||
|
||||
const cards: CardWithGrades[] = cardsRaw.map(({ userGrade, ...card }) => ({
|
||||
const cards: CardWithGrades[] = cardsRaw.map(({ userGrade, totalAttempts, ...card }) => ({
|
||||
...card,
|
||||
grades: [
|
||||
{
|
||||
grade: userGrade,
|
||||
},
|
||||
],
|
||||
attempts: totalAttempts,
|
||||
}))
|
||||
|
||||
const totalCount = await this.prisma.card.count({ where })
|
||||
@@ -143,13 +145,33 @@ export class CardsRepository {
|
||||
grade: true,
|
||||
},
|
||||
},
|
||||
attempts: {
|
||||
where: {
|
||||
userId,
|
||||
},
|
||||
select: {
|
||||
attemptCount: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
skip: (currentPage - 1) * itemsPerPage,
|
||||
take: itemsPerPage,
|
||||
}),
|
||||
])
|
||||
|
||||
return Pagination.transformPaginationData(result, { currentPage, itemsPerPage })
|
||||
const [totalCount, cardsRaw] = result
|
||||
|
||||
const cards = cardsRaw.map(card => ({
|
||||
...card,
|
||||
shots: card.attempts.reduce((acc, attempt) => acc + attempt.attemptCount, 0),
|
||||
}))
|
||||
|
||||
console.log(cards)
|
||||
|
||||
return Pagination.transformPaginationData([totalCount, cards], {
|
||||
currentPage,
|
||||
itemsPerPage,
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
this.logger.error(e?.message)
|
||||
@@ -159,7 +181,7 @@ export class CardsRepository {
|
||||
|
||||
async findCardsByDeckIdWithGrade(userId: string, deckId: string) {
|
||||
try {
|
||||
return this.prisma.card.findMany({
|
||||
const cards = await this.prisma.card.findMany({
|
||||
where: {
|
||||
deckId,
|
||||
},
|
||||
@@ -169,8 +191,18 @@ export class CardsRepository {
|
||||
userId,
|
||||
},
|
||||
},
|
||||
attempts: {
|
||||
where: {
|
||||
userId,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return cards.map(card => ({
|
||||
...card,
|
||||
shots: card.attempts.reduce((acc, attempt) => acc + attempt.attemptCount, 0),
|
||||
}))
|
||||
} catch (e) {
|
||||
this.logger.error(e?.message)
|
||||
throw new InternalServerErrorException(e?.message)
|
||||
|
||||
@@ -20,7 +20,7 @@ export class GradesRepository {
|
||||
grade: number
|
||||
}) {
|
||||
try {
|
||||
return await this.prisma.grade.upsert({
|
||||
const gradeResult = await this.prisma.grade.upsert({
|
||||
where: {
|
||||
cardId_userId: {
|
||||
cardId,
|
||||
@@ -57,6 +57,37 @@ export class GradesRepository {
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const attemptResult = await this.prisma.cardAttempt.upsert({
|
||||
where: {
|
||||
userId_cardId: {
|
||||
userId,
|
||||
cardId,
|
||||
},
|
||||
},
|
||||
update: {
|
||||
attemptCount: {
|
||||
increment: 1,
|
||||
},
|
||||
lastAttempt: new Date(),
|
||||
},
|
||||
create: {
|
||||
attemptCount: 1,
|
||||
lastAttempt: new Date(),
|
||||
user: {
|
||||
connect: {
|
||||
id: userId,
|
||||
},
|
||||
},
|
||||
card: {
|
||||
connect: {
|
||||
id: cardId,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return { gradeResult, attemptResult }
|
||||
} catch (e) {
|
||||
this.logger.error(e?.message)
|
||||
throw new InternalServerErrorException(e?.message)
|
||||
|
||||
Reference in New Issue
Block a user