diff --git a/app/features/tournament-bracket/core/Tournament.server.ts b/app/features/tournament-bracket/core/Tournament.server.ts index 30c1fc6c7..7f6442104 100644 --- a/app/features/tournament-bracket/core/Tournament.server.ts +++ b/app/features/tournament-bracket/core/Tournament.server.ts @@ -1,8 +1,10 @@ +import { sub } from "date-fns"; import { clearCombinedStreamsCache } from "~/features/core/streams/streams.server"; import * as TournamentRepository from "~/features/tournament/TournamentRepository.server"; import { getTentativeTier } from "~/features/tournament-organization/core/tentativeTiers.server"; import type { TournamentManagerDataSet } from "~/modules/brackets-manager/types"; import { isAdmin } from "~/modules/permissions/utils"; +import { databaseTimestampToDate } from "~/utils/dates"; import { notFoundIfFalsy } from "~/utils/remix.server"; import type { Unwrapped } from "~/utils/types"; import { getServerTournamentManager } from "./brackets-manager/manager.server"; @@ -135,8 +137,31 @@ export function clearAllTournamentDataCache() { tournamentDataCache.clear(); } +const RUNNING_TOURNAMENT_MAX_AGE_HOURS = 6; + +function mostRecentStartTime(tournament: Tournament) { + const bracketStartTimes = tournament.ctx.settings.bracketProgression + .filter((b) => b.startTime) + .map((b) => databaseTimestampToDate(b.startTime!)); + + const allStartTimes = [tournament.ctx.startTime, ...bracketStartTimes]; + + return allStartTimes + .filter((t) => t <= new Date()) + .sort((a, b) => b.getTime() - a.getTime())[0]; +} + +function isTournamentLive(tournament: Tournament) { + if (!tournament.hasStarted || tournament.everyBracketOver) return false; + + const cutoff = sub(new Date(), { hours: RUNNING_TOURNAMENT_MAX_AGE_HOURS }); + const latestStartTime = mostRecentStartTime(tournament); + + return Boolean(latestStartTime && latestStartTime >= cutoff); +} + function syncTournamentToRegistry(tournament: Tournament) { - const isRunning = tournament.hasStarted && !tournament.everyBracketOver; + const isRunning = isTournamentLive(tournament); const wasInRegistry = RunningTournaments.has(tournament.ctx.id); if (isRunning) { diff --git a/app/features/tournament/TournamentRepository.server.ts b/app/features/tournament/TournamentRepository.server.ts index e85280e0d..4deb7d6a5 100644 --- a/app/features/tournament/TournamentRepository.server.ts +++ b/app/features/tournament/TournamentRepository.server.ts @@ -1240,7 +1240,7 @@ export function updateTournamentTier({ export async function findRunningTournamentIds() { const now = new Date(); - const oneDayAgo = sub(now, { days: 1 }); + const cutoff = sub(now, { days: 2 }); const rows = await db .selectFrom("Tournament") @@ -1253,11 +1253,7 @@ export async function findRunningTournamentIds() { .select("Tournament.id") .where("Tournament.isFinalized", "=", 0) .where("CalendarEventDate.startTime", "<", dateToDatabaseTimestamp(now)) - .where( - "CalendarEventDate.startTime", - ">", - dateToDatabaseTimestamp(oneDayAgo), - ) + .where("CalendarEventDate.startTime", ">", dateToDatabaseTimestamp(cutoff)) .where((eb) => eb.exists( eb