fallback to monthlyHistory for lastMonthRating
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user