From f945f12d81a74223ee9cd9fd8107b1b9206848c9 Mon Sep 17 00:00:00 2001 From: Daniel Bulant Date: Sun, 3 May 2026 21:05:08 +0200 Subject: [PATCH] add question history --- api/src/party-types.ts | 23 ++++++++++++++++++++++- api/src/routes/quiz.ts | 25 ------------------------- api/src/workflows/quiz.ts | 26 ++++++++++++++++++++++---- 3 files changed, 44 insertions(+), 30 deletions(-) diff --git a/api/src/party-types.ts b/api/src/party-types.ts index 33d4ec0..4ef9fcc 100644 --- a/api/src/party-types.ts +++ b/api/src/party-types.ts @@ -35,6 +35,20 @@ export type Question = { points: number; }; +export type QuizResponse = { + playerId: string; + selected: number; + correct: boolean; + answeredAt: number; + pointsGained: number; +}; + +export type QuizRound = { + questionIndex: number; + question: Question; + responses: QuizResponse[]; +}; + export type QuizState = { status: "running" | "results"; workflowId: string | null; @@ -42,9 +56,16 @@ export type QuizState = { currentQuestion: Question | null; answers: Record< string, - { playerId: string; selected: number; correct: boolean } + { + playerId: string; + selected: number; + correct: boolean; + pointsGained: number; + answeredAt: number; + } >; scores: Record; + history: QuizRound[]; }; export type PartySocketEvent = diff --git a/api/src/routes/quiz.ts b/api/src/routes/quiz.ts index 871584a..9de2059 100644 --- a/api/src/routes/quiz.ts +++ b/api/src/routes/quiz.ts @@ -114,30 +114,5 @@ export const quizRoutes = new Elysia() selected: t.Integer(), }), }, - ) - .get( - "/status", - async ({ params, set }) => { - const existingQuiz = await db - .select({ data: party.data }) - .from(party) - .where(eq(party.id, params.partyId)) - .limit(1) - .then((rows) => rows[0]); - - if (!existingQuiz) { - set.status = 404; - return { error: "Party not found" }; - } - - const quizData = ( - (existingQuiz.data ?? {}) as Record - ).quiz as QuizState | undefined; - - return { - quiz: quizData, - }; - }, - { auth: true }, ), ); diff --git a/api/src/workflows/quiz.ts b/api/src/workflows/quiz.ts index a015b4d..fabe1a7 100644 --- a/api/src/workflows/quiz.ts +++ b/api/src/workflows/quiz.ts @@ -3,7 +3,7 @@ import { eq } from "drizzle-orm"; import { db } from "../db"; import { partyMember } from "../db/schema"; import { updatePartyData } from "../party/state"; -import type { QuizState } from "../party-types"; +import type { QuizResponse, QuizRound, QuizState } from "../party-types"; const TOTAL_QUESTIONS = 5; @@ -31,6 +31,7 @@ export class QuizWorkflow extends ConfiguredInstance { currentQuestion: null, answers: {}, scores: {}, + history: [], }; // Initialize quiz state @@ -48,6 +49,12 @@ export class QuizWorkflow extends ConfiguredInstance { const question = await QuizWorkflow.generateQuestion(i); quizState.currentQuestion = question; quizState.answers = {}; + const round: QuizRound = { + questionIndex: i, + question, + responses: [], + }; + quizState.history.push(round); await QuizWorkflow.updatePartyData(partyId, quizState); // Wait for all responses with timeout @@ -61,14 +68,19 @@ export class QuizWorkflow extends ConfiguredInstance { if (response === null) { // Timeout - fill in missing players with no answer + const now = Date.now(); for (const memberId of memberIds) { if (!receivedPlayers.has(memberId)) { receivedPlayers.add(memberId); - quizState.answers[memberId] = { + const noAnswer: QuizResponse = { playerId: memberId, selected: -1, correct: false, + answeredAt: now, + pointsGained: 0, }; + quizState.answers[memberId] = noAnswer; + round.responses.push(noAnswer); await QuizWorkflow.updatePartyData(partyId, quizState); } } @@ -76,15 +88,21 @@ export class QuizWorkflow extends ConfiguredInstance { } receivedPlayers.add(response.playerId); + const answeredAt = Date.now(); const isCorrect = response.selected === question.correct; - quizState.answers[response.playerId] = { + const pointsGained = isCorrect ? question.points : 0; + const quizResponse: QuizResponse = { ...response, correct: isCorrect, + answeredAt, + pointsGained, }; + quizState.answers[response.playerId] = quizResponse; + round.responses.push(quizResponse); if (isCorrect) { quizState.scores[response.playerId] = - (quizState.scores[response.playerId] ?? 0) + question.points; + (quizState.scores[response.playerId] ?? 0) + pointsGained; } await QuizWorkflow.updatePartyData(partyId, quizState);