1- import { asc , avg , count , desc , eq , sql , sum } from "drizzle-orm" ;
1+ import { asc , avg , count , desc , eq , max , sql , sum } from "drizzle-orm" ;
22import { questions , testSessions , userAnswers } from "./schema" ;
33import { DbType } from "./types" ;
44
5+ function latestAnswersSubquery ( db : DbType ) {
6+ return db
7+ . select ( {
8+ questionId : userAnswers . questionId ,
9+ latestAnswerId : max ( userAnswers . id ) . as ( "latest_answer_id" ) ,
10+ } )
11+ . from ( userAnswers )
12+ . groupBy ( userAnswers . questionId )
13+ . as ( "latest_answers" ) ;
14+ }
15+
516export async function getOverallStatistics ( db : DbType ) {
617 // Aggregate data from testSessions
718 const sessionsResult = await db
@@ -34,12 +45,22 @@ export async function getOverallStatistics(db: DbType) {
3445 } )
3546 . from ( userAnswers ) ;
3647
48+ const latestAnswers = latestAnswersSubquery ( db ) ;
49+ const activeMistakesStats = await db
50+ . select ( {
51+ activeMistakes : count ( userAnswers . id ) ,
52+ } )
53+ . from ( userAnswers )
54+ . innerJoin ( latestAnswers , eq ( userAnswers . id , latestAnswers . latestAnswerId ) )
55+ . where ( eq ( userAnswers . is_correct , false ) ) ;
56+
3757 const testCount = sessionStats [ 0 ] ?. totalTests || 0 ;
3858 const avgScore = sessionStats [ 0 ] ?. averageScore || 0 ;
3959
4060 const timeSpent = Number ( answersStats [ 0 ] ?. totalTimeSpentSeconds || 0 ) ;
4161 const totalAnswers = answersStats [ 0 ] ?. totalAnswers || 0 ;
4262 const correctAnswers = Number ( answersStats [ 0 ] ?. correctAnswers || 0 ) ;
63+ const activeMistakes = activeMistakesStats [ 0 ] ?. activeMistakes || 0 ;
4364
4465 const accuracyRate = totalAnswers > 0 ? correctAnswers / totalAnswers : 0 ;
4566
@@ -50,6 +71,7 @@ export async function getOverallStatistics(db: DbType) {
5071 accuracyRate,
5172 correctAnswers,
5273 totalAnswers,
74+ activeMistakes,
5375 } ;
5476}
5577
@@ -94,37 +116,21 @@ export async function getTestSessionDetails(db: DbType, sessionId: number) {
94116}
95117
96118export async function getUserMistakes ( db : DbType ) {
97- // Get all user answers that are incorrect, joined with the actual questions
119+ const latestAnswers = latestAnswersSubquery ( db ) ;
120+
121+ // Get questions whose latest saved answer is incorrect.
98122 return await db
99123 . select ( {
100124 userAnswer : userAnswers ,
101125 question : questions ,
102126 } )
103127 . from ( userAnswers )
128+ . innerJoin ( latestAnswers , eq ( userAnswers . id , latestAnswers . latestAnswerId ) )
104129 . innerJoin ( questions , eq ( userAnswers . questionId , questions . id ) )
105130 . where ( eq ( userAnswers . is_correct , false ) )
106- . orderBy ( desc ( userAnswers . answered_at ) ) ;
131+ . orderBy ( desc ( userAnswers . id ) ) ;
107132}
108133
109134export async function getUniqueUserMistakes ( db : DbType ) {
110- const mistakes = await db
111- . select ( {
112- userAnswer : userAnswers ,
113- question : questions ,
114- } )
115- . from ( userAnswers )
116- . innerJoin ( questions , eq ( userAnswers . questionId , questions . id ) )
117- . where ( eq ( userAnswers . is_correct , false ) )
118- . orderBy ( desc ( userAnswers . id ) ) ;
119-
120- const seenQuestionIds = new Set < number > ( ) ;
121-
122- return mistakes . filter ( ( { question } ) => {
123- if ( seenQuestionIds . has ( question . id ) ) {
124- return false ;
125- }
126-
127- seenQuestionIds . add ( question . id ) ;
128- return true ;
129- } ) ;
135+ return await getUserMistakes ( db ) ;
130136}
0 commit comments