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[] RefreshToken refreshToken[]
resetPassword resetPassword? resetPassword resetPassword?
favoriteDecks favoriteDeck[] favoriteDecks favoriteDeck[]
attempts cardAttempt[]
@@index([email]) @@index([email])
@@index([id]) @@index([id])
@@ -101,6 +102,7 @@ model card {
author user @relation(fields: [userId], references: [id], onDelete: Cascade) author 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[] grades grade[]
attempts cardAttempt[]
@@index([userId]) @@index([userId])
@@index([deckId]) @@index([deckId])
@@ -175,3 +177,17 @@ model favoriteDeck {
@@index([userId]) @@index([userId])
@@index([deckId]) @@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,13 +97,14 @@ export class CardsRepository {
const whereClause = whereParts.join(' OR ') const whereClause = whereParts.join(' OR ')
const sqlQuery = ` 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 FROM flashcards.card AS c
LEFT JOIN flashcards.grade AS g ON c.id = g."cardId" AND g."userId" = $1 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}) WHERE c."deckId" = $2 AND (${whereClause})
ORDER BY g."grade" ${direction === 'asc' ? 'ASC NULLS FIRST' : 'DESC NULLS LAST'} ORDER BY g."grade" ${direction === 'asc' ? 'ASC NULLS FIRST' : 'DESC NULLS LAST'}
LIMIT $${queryParams.length + 1} OFFSET $${queryParams.length + 2} LIMIT $${queryParams.length + 1} OFFSET $${queryParams.length + 2}
` `
// Add itemsPerPage and start to the queryParams // Add itemsPerPage and start to the queryParams
queryParams.push(itemsPerPage, start) queryParams.push(itemsPerPage, start)
@@ -113,13 +114,14 @@ export class CardsRepository {
...queryParams ...queryParams
)) satisfies Array<any> )) satisfies Array<any>
const cards: CardWithGrades[] = cardsRaw.map(({ userGrade, ...card }) => ({ const cards: CardWithGrades[] = cardsRaw.map(({ userGrade, totalAttempts, ...card }) => ({
...card, ...card,
grades: [ grades: [
{ {
grade: userGrade, grade: userGrade,
}, },
], ],
attempts: totalAttempts,
})) }))
const totalCount = await this.prisma.card.count({ where }) const totalCount = await this.prisma.card.count({ where })
@@ -143,13 +145,33 @@ export class CardsRepository {
grade: true, grade: true,
}, },
}, },
attempts: {
where: {
userId,
},
select: {
attemptCount: true,
},
},
}, },
skip: (currentPage - 1) * itemsPerPage, skip: (currentPage - 1) * itemsPerPage,
take: 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) { } catch (e) {
this.logger.error(e?.message) this.logger.error(e?.message)
@@ -159,7 +181,7 @@ export class CardsRepository {
async findCardsByDeckIdWithGrade(userId: string, deckId: string) { async findCardsByDeckIdWithGrade(userId: string, deckId: string) {
try { try {
return this.prisma.card.findMany({ const cards = await this.prisma.card.findMany({
where: { where: {
deckId, deckId,
}, },
@@ -169,8 +191,18 @@ export class CardsRepository {
userId, userId,
}, },
}, },
attempts: {
where: {
userId,
},
},
}, },
}) })
return cards.map(card => ({
...card,
shots: card.attempts.reduce((acc, attempt) => acc + attempt.attemptCount, 0),
}))
} catch (e) { } catch (e) {
this.logger.error(e?.message) this.logger.error(e?.message)
throw new InternalServerErrorException(e?.message) throw new InternalServerErrorException(e?.message)

View File

@@ -20,7 +20,7 @@ export class GradesRepository {
grade: number grade: number
}) { }) {
try { try {
return await this.prisma.grade.upsert({ const gradeResult = await this.prisma.grade.upsert({
where: { where: {
cardId_userId: { cardId_userId: {
cardId, 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) { } catch (e) {
this.logger.error(e?.message) this.logger.error(e?.message)
throw new InternalServerErrorException(e?.message) throw new InternalServerErrorException(e?.message)