open-prompt / src /app /api /badges /route.ts
GitHub Action
Automated sync to Hugging Face
bcce530
import { NextRequest, NextResponse } from "next/server"
import prisma from "@/lib/prisma"
// Badge types and their criteria
export type BadgeType =
| "verified-quality" // 95%+ success rate
| "framework-compliant" // Uses RACE, CARE, APE, etc.
| "high-performance" // Fast + low token usage
| "community-favorite" // High stars + runs
| "trending" // High recent activity
| "prolific-creator" // Many prompts created
interface Badge {
type: BadgeType
label: string
description: string
icon: string
}
const BADGE_DEFINITIONS: Record<BadgeType, Badge> = {
"verified-quality": {
type: "verified-quality",
label: "Verified Quality",
description: "95%+ success rate",
icon: "✓"
},
"framework-compliant": {
type: "framework-compliant",
label: "Framework Compliant",
description: "Uses structured prompting framework",
icon: "📐"
},
"high-performance": {
type: "high-performance",
label: "High Performance",
description: "Fast and efficient",
icon: "⚡"
},
"community-favorite": {
type: "community-favorite",
label: "Community Favorite",
description: "Loved by the community",
icon: "❤️"
},
"trending": {
type: "trending",
label: "Trending",
description: "High recent activity",
icon: "🔥"
},
"prolific-creator": {
type: "prolific-creator",
label: "Prolific Creator",
description: "Created many quality prompts",
icon: "⭐"
}
}
// Calculate badges for a prompt
export function calculatePromptBadges(prompt: {
totalRuns: number
starsCount: number
remixesCount: number
framework?: string | null
badges?: string[]
}): BadgeType[] {
const badges: BadgeType[] = []
// Framework Compliant - has a framework assigned
if (prompt.framework) {
badges.push("framework-compliant")
}
// Community Favorite - 50+ stars or 1000+ runs
if (prompt.starsCount >= 50 || prompt.totalRuns >= 1000) {
badges.push("community-favorite")
}
// High Performance - high usage indicates it works well
if (prompt.totalRuns >= 500 && prompt.starsCount >= 20) {
badges.push("high-performance")
}
// Trending - high recent activity (approximated by total stats)
if (prompt.totalRuns >= 100 && prompt.remixesCount >= 5) {
badges.push("trending")
}
// Verified Quality - good star-to-run ratio
const starRatio = prompt.totalRuns > 0 ? prompt.starsCount / prompt.totalRuns : 0
if (starRatio >= 0.1 && prompt.totalRuns >= 50) {
badges.push("verified-quality")
}
return badges
}
// GET - Get badges for a prompt
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url)
const promptId = searchParams.get("promptId")
const promptSlug = searchParams.get("slug")
if (!promptId && !promptSlug) {
return NextResponse.json(
{ error: "promptId or slug is required" },
{ status: 400 }
)
}
const prompt = await prisma.prompt.findFirst({
where: promptId
? { id: promptId }
: { slug: promptSlug! },
select: {
id: true,
totalRuns: true,
starsCount: true,
remixesCount: true,
framework: true,
badges: true,
}
})
if (!prompt) {
return NextResponse.json(
{ error: "Prompt not found" },
{ status: 404 }
)
}
const calculatedBadges = calculatePromptBadges(prompt)
// Return badge details
const badgeDetails = calculatedBadges.map(type => BADGE_DEFINITIONS[type])
return NextResponse.json({
promptId: prompt.id,
badges: badgeDetails,
badgeTypes: calculatedBadges
})
} catch (error) {
console.error("Error fetching badges:", error)
return NextResponse.json(
{ error: "Failed to fetch badges" },
{ status: 500 }
)
}
}
// POST - Recalculate and update badges for a prompt
export async function POST(request: NextRequest) {
try {
const { promptId } = await request.json()
if (!promptId) {
return NextResponse.json(
{ error: "promptId is required" },
{ status: 400 }
)
}
const prompt = await prisma.prompt.findUnique({
where: { id: promptId },
select: {
id: true,
totalRuns: true,
starsCount: true,
remixesCount: true,
framework: true,
}
})
if (!prompt) {
return NextResponse.json(
{ error: "Prompt not found" },
{ status: 404 }
)
}
const calculatedBadges = calculatePromptBadges(prompt)
// Update badges in database
await prisma.prompt.update({
where: { id: promptId },
data: { badges: calculatedBadges }
})
const badgeDetails = calculatedBadges.map(type => BADGE_DEFINITIONS[type])
return NextResponse.json({
promptId: prompt.id,
badges: badgeDetails,
badgeTypes: calculatedBadges,
updated: true
})
} catch (error) {
console.error("Error updating badges:", error)
return NextResponse.json(
{ error: "Failed to update badges" },
{ status: 500 }
)
}
}