Initial working commit
Some checks failed
Automated Container Build / build-and-push (push) Failing after 7s

This commit is contained in:
Elijah 2026-06-27 19:19:38 -07:00
parent 666ceb7325
commit b7ce314f01
105 changed files with 35510 additions and 11 deletions

View file

@ -0,0 +1,72 @@
import { NextRequest, NextResponse } from "next/server";
import { getQuizSetWithQuestions, createQuizAttempt, listQuizAttempts } from "@/services/quizService";
import { scoreQuiz } from "@/lib/scoring";
export async function POST(
request: NextRequest,
ctx: RouteContext<"/api/quizzes/[id]/attempt">
) {
const { id } = await ctx.params;
const body = await request.json().catch(() => null);
if (!body || !body.answersJson) {
return NextResponse.json(
{ error: "answersJson is required" },
{ status: 400 }
);
}
const quizSet = await getQuizSetWithQuestions(id);
if (!quizSet) {
return NextResponse.json({ error: "Quiz not found" }, { status: 404 });
}
// Parse answers
let answers: Record<string, string[]>;
try {
answers = JSON.parse(body.answersJson);
} catch {
return NextResponse.json({ error: "Invalid answers JSON" }, { status: 400 });
}
// Determine which questions were included in this attempt
const isPartialRetake = body.isPartialRetake === true;
// If partial retake, we only score the questions that actually had answers provided
// or that were explicitly passed in a questionIds array.
// For simplicity, we filter the quizSet questions down to what's in the answers object
// if it's a partial retake, though the client will only show those anyway.
let questionsToScore = quizSet.questions;
if (isPartialRetake) {
const answeredIds = Object.keys(answers);
questionsToScore = quizSet.questions.filter(q => answeredIds.includes(q.id));
}
// Format questions for the scoring utility
const formattedQuestions = questionsToScore.map((q) => ({
id: q.id,
type: q.type as "MULTIPLE_CHOICE" | "SATA",
options: q.options.map((o) => ({ id: o.id, isCorrect: o.isCorrect })),
}));
const { total, maxScore } = scoreQuiz(formattedQuestions, answers);
const attempt = await createQuizAttempt({
quizSetId: id,
score: total,
maxScore: maxScore,
answersJson: body.answersJson,
isPartialRetake,
});
return NextResponse.json(attempt, { status: 201 });
}
export async function GET(
_request: NextRequest,
ctx: RouteContext<"/api/quizzes/[id]/attempt">
) {
const { id } = await ctx.params;
const attempts = await listQuizAttempts(id);
return NextResponse.json(attempts);
}