import { NextResponse } from "next/server"; import { db } from "@/db"; import { quizSessions } from "@/db/schema"; import { eq, and, desc } from "drizzle-orm"; import { getSession } from "@/lib/auth"; import { WARMUP_PARAGRAPHS } from "@/lib/warmup-paragraphs"; interface WarmupProgress { warmupCompleted: number; } function parseWarmupProgress(answersJson: string): WarmupProgress { try { const parsed = JSON.parse(answersJson); if (parsed && typeof parsed === "object" && "warmupCompleted" in parsed) { return { warmupCompleted: parsed.warmupCompleted ?? 0 }; } // Legacy format: answers is an array, no warmup tracking yet return { warmupCompleted: 0 }; } catch { return { warmupCompleted: 0 }; } } async function getPassedQuizSession(annotatorId: string) { const [session] = await db .select() .from(quizSessions) .where( and( eq(quizSessions.annotatorId, annotatorId), eq(quizSessions.passed, true), ), ) .orderBy(desc(quizSessions.startedAt)) .limit(1); return session ?? null; } export async function GET() { const session = await getSession(); if (!session) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const quizSession = await getPassedQuizSession(session.annotatorId); if (!quizSession) { return NextResponse.json( { error: "Quiz not passed" }, { status: 403 }, ); } const progress = parseWarmupProgress(quizSession.answers); if (progress.warmupCompleted >= WARMUP_PARAGRAPHS.length) { return NextResponse.json({ done: true, warmupCompleted: progress.warmupCompleted }); } const next = WARMUP_PARAGRAPHS[progress.warmupCompleted]; return NextResponse.json({ done: false, warmupCompleted: progress.warmupCompleted, paragraph: { id: next.id, text: next.text, index: progress.warmupCompleted, total: WARMUP_PARAGRAPHS.length, }, }); } export async function POST(request: Request) { const session = await getSession(); if (!session) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const quizSession = await getPassedQuizSession(session.annotatorId); if (!quizSession) { return NextResponse.json( { error: "Quiz not passed" }, { status: 403 }, ); } const body = await request.json(); const { category, specificity, warmupIndex } = body as { category?: string; specificity?: number; warmupIndex?: number; }; if (!category || !specificity || warmupIndex === undefined) { return NextResponse.json( { error: "Missing required fields: category, specificity, warmupIndex" }, { status: 400 }, ); } const progress = parseWarmupProgress(quizSession.answers); if (warmupIndex !== progress.warmupCompleted) { return NextResponse.json( { error: "Warmup index mismatch" }, { status: 400 }, ); } if (warmupIndex >= WARMUP_PARAGRAPHS.length) { return NextResponse.json( { error: "Warmup already complete" }, { status: 400 }, ); } const gold = WARMUP_PARAGRAPHS[warmupIndex]; const newCompleted = warmupIndex + 1; const categoryCorrect = category === gold.goldCategory; const specificityCorrect = specificity === gold.goldSpecificity; // Store warmup progress in the quiz session answers field // Preserve existing quiz answers array if present, add warmup tracking let existingData: Record; try { const parsed = JSON.parse(quizSession.answers); if (Array.isArray(parsed)) { existingData = { quizAnswers: parsed }; } else { existingData = parsed; } } catch { existingData = {}; } await db .update(quizSessions) .set({ answers: JSON.stringify({ ...existingData, warmupCompleted: newCompleted, }), }) .where(eq(quizSessions.id, quizSession.id)); return NextResponse.json({ categoryCorrect, specificityCorrect, goldCategory: gold.goldCategory, goldSpecificity: gold.goldSpecificity, explanation: gold.explanation, warmupCompleted: newCompleted, done: newCompleted >= WARMUP_PARAGRAPHS.length, }); }