Skip to content

Commit a3a10f5

Browse files
committed
Test
1 parent 331fad4 commit a3a10f5

File tree

4 files changed

+16
-6
lines changed

4 files changed

+16
-6
lines changed

.claude/settings.local.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"Bash(ls:*)",
1010
"Bash(git push:*)",
1111
"Bash(grep:*)",
12-
"Bash(mkdir:*)"
12+
"Bash(mkdir:*)",
13+
"Bash(npm run build:*)"
1314
],
1415
"deny": []
1516
}

api/leaderboard.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import User from '../models/User.js';
22
import UserStats from '../models/UserStats.js';
33

4-
// Improved caching with separate keys for different modes
5-
const CACHE_DURATION = 60000; // 1 minute cache
4+
// Production-scale caching for 2M+ users
5+
const CACHE_DURATION = 300000; // 5 minute cache for production performance
6+
const DAILY_CACHE_DURATION = 180000; // 3 minute cache for daily leaderboards (more frequent updates)
67
const cache = new Map();
78

89
function getCacheKey(mode, pastDay) {
@@ -11,7 +12,8 @@ function getCacheKey(mode, pastDay) {
1112

1213
function getCachedData(key) {
1314
const cached = cache.get(key);
14-
if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
15+
const cacheDuration = key.includes('daily') ? DAILY_CACHE_DURATION : CACHE_DURATION;
16+
if (cached && Date.now() - cached.timestamp < cacheDuration) {
1517
return cached.data;
1618
}
1719
return null;

components/gameUI.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ singlePlayerRound={singlePlayerRound} onboarding={onboarding} countryGuesser={co
794794
}} panoShown={showPanoOnResult} />
795795

796796
{/* Critical timer screen warning effect */}
797-
{((timeToNextMultiplayerEvt <= 5 && timeToNextMultiplayerEvt > 0 && multiplayerTimerShown && !showAnswer && !pinPoint && multiplayerState?.inGame && multiplayerState?.gameData?.state === 'guess') ||
797+
{((timeToNextMultiplayerEvt <= 5 && timeToNextMultiplayerEvt > 0 && multiplayerTimerShown && !showAnswer && !pinPoint && multiplayerState?.inGame && multiplayerState?.gameData?.state === 'guess') ||
798798
(timeToNextRound <= 5 && timeToNextRound > 0 && onboardingTimerShown && !showAnswer && !pinPoint && onboarding)) && (
799799
<div className="screen-critical-warning" />
800800
)}

models/UserStats.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,19 @@ const userStatsSchema = new mongoose.Schema({
6060
}
6161
});
6262

63-
// Compound indexes for efficient querying
63+
// Production-grade indexes for 2M+ users with 20k daily active
6464
userStatsSchema.index({ userId: 1, timestamp: -1 }); // User's stats over time (descending)
6565
userStatsSchema.index({ userId: 1, timestamp: 1 }); // User's stats over time (ascending)
6666
userStatsSchema.index({ timestamp: -1, xpRank: 1 }); // Leaderboard snapshots by XP
6767
userStatsSchema.index({ timestamp: -1, eloRank: 1 }); // Leaderboard snapshots by ELO
6868

69+
// CRITICAL: Production performance indexes for daily leaderboards
70+
userStatsSchema.index({ timestamp: -1, userId: 1 }); // Efficient timestamp range + userId lookup
71+
userStatsSchema.index({ timestamp: -1, totalXp: -1 }); // Fast XP leaderboard by time
72+
userStatsSchema.index({ timestamp: -1, elo: -1 }); // Fast ELO leaderboard by time
73+
userStatsSchema.index({ timestamp: -1, userId: 1, totalXp: -1 }); // Compound for XP daily queries
74+
userStatsSchema.index({ timestamp: -1, userId: 1, elo: -1 }); // Compound for ELO daily queries
75+
6976
// Static methods for common queries
7077
userStatsSchema.statics = {
7178

0 commit comments

Comments
 (0)