fix: count attempts per user instead of globally

This commit is contained in:
2024-06-02 14:36:12 +02:00
parent 5a1d375ada
commit 958f9bae30
3 changed files with 113 additions and 34 deletions

View File

@@ -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])
}

View File

@@ -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)

View File

@@ -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)