Client sends all files in a single request to /api/upload/batch,
server receives them all upfront via multer then processes OCR
sequentially. Eliminates network round-trips between each file.
Server: replace hard 503 rejection with a bounded queue (50 slots,
2min timeout) so requests wait for a processing slot instead of failing.
Client: upload files sequentially instead of via Promise.all, and
retry with exponential backoff on 503/504 responses.
- Host can kick players from lobby (removes from game, clears presenter if needed)
- Client can voluntarily leave game
- Fix browser-compatible base64 decoding for document upload (atob vs Buffer)
Bug Fix:
- Fix stale closure bug in client answer validation where correct answers
were sometimes marked incorrect. The issue occurred when players answered
quickly after a question started - React's async state updates meant
currentCorrectShape could hold the previous question's value. Added
currentCorrectShapeRef to ensure the latest value is always used.
Scoreboard Improvements:
- Unified desktop/mobile layout: avatar, name, and points on first line;
progress bar on second line; bonus pills on third line
- Removed 5-player limit to show all players
- Added vertical scrolling when player list exceeds viewport
- Fixed layout to prevent content overflow issues
- 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
Add a centralized game configuration system that allows customizable
scoring mechanics and game rules. Users can now set default game
configurations that persist across sessions, and individual quizzes
can have their own configuration overrides.
## New Features
### Game Configuration Options
- Shuffle Questions: Randomize question order when starting a game
- Shuffle Answers: Randomize answer positions for each question
- Host Participates: Toggle whether the host plays as a competitor
or spectates (host now shows as 'Spectator' when not participating)
- Streak Bonus: Multiplied points for consecutive correct answers,
with configurable threshold and multiplier values
- Comeback Bonus: Extra points for players ranked below top 3
- Wrong Answer Penalty: Deduct percentage of max points for incorrect
answers (configurable percentage)
- First Correct Bonus: Extra points for the first player to answer
correctly on each question
### Default Settings Management
- New Settings icon in landing page header (authenticated users only)
- DefaultConfigModal for editing user-wide default game settings
- Default configs are loaded when creating new quizzes
- Defaults persist to database via new user API endpoints
### Reusable UI Components
- GameConfigPanel: Comprehensive toggle-based settings panel with
expandable sub-options, tooltips, and suggested values based on
question count
- DefaultConfigModal: Modal wrapper for editing default configurations
## Technical Changes
### Frontend
- New useUserConfig hook for fetching/saving user default configurations
- QuizEditor now uses GameConfigPanel instead of inline toggle checkboxes
- GameScreen handles spectator mode with disabled answer buttons
- Updated useGame hook with new scoring calculations and config state
- Improved useAuthenticatedFetch with deduped silent refresh and
redirect-once pattern to prevent multiple auth redirects
### Backend
- Added game_config column to quizzes table (JSON storage)
- Added default_game_config column to users table
- New PATCH endpoint for quiz config updates: /api/quizzes/:id/config
- New PUT endpoint for user defaults: /api/users/me/default-config
- Auto-migration in connection.ts for existing databases
### Scoring System
- New calculatePoints() function in constants.ts handles all scoring
logic including streaks, comebacks, penalties, and first-correct bonus
- New calculateBasePoints() for time-based point calculation
- New getPlayerRank() helper for comeback bonus eligibility
### Tests
- Added tests for DefaultConfigModal component
- Added tests for GameConfigPanel component
- Added tests for QuizEditor config integration
- Added tests for useUserConfig hook
- Updated API tests for new endpoints
## Type Changes
- Added GameConfig interface with all configuration options
- Added DEFAULT_GAME_CONFIG constant with sensible defaults
- Quiz type now includes optional config property