e3d4f7c96e
Build and Deploy / build-and-deploy (push) Has been cancelled
- Fix memory leak: revoke object URLs in TimelineUploadSection - Fix broken timeline photo URLs in admin panel (/data/... → /api/files/...) - Remove duplicate bad-word list in AI moderation function - Add input validation for type/status params in media and contributions API - Add bulk-approve button in admin for pending contributions - Add PATCH endpoint for bulk-approving all pending contributions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
40 lines
1.0 KiB
TypeScript
40 lines
1.0 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
import { getDb } from '@/lib/db'
|
|
|
|
export const runtime = 'nodejs'
|
|
|
|
const VALID_TYPES = ['photo', 'video', 'music']
|
|
const VALID_STATUSES = ['approved', 'pending', 'rejected', 'flagged']
|
|
|
|
export async function GET(req: NextRequest) {
|
|
const type = req.nextUrl.searchParams.get('type')
|
|
const status = req.nextUrl.searchParams.get('status')
|
|
|
|
if (type && !VALID_TYPES.includes(type)) {
|
|
return NextResponse.json({ error: 'Invalid type' }, { status: 400 })
|
|
}
|
|
if (status && !VALID_STATUSES.includes(status)) {
|
|
return NextResponse.json({ error: 'Invalid status' }, { status: 400 })
|
|
}
|
|
|
|
const db = getDb()
|
|
|
|
let query = 'SELECT * FROM media WHERE 1=1'
|
|
const queryParams: string[] = []
|
|
|
|
if (type) {
|
|
query += ' AND type = ?'
|
|
queryParams.push(type)
|
|
}
|
|
|
|
if (status) {
|
|
query += ' AND status = ?'
|
|
queryParams.push(status)
|
|
}
|
|
|
|
query += ' ORDER BY sort_order, created_at'
|
|
|
|
const media = db.prepare(query).all(...queryParams)
|
|
return NextResponse.json(media)
|
|
}
|