From 2b87669f4174ce42ba29ca41bf886a69000dd1c9 Mon Sep 17 00:00:00 2001 From: Fahri Can Date: Wed, 13 May 2026 16:56:14 +0300 Subject: [PATCH] gg --- src/modules/feeder/feeder.service.ts | 18 ++++++++++++ src/tasks/data-fetcher.task.ts | 44 ++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/modules/feeder/feeder.service.ts b/src/modules/feeder/feeder.service.ts index 8af93ed..687ebd0 100755 --- a/src/modules/feeder/feeder.service.ts +++ b/src/modules/feeder/feeder.service.ts @@ -256,6 +256,24 @@ export class FeederService { this.logger.log("🎉 HISTORICAL SCAN COMPLETED"); } + // ============================================ + // INTRADAY ARCHIVE: finished live matches → matches table + // ============================================ + async archiveCompletedMatchesForDate( + dateStr: string, + sports: Sport[] = this.SPORTS, + ): Promise { + this.logger.log( + `📦 Archiving completed matches for ${dateStr} [${sports.join(", ")}]`, + ); + for (const sport of sports) { + await this.processDate(dateStr, sport, [], { + onlyCompletedMatches: true, + refreshExistingMatches: false, + }); + } + } + // ============================================ // PROCESS SINGLE DATE // ============================================ diff --git a/src/tasks/data-fetcher.task.ts b/src/tasks/data-fetcher.task.ts index 19eadff..0b3850f 100755 --- a/src/tasks/data-fetcher.task.ts +++ b/src/tasks/data-fetcher.task.ts @@ -21,6 +21,7 @@ import { getShiftedDateStringInTimeZone, } from "../common/utils/timezone.util"; import { TaskLockService } from "./task-lock.service"; +import { FeederService } from "../modules/feeder/feeder.service"; // ──────────────────────────────────────────────────────────────── // Types @@ -106,6 +107,7 @@ export class DataFetcherTask { private readonly prisma: PrismaService, private readonly scraper: FeederScraperService, private readonly taskLock: TaskLockService, + private readonly feeder: FeederService, ) {} // ──────────────────────────────────────────────────────────── @@ -203,6 +205,7 @@ export class DataFetcherTask { await this.syncMatchList(today); await this.syncMatchList(tomorrow); await this.updateLiveScores(); + await this.archiveNewlyFinishedMatches(today); await this.settlePredictionRuns(); await this.fetchOddsForMatches(); await this.fillMissingLineups(); @@ -210,6 +213,43 @@ export class DataFetcherTask { this.logger.log("syncLiveMatches END"); } + private async archiveNewlyFinishedMatches(todayStr: string): Promise { + try { + const finishedLive = await this.prisma.liveMatch.findMany({ + where: { + OR: [ + { status: { in: FINISHED_STATUS_VALUES_FOR_DB } }, + { state: { in: FINISHED_STATE_VALUES_FOR_DB } }, + ], + scoreHome: { not: null }, + scoreAway: { not: null }, + }, + select: { id: true }, + }); + + if (finishedLive.length === 0) return; + + const ids = finishedLive.map((m) => m.id); + const alreadyArchived = await this.prisma.match.findMany({ + where: { id: { in: ids } }, + select: { id: true }, + }); + + const archivedSet = new Set(alreadyArchived.map((m) => m.id)); + const newCount = ids.filter((id) => !archivedSet.has(id)).length; + + if (newCount === 0) return; + + this.logger.log( + `${newCount} finished match(es) not yet archived — running feeder for ${todayStr}`, + ); + await this.feeder.archiveCompletedMatchesForDate(todayStr); + } catch (error: unknown) { + const message = error instanceof Error ? error.message : String(error); + this.logger.error(`archiveNewlyFinishedMatches failed: ${message}`); + } + } + private async syncMatchList(date: string): Promise { // Football const footballLeagues = this.loadLeagueFilterSet("qualified_leagues.json"); @@ -1080,8 +1120,8 @@ export class DataFetcherTask { status: storedStatus, scoreHome: sHome, scoreAway: sAway, - htScoreHome: sHtHome, - htScoreAway: sHtAway, + ...(sHtHome !== null && { htScoreHome: sHtHome }), + ...(sHtAway !== null && { htScoreAway: sHtAway }), homeTeamId: homeTeamId, awayTeamId: awayTeamId, updatedAt: new Date(),