Server: - quiz mode (GameRound): in-memory FR question bank (mcq + truefalse), per-room anti-repeat, first-vote lock, score = base + speed bonus ∝ time left; registered via registerRound, loaded at startup - shared: typed quiz payloads (QuizQuestionPayload / reveal truth / result) - tests: quiz scoring, vote lock, bounds, reveal (bun test) Client: - room store handles round:start / voteAck / reveal / game:end - RoomPage dispatches by status: lobby (host start controls) → quiz view (question, countdown, vote, reveal + scoreboard) → game-end view - replaces standalone lobby page Roadmap V1 step 4. Verified end-to-end over the wire (start→vote→reveal→ score→next round→game:end, no answer leaked, anti-repeat works). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
30 lines
988 B
TypeScript
30 lines
988 B
TypeScript
// Types concrets de l'épreuve Quiz, partagés client/serveur.
|
|
// Le payload générique du moteur est `unknown` ; le client le narrow via type === "quiz".
|
|
// V1 : formats mcq + truefalse (free / image_reveal arrivent avec la DB).
|
|
|
|
import type { QuizFormat } from "./domain"
|
|
|
|
/** Payload diffusé au lancement d'une manche quiz (round:start), SANS la réponse. */
|
|
export interface QuizQuestionPayload {
|
|
format: QuizFormat
|
|
prompt: string
|
|
/** Choix proposés (truefalse = ["Vrai", "Faux"]). */
|
|
choices: string[]
|
|
category?: string
|
|
/** 1 (facile) .. 3 (difficile). */
|
|
difficulty?: number
|
|
}
|
|
|
|
/** Vérité révélée à tous (round:reveal → truth). */
|
|
export interface QuizRevealTruth {
|
|
correctIndex: number
|
|
}
|
|
|
|
/** Résultat d'un joueur sur la manche. */
|
|
export interface QuizPlayerResult {
|
|
choiceIndex: number | null
|
|
correct: boolean
|
|
}
|
|
|
|
/** round:reveal → perPlayerResult : playerId → résultat. */
|
|
export type QuizPerPlayerResult = Record<string, QuizPlayerResult>
|