Fix host reconnection losing player state and first-answer bonus

- Persist firstCorrectPlayerId to backend during state sync
- Restore full players array (not just host) on host reconnect
- Add default values to WELCOME payload for new/unmatched players
- Add migration for first_correct_player_id column in game_sessions
This commit is contained in:
Joey Yakimowich-Payne 2026-01-14 10:04:51 -07:00
commit 035ea57274
No known key found for this signature in database
GPG key ID: 6BFE655FA5ABD1E1
4 changed files with 22 additions and 3 deletions

View file

@ -45,6 +45,7 @@ const runMigrations = () => {
game_state TEXT NOT NULL DEFAULT 'LOBBY',
current_question_index INTEGER NOT NULL DEFAULT 0,
players_data TEXT NOT NULL DEFAULT '[]',
first_correct_player_id TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
@ -52,6 +53,13 @@ const runMigrations = () => {
`);
console.log("Migration: Created game_sessions table");
}
const sessionTableInfo = db.prepare("PRAGMA table_info(game_sessions)").all() as { name: string }[];
const hasFirstCorrect = sessionTableInfo.some(col => col.name === "first_correct_player_id");
if (!hasFirstCorrect) {
db.exec("ALTER TABLE game_sessions ADD COLUMN first_correct_player_id TEXT");
console.log("Migration: Added first_correct_player_id to game_sessions");
}
};
runMigrations();

View file

@ -50,6 +50,7 @@ CREATE TABLE IF NOT EXISTS game_sessions (
game_state TEXT NOT NULL DEFAULT 'LOBBY',
current_question_index INTEGER NOT NULL DEFAULT 0,
players_data TEXT NOT NULL DEFAULT '[]',
first_correct_player_id TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

View file

@ -15,6 +15,7 @@ interface GameSession {
game_state: string;
current_question_index: number;
players_data: string;
first_correct_player_id: string | null;
created_at: string;
updated_at: string;
}
@ -112,6 +113,7 @@ router.get('/:pin/host', (req: Request, res: Response) => {
gameState: session.game_state,
currentQuestionIndex: session.current_question_index,
players: JSON.parse(session.players_data),
firstCorrectPlayerId: session.first_correct_player_id,
});
} catch (err) {
console.error('Error getting host session:', err);
@ -123,7 +125,7 @@ router.patch('/:pin', (req: Request, res: Response) => {
try {
const { pin } = req.params;
const hostSecret = req.headers['x-host-secret'] as string;
const { hostPeerId, gameState, currentQuestionIndex, players } = req.body;
const { hostPeerId, gameState, currentQuestionIndex, players, firstCorrectPlayerId } = req.body;
if (!hostSecret) {
res.status(401).json({ error: 'Host secret required' });
@ -156,6 +158,10 @@ router.patch('/:pin', (req: Request, res: Response) => {
updates.push('players_data = ?');
values.push(JSON.stringify(players));
}
if (firstCorrectPlayerId !== undefined) {
updates.push("first_correct_player_id = ?");
values.push(firstCorrectPlayerId);
}
if (updates.length === 0) {
res.status(400).json({ error: 'No updates provided' });