feat: add monthlyHistory[] per player via getMonthlyHistory + bulk fetch (#6)
Add getMonthlyHistory() to models/player for single-player use and getAllMonthlyHistoriesFromDB() for bulk fetches (one query, grouped in memory). Wire monthlyHistory into all player objects returned by getPlayerDataFromDB and getAllRatingsFromDB. Bulk path pre-fetches in one query to avoid N extra per-player queries.
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
const { db } = require('../db');
|
||||
const { getPlayerFromDB, getRoundHistoryFromDB, savePredictedRatingToDB, savePlayerToDB } = require('../models/player');
|
||||
const { getPlayerFromDB, getRoundHistoryFromDB, savePredictedRatingToDB, savePlayerToDB, getMonthlyHistory, getAllMonthlyHistoriesFromDB } = require('../models/player');
|
||||
const { fetchPlayerDataHTTP, parsePlayerData } = require('../scrapers/player-http');
|
||||
const { calculatePredictedRating } = require('./rating-calculator');
|
||||
const logger = require('../logger');
|
||||
|
||||
async function getPlayerDataFromDB(pdgaNumber) {
|
||||
async function getPlayerDataFromDB(pdgaNumber, { includeMonthlyHistory = true } = {}) {
|
||||
try {
|
||||
const cachedPlayer = await getPlayerFromDB(pdgaNumber);
|
||||
if (cachedPlayer) {
|
||||
@@ -23,6 +23,11 @@ async function getPlayerDataFromDB(pdgaNumber) {
|
||||
const resolvedPredicted = predictedRating > 0 ? predictedRating : null;
|
||||
const resolvedStdDev = stdDev > 0 ? stdDev : null;
|
||||
|
||||
// Skip in bulk-fetch paths where caller supplies history via getAllMonthlyHistoriesFromDB
|
||||
const monthlyHistory = includeMonthlyHistory
|
||||
? await getMonthlyHistory(cachedPlayer.pdga_number)
|
||||
: [];
|
||||
|
||||
return {
|
||||
pdgaNumber: cachedPlayer.pdga_number,
|
||||
name: cachedPlayer.name,
|
||||
@@ -34,7 +39,7 @@ async function getPlayerDataFromDB(pdgaNumber) {
|
||||
lastMonthRating: (rating != null && ratingChange != null) ? rating - ratingChange : null,
|
||||
// gap between next predicted update and current rating (null when either is missing)
|
||||
deltaPredicted: (resolvedPredicted != null && rating != null) ? resolvedPredicted - rating : null,
|
||||
monthlyHistory: []
|
||||
monthlyHistory
|
||||
};
|
||||
}
|
||||
return null;
|
||||
@@ -137,6 +142,9 @@ async function getAllRatingsFromDB(progressCallback = null) {
|
||||
|
||||
logger.info(`Loading ${allPlayers.length} players from database...`);
|
||||
|
||||
// Fetch all monthly histories in one query so the per-player loop doesn't add N extra queries
|
||||
const monthlyHistoryMap = await getAllMonthlyHistoriesFromDB(12);
|
||||
|
||||
const ratings = [];
|
||||
const total = allPlayers.length;
|
||||
|
||||
@@ -154,9 +162,10 @@ async function getAllRatingsFromDB(progressCallback = null) {
|
||||
}
|
||||
|
||||
try {
|
||||
const playerData = await getPlayerDataFromDB(pdgaNumber);
|
||||
const playerData = await getPlayerDataFromDB(pdgaNumber, { includeMonthlyHistory: false });
|
||||
|
||||
if (playerData) {
|
||||
playerData.monthlyHistory = monthlyHistoryMap.get(pdgaNumber) ?? [];
|
||||
ratings.push(playerData);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user