mirror of
https://github.com/pupperpowell/bibdle.git
synced 2026-04-05 17:33:31 -04:00
Updated streak-percentile to count all players from the last 30 days (or
all active streaks if players have a greater than 30 day streak)
This commit is contained in:
@@ -119,8 +119,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{#if streakPercentile !== null}
|
{#if streakPercentile !== null}
|
||||||
<p class="text-sm mt-4 text-gray-700 font-triodion">
|
<p class="text-sm mt-4 text-gray-700 font-triodion">
|
||||||
Only {streakPercentile}% of players have a streak of {streak}
|
{streakPercentile <= 50 ? "Only " : ""}{streakPercentile}% of players have a streak of {streak} or greater.
|
||||||
or greater.
|
|
||||||
</p>
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -38,13 +38,30 @@ export const GET: RequestHandler = async ({ url }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the current streak for each user
|
// Calculate the current streak for each user.
|
||||||
const streaks: number[] = [];
|
// Start from today; if the user hasn't played today yet, try yesterday so
|
||||||
|
// that streaks aren't zeroed out mid-day before the player has had a chance
|
||||||
|
// to complete today's puzzle.
|
||||||
|
const yesterday = new Date(`${localDate}T00:00:00`);
|
||||||
|
yesterday.setDate(yesterday.getDate() - 1);
|
||||||
|
const yesterdayStr = yesterday.toLocaleDateString('en-CA');
|
||||||
|
|
||||||
|
const thirtyDaysAgo = new Date(`${localDate}T00:00:00`);
|
||||||
|
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
|
||||||
|
const thirtyDaysAgoStr = thirtyDaysAgo.toLocaleDateString('en-CA');
|
||||||
|
|
||||||
|
// For each user, compute their current streak and whether they've played
|
||||||
|
// within the last 30 days. "Eligible players" = active streak OR recent play.
|
||||||
|
const userStats: { streak: number; isEligible: boolean }[] = [];
|
||||||
for (const [, dates] of byUser) {
|
for (const [, dates] of byUser) {
|
||||||
// dates are already desc-sorted
|
// dates are already desc-sorted
|
||||||
const dateSet = new Set(dates);
|
const dateSet = new Set(dates);
|
||||||
|
|
||||||
|
// Pick the most recent anchor: today if played, otherwise yesterday
|
||||||
|
const anchor = dateSet.has(localDate) ? localDate : yesterdayStr;
|
||||||
|
|
||||||
let streak = 0;
|
let streak = 0;
|
||||||
let cursor = new Date(`${localDate}T00:00:00`);
|
let cursor = new Date(`${anchor}T00:00:00`);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const dateStr = cursor.toLocaleDateString('en-CA');
|
const dateStr = cursor.toLocaleDateString('en-CA');
|
||||||
@@ -53,20 +70,34 @@ export const GET: RequestHandler = async ({ url }) => {
|
|||||||
cursor.setDate(cursor.getDate() - 1);
|
cursor.setDate(cursor.getDate() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
streaks.push(streak);
|
const hasRecentPlay = dates.some((d) => d >= thirtyDaysAgoStr);
|
||||||
|
userStats.push({ streak, isEligible: streak >= 1 || hasRecentPlay });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only count users who have an active streak (streak >= 1)
|
const eligiblePlayers = userStats.filter((u) => u.isEligible);
|
||||||
const activeStreaks = streaks.filter((s) => s >= 1);
|
|
||||||
|
|
||||||
if (activeStreaks.length === 0) {
|
if (eligiblePlayers.length === 0) {
|
||||||
|
console.log('[streak-percentile] No eligible players found, returning 100th percentile');
|
||||||
return json({ percentile: 100 });
|
return json({ percentile: 100 });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Percentage of active-streak users who have a streak >= targetStreak
|
// Percentage of eligible players who have a streak >= targetStreak
|
||||||
const atOrAbove = activeStreaks.filter((s) => s >= targetStreak).length;
|
const atOrAbove = eligiblePlayers.filter((u) => u.streak >= targetStreak).length;
|
||||||
const raw = (atOrAbove / activeStreaks.length) * 100;
|
const raw = (atOrAbove / eligiblePlayers.length) * 100;
|
||||||
const percentile = raw < 1 ? Math.round(raw * 100) / 100 : Math.round(raw);
|
const percentile = raw < 1 ? Math.round(raw * 100) / 100 : Math.round(raw);
|
||||||
|
|
||||||
|
console.log('[streak-percentile]', {
|
||||||
|
localDate,
|
||||||
|
targetStreak,
|
||||||
|
totalUsers: byUser.size,
|
||||||
|
totalRows: rows.length,
|
||||||
|
eligiblePlayers: eligiblePlayers.length,
|
||||||
|
activeStreaks: userStats.filter((u) => u.streak >= 1).length,
|
||||||
|
recentPlayers: userStats.filter((u) => u.isEligible).length,
|
||||||
|
atOrAbove,
|
||||||
|
raw,
|
||||||
|
percentile,
|
||||||
|
});
|
||||||
|
|
||||||
return json({ percentile });
|
return json({ percentile });
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user