// ST-1107: Vercel cron handler die verlopen Claude-vragen op 'expired' zet. // // Wordt dagelijks om 04:00 UTC door Vercel POST'd (zie vercel.json crons- // config; Vercel Hobby-plan staat alleen daily crons toe — Pro ondersteunt // fijnmaziger). Auth is // via een gedeeld secret in de Authorization-header — Vercel injecteert // `Authorization: Bearer ` automatisch wanneer de env-var op de // project-omgeving staat. // // Bonus (ST-1107.4): zelfde route ruimt ook M10's verlopen `pending` // login_pairings op. Reden: één cron-job is goedkoper qua Vercel-budget en // houdt de cleanup-strategie centraal. import { prisma } from '@/lib/prisma' export const runtime = 'nodejs' export async function POST(request: Request) { const auth = request.headers.get('authorization') const expected = process.env.CRON_SECRET if (!expected || auth !== `Bearer ${expected}`) { return Response.json({ error: 'Unauthorized' }, { status: 401 }) } const now = new Date() // M11: open Claude-vragen → expired const expiredQuestions = await prisma.claudeQuestion.updateMany({ where: { status: 'open', expires_at: { lt: now } }, data: { status: 'expired' }, }) // M10: pending login_pairings die niet meer bruikbaar zijn → cancelled // (status='expired' bestaat niet voor pairings; cancelled heeft hetzelfde // resultaat: niet-claimable, niet meer in de SSE-listener.) const expiredPairings = await prisma.loginPairing.updateMany({ where: { status: 'pending', expires_at: { lt: now } }, data: { status: 'cancelled' }, }) return Response.json({ expired_questions: expiredQuestions.count, expired_pairings: expiredPairings.count, ran_at: now.toISOString(), }) }