DB:
- quiz_question gains `lang` ('fr' default) and `active` (true default); migration 0002
- only active questions are served to games (pool filter)
History:
- engine writes a game_history row at game end (modes + ranked results), fire-and-forget
- public GET /api/history/:code lists a room's recent games
- lobby shows a "Parties précédentes" collapsible (date, modes, winner/scores)
Back-office:
- create form has a FR/EN language select; lang stored
- per-question active toggle (PATCH /questions/:id) — disable without deleting;
inactive rows dimmed and labelled
- seeds set lang (opentdb=en, manual/pokemon=fr)
Verified e2e: migration applied; game played → /api/history returns it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
55 lines
1.2 KiB
TypeScript
55 lines
1.2 KiB
TypeScript
// Historique de parties (table game_history). No-op si pas de DB.
|
|
|
|
import { desc, eq } from "drizzle-orm"
|
|
import { db } from "./index"
|
|
import { gameHistory } from "./schema"
|
|
|
|
export interface GameResultEntry {
|
|
name: string
|
|
score: number
|
|
}
|
|
|
|
export async function saveGameHistory(
|
|
roomCode: string,
|
|
modes: string[],
|
|
results: GameResultEntry[]
|
|
): Promise<void> {
|
|
if (!db) {
|
|
return
|
|
}
|
|
await db.insert(gameHistory).values({ roomCode, modes, results })
|
|
}
|
|
|
|
export interface GameHistoryRow {
|
|
id: string
|
|
playedAt: string
|
|
modes: string[]
|
|
results: GameResultEntry[]
|
|
}
|
|
|
|
export async function listGameHistory(
|
|
roomCode: string,
|
|
limit = 10
|
|
): Promise<GameHistoryRow[]> {
|
|
if (!db) {
|
|
return []
|
|
}
|
|
const rows = await db
|
|
.select({
|
|
id: gameHistory.id,
|
|
playedAt: gameHistory.playedAt,
|
|
modes: gameHistory.modes,
|
|
results: gameHistory.results,
|
|
})
|
|
.from(gameHistory)
|
|
.where(eq(gameHistory.roomCode, roomCode))
|
|
.orderBy(desc(gameHistory.playedAt))
|
|
.limit(limit)
|
|
return rows.map((r) => ({
|
|
id: r.id,
|
|
playedAt:
|
|
r.playedAt instanceof Date ? r.playedAt.toISOString() : String(r.playedAt),
|
|
modes: (r.modes as string[]) ?? [],
|
|
results: (r.results as GameResultEntry[]) ?? [],
|
|
}))
|
|
}
|