@@ -161,7 +161,8 @@ export class DataFetcherTask {
|
||||
`Pruned ${deleted.count} stale live matches. Starting full sync...`,
|
||||
);
|
||||
} catch (error: unknown) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
const message =
|
||||
error instanceof Error ? error.message : String(error);
|
||||
this.logger.error(`Stale live_match cleanup failed: ${message}`);
|
||||
return;
|
||||
}
|
||||
@@ -194,12 +195,12 @@ export class DataFetcherTask {
|
||||
|
||||
private async syncMatchList(date: string): Promise<void> {
|
||||
// Football
|
||||
const footballLeagues = this.loadLeagueFilterSet("top_leagues.json");
|
||||
const footballLeagues = this.loadLeagueFilterSet("qualified_leagues.json");
|
||||
if (footballLeagues && footballLeagues.size > 0) {
|
||||
await this.fetchMatchesForSport("football", date, footballLeagues);
|
||||
} else {
|
||||
this.logger.warn(
|
||||
"top_leagues.json is missing/empty — writing ALL football matches",
|
||||
"qualified_leagues.json is missing/empty — writing ALL football matches",
|
||||
);
|
||||
await this.fetchMatchesForSport("football", date, new Set());
|
||||
}
|
||||
@@ -250,7 +251,7 @@ export class DataFetcherTask {
|
||||
}
|
||||
|
||||
this.logger.log(
|
||||
`📡 Updating scores for ${liveMatches.length} live matches`,
|
||||
`LIVE Updating scores for ${liveMatches.length} live matches`,
|
||||
);
|
||||
|
||||
for (const match of liveMatches) {
|
||||
@@ -278,25 +279,25 @@ export class DataFetcherTask {
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.log("📡 Live score update complete");
|
||||
this.logger.log("LIVE Live score update complete");
|
||||
} catch (error: unknown) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
this.logger.error(`Live score update failed: ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────────────────────
|
||||
// Phase 3: Odds + referee + lineups + sidelined
|
||||
// ────────────────────────────────────────────────────────────
|
||||
|
||||
private async fetchOddsForMatches(): Promise<void> {
|
||||
this.logger.log("💰 Fetching odds for live matches...");
|
||||
this.logger.log("MONEY Fetching odds for live matches...");
|
||||
|
||||
try {
|
||||
// Load both league filters
|
||||
// Load both league filters (data-driven qualified leagues)
|
||||
const topLeagueIds: string[] = [];
|
||||
|
||||
const footballLeagues = this.loadLeagueFilterSet("top_leagues.json");
|
||||
const footballLeagues = this.loadLeagueFilterSet(
|
||||
"qualified_leagues.json",
|
||||
);
|
||||
if (footballLeagues) topLeagueIds.push(...footballLeagues);
|
||||
|
||||
const basketballLeagues = this.loadLeagueFilterSet(
|
||||
@@ -337,11 +338,13 @@ export class DataFetcherTask {
|
||||
});
|
||||
|
||||
if (matchesToFetch.length === 0) {
|
||||
this.logger.log("💰 No matches to fetch odds for");
|
||||
this.logger.log("MONEY No matches to fetch odds for");
|
||||
return;
|
||||
}
|
||||
|
||||
this.logger.log(`💰 Fetching odds for ${matchesToFetch.length} matches`);
|
||||
this.logger.log(
|
||||
`MONEY Fetching odds for ${matchesToFetch.length} matches`,
|
||||
);
|
||||
|
||||
let successCount = 0;
|
||||
let errorCount = 0;
|
||||
@@ -370,7 +373,7 @@ export class DataFetcherTask {
|
||||
// Retry failed matches (502/Timeout)
|
||||
if (failedMatches.length > 0) {
|
||||
this.logger.warn(
|
||||
`âš ï¸ Retrying ${failedMatches.length} failed matches (502/Timeout)...`,
|
||||
`Retrying ${failedMatches.length} failed matches (502/Timeout)...`,
|
||||
);
|
||||
|
||||
for (const match of failedMatches) {
|
||||
@@ -378,7 +381,7 @@ export class DataFetcherTask {
|
||||
try {
|
||||
await this.processMatchOdds(match);
|
||||
successCount++;
|
||||
this.logger.log(`✅ Retry successful for match ${match.id}`);
|
||||
this.logger.log(`SUCCESS Retry successful for match ${match.id}`);
|
||||
} catch (retryErr: unknown) {
|
||||
const message =
|
||||
retryErr instanceof Error ? retryErr.message : String(retryErr);
|
||||
@@ -390,7 +393,7 @@ export class DataFetcherTask {
|
||||
}
|
||||
|
||||
this.logger.log(
|
||||
`💰 Odds complete: ${successCount} success, ${errorCount} errors (initially)`,
|
||||
`MONEY Odds complete: ${successCount} success, ${errorCount} errors (initially)`,
|
||||
);
|
||||
} catch (error: unknown) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
@@ -905,12 +908,16 @@ export class DataFetcherTask {
|
||||
|
||||
// Guard: If match already has pre-match odds and is now live/finished,
|
||||
// do NOT overwrite odds/lineups/sidelined — the model needs stable pre-match data.
|
||||
const matchState = match.state?.toLowerCase() ?? '';
|
||||
const matchStatus = match.status?.toLowerCase() ?? '';
|
||||
const matchState = match.state?.toLowerCase() ?? "";
|
||||
const matchStatus = match.status?.toLowerCase() ?? "";
|
||||
const liveStates = LIVE_STATE_VALUES_FOR_DB.map((s) => s.toLowerCase());
|
||||
const liveStatuses = LIVE_STATUS_VALUES_FOR_DB.map((s) => s.toLowerCase());
|
||||
const finishedStates = FINISHED_STATE_VALUES_FOR_DB.map((s) => s.toLowerCase());
|
||||
const finishedStatuses = FINISHED_STATUS_VALUES_FOR_DB.map((s) => s.toLowerCase());
|
||||
const finishedStates = FINISHED_STATE_VALUES_FOR_DB.map((s) =>
|
||||
s.toLowerCase(),
|
||||
);
|
||||
const finishedStatuses = FINISHED_STATUS_VALUES_FOR_DB.map((s) =>
|
||||
s.toLowerCase(),
|
||||
);
|
||||
|
||||
const isLiveOrFinished =
|
||||
liveStates.includes(matchState) ||
|
||||
@@ -921,7 +928,7 @@ export class DataFetcherTask {
|
||||
const existingOdds = match.odds as Record<string, unknown> | null;
|
||||
const hasExistingOdds =
|
||||
!!existingOdds &&
|
||||
typeof existingOdds === 'object' &&
|
||||
typeof existingOdds === "object" &&
|
||||
Object.keys(existingOdds).length > 0;
|
||||
|
||||
if (isLiveOrFinished && hasExistingOdds) {
|
||||
@@ -957,7 +964,7 @@ export class DataFetcherTask {
|
||||
sidelined.awayTeam.totalSidelined > 0))
|
||||
) {
|
||||
this.logger.log(
|
||||
`✅ Loop update: ${match.matchName} | Odds: ${Object.keys(odds).length} | Ref: ${refereeName || "N/A"} | Lineups: ${lineups ? "Yes" : "No"} | Sidelined: ${sidelined ? "Yes" : "No"}`,
|
||||
`SUCCESS Loop update: ${match.matchName} | Odds: ${Object.keys(odds).length} | Ref: ${refereeName || "N/A"} | Lineups: ${lineups ? "Yes" : "No"} | Sidelined: ${sidelined ? "Yes" : "No"}`,
|
||||
);
|
||||
} else {
|
||||
this.logger.debug(
|
||||
@@ -1334,4 +1341,3 @@ export class DataFetcherTask {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user