68 lines
1.9 KiB
TypeScript
68 lines
1.9 KiB
TypeScript
|
|
import { prisma } from '@/lib/prisma'
|
||
|
|
import { activateRound, closeRound } from './round-engine'
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Check for rounds that need to be automatically opened or closed
|
||
|
|
* based on their windowOpenAt / windowCloseAt timestamps.
|
||
|
|
* Called on a 60-second interval from instrumentation.ts.
|
||
|
|
*/
|
||
|
|
export async function processScheduledRounds(): Promise<{
|
||
|
|
activated: number
|
||
|
|
closed: number
|
||
|
|
}> {
|
||
|
|
const now = new Date()
|
||
|
|
let activated = 0
|
||
|
|
let closed = 0
|
||
|
|
|
||
|
|
// Find a SUPER_ADMIN to use as the actor for audit logging
|
||
|
|
const systemActor = await prisma.user.findFirst({
|
||
|
|
where: { role: 'SUPER_ADMIN' },
|
||
|
|
select: { id: true },
|
||
|
|
})
|
||
|
|
|
||
|
|
if (!systemActor) {
|
||
|
|
return { activated, closed }
|
||
|
|
}
|
||
|
|
|
||
|
|
// 1. Activate DRAFT rounds whose windowOpenAt has arrived
|
||
|
|
const roundsToOpen = await prisma.round.findMany({
|
||
|
|
where: {
|
||
|
|
status: 'ROUND_DRAFT',
|
||
|
|
windowOpenAt: { lte: now },
|
||
|
|
competition: { status: { not: 'ARCHIVED' } },
|
||
|
|
},
|
||
|
|
select: { id: true, name: true },
|
||
|
|
})
|
||
|
|
|
||
|
|
for (const round of roundsToOpen) {
|
||
|
|
const result = await activateRound(round.id, systemActor.id, prisma)
|
||
|
|
if (result.success) {
|
||
|
|
activated++
|
||
|
|
console.log(`[RoundScheduler] Activated round: ${round.name}`)
|
||
|
|
} else {
|
||
|
|
console.warn(`[RoundScheduler] Failed to activate "${round.name}":`, result.errors)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 2. Close ACTIVE rounds whose windowCloseAt has passed
|
||
|
|
const roundsToClose = await prisma.round.findMany({
|
||
|
|
where: {
|
||
|
|
status: 'ROUND_ACTIVE',
|
||
|
|
windowCloseAt: { lte: now },
|
||
|
|
},
|
||
|
|
select: { id: true, name: true },
|
||
|
|
})
|
||
|
|
|
||
|
|
for (const round of roundsToClose) {
|
||
|
|
const result = await closeRound(round.id, systemActor.id, prisma)
|
||
|
|
if (result.success) {
|
||
|
|
closed++
|
||
|
|
console.log(`[RoundScheduler] Closed round: ${round.name}`)
|
||
|
|
} else {
|
||
|
|
console.warn(`[RoundScheduler] Failed to close "${round.name}":`, result.errors)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return { activated, closed }
|
||
|
|
}
|