mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
chore: relocate backend into apps/api ahead of monorepo merge
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Grades a submission against the stored correct answers.
|
||||
*
|
||||
* The breakdown returned here is what gets sent back to the client, so it
|
||||
* deliberately never includes which option(s) were correct — only whether
|
||||
* the user's own answer for each question was right or wrong. Explanation
|
||||
* text is included only when the question was answered correctly, since
|
||||
* showing it for a wrong answer would effectively reveal the correct one.
|
||||
*
|
||||
* @param {Array} questions - QuizQuestion rows w/ .options (incl. is_correct), already fetched
|
||||
* @param {Object} answers - { [question_id]: optionId | optionId[] } submitted by the client
|
||||
*/
|
||||
function gradeSubmission(questions, answers = {}) {
|
||||
let totalPoints = 0;
|
||||
let earnedPoints = 0;
|
||||
|
||||
const breakdown = questions.map((q) => {
|
||||
const points = q.points ?? 1;
|
||||
totalPoints += points;
|
||||
|
||||
const correctIds = (q.options ?? [])
|
||||
.filter((o) => o.is_correct)
|
||||
.map((o) => o.option_id);
|
||||
|
||||
const submitted = answers[q.question_id];
|
||||
const submittedIds = Array.isArray(submitted)
|
||||
? submitted
|
||||
: (submitted !== undefined && submitted !== null ? [submitted] : []);
|
||||
|
||||
const isCorrect =
|
||||
submittedIds.length === correctIds.length &&
|
||||
correctIds.every((id) => submittedIds.includes(id));
|
||||
|
||||
if (isCorrect) earnedPoints += points;
|
||||
|
||||
return {
|
||||
question_id: q.question_id,
|
||||
type: q.type,
|
||||
question: q.question,
|
||||
points,
|
||||
is_correct: isCorrect,
|
||||
selected_option_ids: submittedIds,
|
||||
explanation: isCorrect ? (q.explanation ?? null) : null,
|
||||
options: (q.options ?? []).map((o) => ({
|
||||
option_id: o.option_id,
|
||||
text: o.text,
|
||||
})),
|
||||
};
|
||||
});
|
||||
|
||||
const score = totalPoints > 0 ? Math.round((earnedPoints / totalPoints) * 100) : 0;
|
||||
return { totalPoints, earnedPoints, score, breakdown };
|
||||
}
|
||||
|
||||
module.exports = { gradeSubmission };
|
||||
Reference in New Issue
Block a user