GitHub Action
Automated sync to Hugging Face
bcce530
import { NextRequest, NextResponse } from "next/server"
import prisma from "@/lib/prisma"
// Thunderdome vote model and tracking
// GET - Get model leaderboard from Thunderdome battles
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url)
const period = searchParams.get("period") || "all" // all, week, month
// Calculate date filter
let dateFilter: Date | undefined
if (period === "week") {
dateFilter = new Date()
dateFilter.setDate(dateFilter.getDate() - 7)
} else if (period === "month") {
dateFilter = new Date()
dateFilter.setMonth(dateFilter.getMonth() - 1)
}
// Get all saved comparisons (thunderdome battles)
const whereClause: Record<string, unknown> = { type: "thunderdome" }
if (dateFilter) {
whereClause.createdAt = { gte: dateFilter }
}
const battles = await prisma.savedComparison.findMany({
where: whereClause,
select: {
id: true,
results: true,
winner: true,
createdAt: true,
},
})
// Aggregate wins and votes by model
const modelStats: Record<string, {
wins: number
battles: number
totalVotes: number
}> = {}
battles.forEach(battle => {
const results = battle.results as Array<{
model: string
votes: number
}>
results.forEach(result => {
if (!modelStats[result.model]) {
modelStats[result.model] = { wins: 0, battles: 0, totalVotes: 0 }
}
modelStats[result.model].battles += 1
modelStats[result.model].totalVotes += result.votes || 0
if (battle.winner === result.model) {
modelStats[result.model].wins += 1
}
})
})
// Calculate win rates and sort
const leaderboard = Object.entries(modelStats)
.map(([model, stats]) => ({
model,
wins: stats.wins,
battles: stats.battles,
totalVotes: stats.totalVotes,
winRate: stats.battles > 0 ? (stats.wins / stats.battles) * 100 : 0,
}))
.sort((a, b) => {
// Sort by win rate, then by total battles
if (b.winRate !== a.winRate) return b.winRate - a.winRate
return b.battles - a.battles
})
// Get recent battles for display
const recentBattles = await prisma.savedComparison.findMany({
where: { type: "thunderdome" },
orderBy: { createdAt: "desc" },
take: 10,
select: {
id: true,
name: true,
prompt: true,
results: true,
winner: true,
createdAt: true,
},
})
return NextResponse.json({
leaderboard,
recentBattles,
totalBattles: battles.length,
period,
})
} catch (error) {
console.error("Error fetching thunderdome stats:", error)
return NextResponse.json(
{ error: "Failed to fetch thunderdome stats" },
{ status: 500 }
)
}
}
// POST - Record a community vote on a battle
export async function POST(request: NextRequest) {
try {
const { battleId, modelVote, userId } = await request.json()
if (!battleId || !modelVote) {
return NextResponse.json(
{ error: "battleId and modelVote are required" },
{ status: 400 }
)
}
// Get the battle
const battle = await prisma.savedComparison.findUnique({
where: { id: battleId },
})
if (!battle) {
return NextResponse.json(
{ error: "Battle not found" },
{ status: 404 }
)
}
// Update the vote count for the model
const results = battle.results as Array<{
model: string
output: string
votes: number
}>
const updatedResults = results.map(result => {
if (result.model === modelVote) {
return { ...result, votes: (result.votes || 0) + 1 }
}
return result
})
// Determine new winner
const maxVotes = Math.max(...updatedResults.map(r => r.votes || 0))
const newWinner = maxVotes > 0
? updatedResults.find(r => r.votes === maxVotes)?.model || battle.winner
: battle.winner
// Update the battle
await prisma.savedComparison.update({
where: { id: battleId },
data: {
results: updatedResults,
winner: newWinner,
},
})
return NextResponse.json({
success: true,
updatedResults,
winner: newWinner,
})
} catch (error) {
console.error("Error recording vote:", error)
return NextResponse.json(
{ error: "Failed to record vote" },
{ status: 500 }
)
}
}