fallback to monthlyHistory for lastMonthRating

This commit is contained in:
Samuel Enocsson
2026-05-21 15:58:48 +02:00
parent 4b145094bf
commit a7562e9b47
+30 -3
View File
@@ -4,6 +4,28 @@ const { fetchPlayerDataHTTP, parsePlayerData } = require('../scrapers/player-htt
const { calculatePredictedRating } = require('./rating-calculator'); const { calculatePredictedRating } = require('./rating-calculator');
const logger = require('../logger'); const logger = require('../logger');
// Derives previous-month rating and the delta to it. Prefers PDGA's reported
// rating_change (canonical), falls back to our own monthly snapshots when
// rating_change is missing — common for players whose latest scrape failed.
function deriveMonthlyDeltas(rating, rawRatingChange, monthlyHistory) {
if (rating != null && rawRatingChange != null) {
return { lastMonthRating: rating - rawRatingChange, ratingChange: rawRatingChange };
}
if (rating != null && monthlyHistory && monthlyHistory.length >= 1) {
// The "last month" snapshot depends on whether current_rating is already in
// history. If equal, current is the most recent entry — last month is the one
// before it. If not, current is newer than history — the latest entry IS last month.
const lastIdx = monthlyHistory.length - 1;
const lastMonth = (monthlyHistory[lastIdx] === rating)
? (monthlyHistory.length >= 2 ? monthlyHistory[lastIdx - 1] : null)
: monthlyHistory[lastIdx];
if (lastMonth != null) {
return { lastMonthRating: lastMonth, ratingChange: rating - lastMonth };
}
}
return { lastMonthRating: null, ratingChange: rawRatingChange };
}
async function getPlayerDataFromDB(pdgaNumber, { includeMonthlyHistory = true } = {}) { async function getPlayerDataFromDB(pdgaNumber, { includeMonthlyHistory = true } = {}) {
try { try {
const cachedPlayer = await getPlayerFromDB(pdgaNumber); const cachedPlayer = await getPlayerFromDB(pdgaNumber);
@@ -19,7 +41,7 @@ async function getPlayerDataFromDB(pdgaNumber, { includeMonthlyHistory = true }
} }
const rating = cachedPlayer.current_rating; const rating = cachedPlayer.current_rating;
const ratingChange = cachedPlayer.rating_change; const rawRatingChange = cachedPlayer.rating_change;
const resolvedPredicted = predictedRating > 0 ? predictedRating : null; const resolvedPredicted = predictedRating > 0 ? predictedRating : null;
const resolvedStdDev = stdDev > 0 ? stdDev : null; const resolvedStdDev = stdDev > 0 ? stdDev : null;
@@ -28,6 +50,8 @@ async function getPlayerDataFromDB(pdgaNumber, { includeMonthlyHistory = true }
? await getMonthlyHistory(cachedPlayer.pdga_number) ? await getMonthlyHistory(cachedPlayer.pdga_number)
: []; : [];
const { lastMonthRating, ratingChange } = deriveMonthlyDeltas(rating, rawRatingChange, monthlyHistory);
return { return {
pdgaNumber: cachedPlayer.pdga_number, pdgaNumber: cachedPlayer.pdga_number,
name: cachedPlayer.name, name: cachedPlayer.name,
@@ -35,8 +59,7 @@ async function getPlayerDataFromDB(pdgaNumber, { includeMonthlyHistory = true }
ratingChange, ratingChange,
predictedRating: resolvedPredicted, predictedRating: resolvedPredicted,
stdDev: resolvedStdDev, stdDev: resolvedStdDev,
// previous month's official rating (null when either value is missing) lastMonthRating,
lastMonthRating: (rating != null && ratingChange != null) ? rating - ratingChange : null,
// gap between next predicted update and current rating (null when either is missing) // gap between next predicted update and current rating (null when either is missing)
deltaPredicted: (resolvedPredicted != null && rating != null) ? resolvedPredicted - rating : null, deltaPredicted: (resolvedPredicted != null && rating != null) ? resolvedPredicted - rating : null,
monthlyHistory monthlyHistory
@@ -166,6 +189,10 @@ async function getAllRatingsFromDB(progressCallback = null) {
if (playerData) { if (playerData) {
playerData.monthlyHistory = monthlyHistoryMap.get(pdgaNumber) ?? []; playerData.monthlyHistory = monthlyHistoryMap.get(pdgaNumber) ?? [];
// Re-derive now that history is attached — bulk path skipped includeMonthlyHistory
const derived = deriveMonthlyDeltas(playerData.rating, player.rating_change, playerData.monthlyHistory);
playerData.lastMonthRating = derived.lastMonthRating;
playerData.ratingChange = derived.ratingChange;
ratings.push(playerData); ratings.push(playerData);
} }