add question history
This commit is contained in:
parent
642a034e08
commit
f945f12d81
3 changed files with 44 additions and 30 deletions
|
|
@ -35,6 +35,20 @@ export type Question = {
|
||||||
points: number;
|
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 = {
|
export type QuizState = {
|
||||||
status: "running" | "results";
|
status: "running" | "results";
|
||||||
workflowId: string | null;
|
workflowId: string | null;
|
||||||
|
|
@ -42,9 +56,16 @@ export type QuizState = {
|
||||||
currentQuestion: Question | null;
|
currentQuestion: Question | null;
|
||||||
answers: Record<
|
answers: Record<
|
||||||
string,
|
string,
|
||||||
{ playerId: string; selected: number; correct: boolean }
|
{
|
||||||
|
playerId: string;
|
||||||
|
selected: number;
|
||||||
|
correct: boolean;
|
||||||
|
pointsGained: number;
|
||||||
|
answeredAt: number;
|
||||||
|
}
|
||||||
>;
|
>;
|
||||||
scores: Record<string, number>;
|
scores: Record<string, number>;
|
||||||
|
history: QuizRound[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PartySocketEvent =
|
export type PartySocketEvent =
|
||||||
|
|
|
||||||
|
|
@ -114,30 +114,5 @@ export const quizRoutes = new Elysia()
|
||||||
selected: t.Integer(),
|
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<string, unknown>
|
|
||||||
).quiz as QuizState | undefined;
|
|
||||||
|
|
||||||
return {
|
|
||||||
quiz: quizData,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{ auth: true },
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { eq } from "drizzle-orm";
|
||||||
import { db } from "../db";
|
import { db } from "../db";
|
||||||
import { partyMember } from "../db/schema";
|
import { partyMember } from "../db/schema";
|
||||||
import { updatePartyData } from "../party/state";
|
import { updatePartyData } from "../party/state";
|
||||||
import type { QuizState } from "../party-types";
|
import type { QuizResponse, QuizRound, QuizState } from "../party-types";
|
||||||
|
|
||||||
const TOTAL_QUESTIONS = 5;
|
const TOTAL_QUESTIONS = 5;
|
||||||
|
|
||||||
|
|
@ -31,6 +31,7 @@ export class QuizWorkflow extends ConfiguredInstance {
|
||||||
currentQuestion: null,
|
currentQuestion: null,
|
||||||
answers: {},
|
answers: {},
|
||||||
scores: {},
|
scores: {},
|
||||||
|
history: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize quiz state
|
// Initialize quiz state
|
||||||
|
|
@ -48,6 +49,12 @@ export class QuizWorkflow extends ConfiguredInstance {
|
||||||
const question = await QuizWorkflow.generateQuestion(i);
|
const question = await QuizWorkflow.generateQuestion(i);
|
||||||
quizState.currentQuestion = question;
|
quizState.currentQuestion = question;
|
||||||
quizState.answers = {};
|
quizState.answers = {};
|
||||||
|
const round: QuizRound = {
|
||||||
|
questionIndex: i,
|
||||||
|
question,
|
||||||
|
responses: [],
|
||||||
|
};
|
||||||
|
quizState.history.push(round);
|
||||||
|
|
||||||
await QuizWorkflow.updatePartyData(partyId, quizState);
|
await QuizWorkflow.updatePartyData(partyId, quizState);
|
||||||
// Wait for all responses with timeout
|
// Wait for all responses with timeout
|
||||||
|
|
@ -61,14 +68,19 @@ export class QuizWorkflow extends ConfiguredInstance {
|
||||||
|
|
||||||
if (response === null) {
|
if (response === null) {
|
||||||
// Timeout - fill in missing players with no answer
|
// Timeout - fill in missing players with no answer
|
||||||
|
const now = Date.now();
|
||||||
for (const memberId of memberIds) {
|
for (const memberId of memberIds) {
|
||||||
if (!receivedPlayers.has(memberId)) {
|
if (!receivedPlayers.has(memberId)) {
|
||||||
receivedPlayers.add(memberId);
|
receivedPlayers.add(memberId);
|
||||||
quizState.answers[memberId] = {
|
const noAnswer: QuizResponse = {
|
||||||
playerId: memberId,
|
playerId: memberId,
|
||||||
selected: -1,
|
selected: -1,
|
||||||
correct: false,
|
correct: false,
|
||||||
|
answeredAt: now,
|
||||||
|
pointsGained: 0,
|
||||||
};
|
};
|
||||||
|
quizState.answers[memberId] = noAnswer;
|
||||||
|
round.responses.push(noAnswer);
|
||||||
await QuizWorkflow.updatePartyData(partyId, quizState);
|
await QuizWorkflow.updatePartyData(partyId, quizState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -76,15 +88,21 @@ export class QuizWorkflow extends ConfiguredInstance {
|
||||||
}
|
}
|
||||||
|
|
||||||
receivedPlayers.add(response.playerId);
|
receivedPlayers.add(response.playerId);
|
||||||
|
const answeredAt = Date.now();
|
||||||
const isCorrect = response.selected === question.correct;
|
const isCorrect = response.selected === question.correct;
|
||||||
quizState.answers[response.playerId] = {
|
const pointsGained = isCorrect ? question.points : 0;
|
||||||
|
const quizResponse: QuizResponse = {
|
||||||
...response,
|
...response,
|
||||||
correct: isCorrect,
|
correct: isCorrect,
|
||||||
|
answeredAt,
|
||||||
|
pointsGained,
|
||||||
};
|
};
|
||||||
|
quizState.answers[response.playerId] = quizResponse;
|
||||||
|
round.responses.push(quizResponse);
|
||||||
|
|
||||||
if (isCorrect) {
|
if (isCorrect) {
|
||||||
quizState.scores[response.playerId] =
|
quizState.scores[response.playerId] =
|
||||||
(quizState.scores[response.playerId] ?? 0) + question.points;
|
(quizState.scores[response.playerId] ?? 0) + pointsGained;
|
||||||
}
|
}
|
||||||
|
|
||||||
await QuizWorkflow.updatePartyData(partyId, quizState);
|
await QuizWorkflow.updatePartyData(partyId, quizState);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue