Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iris : Adds support for multiple options correct, and search and sort in leaderboard #48

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
30 changes: 19 additions & 11 deletions src/controllers/checkQuiz/autoCheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,40 @@ interface autoCheckRequest extends Request {
quizId: string
}
}

const autoCheck = async (req: autoCheckRequest, res: Response) => {
const quizId = req.params.quizId

try {
const quiz = await QuizModel.findById(quizId).populate({
path: 'sections.questions',
select: 'type correctAnswer maxMarks _id autoCheck',
})

quiz?.sections?.forEach(async (section) => {
section?.questions?.forEach(async (question) => {
if (question.type === QuestionTypes.MCQ && question.autoCheck) {
await ResponseModel.updateMany({ quizId: quizId, questionId: question._id }, [
{
$set: {
marksAwarded: {
$cond: {
if: { $eq: ['$selectedOptionId', question.correctAnswer] },
then: question.maxMarks,
else: 0,
await ResponseModel.updateMany(
{ quizId: quizId, questionId: question._id },
[
{
$set: {
marksAwarded: {
$cond: {
if: { $setEquals: ['$selectedOptionId', question.correctAnswer] }, // Check if the arrays have the same elements
then: question.maxMarks,
else: 0,
},
},
status: ResponseStatus.checked,
},
status: ResponseStatus.checked,
},
},
])
],
)
}
})
})

return res.status(200).json({
success: true,
message: 'Autocheck successful',
Expand All @@ -49,4 +56,5 @@ const autoCheck = async (req: autoCheckRequest, res: Response) => {
})
}
}

export default autoCheck
116 changes: 74 additions & 42 deletions src/controllers/checkQuiz/generateLeaderBoard.ts
Original file line number Diff line number Diff line change
@@ -1,79 +1,111 @@
import LeaderboardModel from '@models/leaderboard/leaderboardModel'
import ResponseModel from '@models/response/responseModel'
import sendFailureResponse from '@utils/failureResponse'
import getQuiz from '@utils/getQuiz'
import { Request, Response } from 'express'
import { Types } from 'mongoose'
import { ResponseStatus } from 'types'

import LeaderboardModel from '@models/leaderboard/leaderboardModel';
import ResponseModel from '@models/response/responseModel';
import sendFailureResponse from '@utils/failureResponse';
import getQuiz from '@utils/getQuiz';
import { Request, Response } from 'express';
import { Types } from 'mongoose';
import { ResponseStatus } from 'types';
import sendInvalidInputResponse from '@utils/invalidInputResponse';
//DONE
interface generateLeaderBoardRequest extends Request {
params: {
quizId: string
}
quizId: string;
sectionIndex?: string;
};
}

interface Participant {
userId: Types.ObjectId
marks: number
questionsAttempted: number
questionsChecked: number
userId: Types.ObjectId;
marks: number;
questionsAttempted: number;
questionsChecked: number;
}

const generateLeaderBoard = async (req: generateLeaderBoardRequest, res: Response) => {
const { quizId } = req.params
const { quizId } = req.params;
let sectionIndex = req.params.sectionIndex ? parseInt(req.params.sectionIndex, 10) : null;
if (sectionIndex != null && isNaN(sectionIndex)) {
sectionIndex = null;
}
console.log('Generating leaderboard for quiz:', quizId);
console.log('Section index:', sectionIndex);

try {
const quiz = await getQuiz(quizId)
const participants: Participant[] = []
const quiz = await getQuiz(quizId);
console.log('Quiz found:', quiz);
if (!quiz || !quiz?.sections) {
return sendInvalidInputResponse(res);
}

const participants: Participant[] = [];

let Questions = [];

if (sectionIndex != null) {
console.log('Section index: not null');
Questions = quiz.sections[sectionIndex]?.questions || [];
} else {
console.log('Section index: null');
Questions = quiz.sections.flatMap((section) => section.questions);
}

await Promise.all(
quiz?.participants?.map(async (participant) => {
const responses = await ResponseModel.find({ quizId: quizId, userId: participant.userId })

let score = 0
let questionsAttempted = 0
let questionsChecked = 0
const responses = await ResponseModel.find({
userId: participant.userId,
quizId: quizId,
questionId: { $in: Questions.filter((q) => q !== undefined).map((q) => q._id) },
});
let score = 0;
let questionsAttempted = 0;
let questionsChecked = 0;

responses.forEach((response) => {
score += response.marksAwarded || 0
questionsAttempted++
questionsChecked += response.status === ResponseStatus.checked ? 1 : 0
})
score += response.marksAwarded || 0;
questionsAttempted++;
questionsChecked += response.status === ResponseStatus.checked ? 1 : 0;
});

if (Types.ObjectId.isValid(participant.userId)) {
if (
Types.ObjectId.isValid(participant.userId)
) {
const leaderboardEntry: Participant = {
userId: participant.userId,
marks: score,
questionsAttempted: questionsAttempted,
questionsChecked: questionsChecked,
}
participants.push(leaderboardEntry)
};

participants.push(leaderboardEntry);
}
}) as Promise<void>[],
)
);

const sortedParticipants = participants.sort((a, b) => {
if (a.marks > b.marks) {
return -1
} else return 1
})
const sortedParticipants = participants.sort((a, b) => b.marks - a.marks);

console.log('Sorted participants:', sortedParticipants);

await LeaderboardModel.findOneAndUpdate(
{ quizId: quizId },
{ quizId: quizId, sectionIndex: sectionIndex },
{
quizId: quizId,
sectionIndex: sectionIndex,
participants: sortedParticipants,
},
{ upsert: true },
)
);

return res.status(200).json({
message: 'Leaderboard generated successfully',
leaderboard: participants,
})
leaderboard: sortedParticipants,
});
} catch (error: unknown) {
return sendFailureResponse({
res,
error,
messageToSend: 'Failed to generate leaderboard',
})
});
}
}
};

export default generateLeaderBoard
export default generateLeaderBoard;
88 changes: 0 additions & 88 deletions src/controllers/checkQuiz/generateSectionLeaderboard.ts

This file was deleted.

Loading