import { getToken } from "next-auth/jwt"; import { queryOne, run } from "@/lib/db"; export const dynamic = "force-dynamic"; // Disable caching // Ensure the user is an admin async function verifyAdmin(request) { const token = await getToken({ req: request, secret: process.env.NEXTAUTH_SECRET || "your-fallback-secret-should-be-at-least-32-chars", }); if (!token) { return { authorized: false, error: "Unauthorized", status: 401 }; } if (token.role !== "admin") { return { authorized: false, error: "Admin access required", status: 403 }; } return { authorized: true, token }; } // DELETE - Remove a specific clue export async function DELETE(request, context) { try { // Verify admin access const { authorized, error, status } = await verifyAdmin(request); if (!authorized) { return Response.json({ error }, { status }); } const { clueId } = context.params; // Validate clueId is a number if (isNaN(parseInt(clueId))) { return Response.json({ error: "Invalid clue ID" }, { status: 400 }); } // Check if clue exists const clue = await queryOne("SELECT id FROM clues WHERE id = ?", [clueId]); if (!clue) { return Response.json({ error: "Clue not found" }, { status: 404 }); } // Delete clue record await run("DELETE FROM clues WHERE id = ?", [clueId]); // Also delete any references in team_clues table await run(` CREATE TABLE IF NOT EXISTS team_clues ( team_id INTEGER NOT NULL, clue_id INTEGER NOT NULL, found_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (team_id, clue_id), FOREIGN KEY (team_id) REFERENCES teams(id), FOREIGN KEY (clue_id) REFERENCES clues(id) ) `); await run("DELETE FROM team_clues WHERE clue_id = ?", [clueId]); return Response.json({ success: true, message: "Clue deleted successfully", }); } catch (error) { console.error("Admin clue deletion error:", error); return Response.json( { error: "Failed to delete clue: " + error.message }, { status: 500 } ); } } // GET - Get a specific clue export async function GET(request, context) { try { // Verify admin access const { authorized, error, status } = await verifyAdmin(request); if (!authorized) { return Response.json({ error }, { status }); } const { clueId } = context.params; // Validate clueId is a number if (isNaN(parseInt(clueId))) { return Response.json({ error: "Invalid clue ID" }, { status: 400 }); } // Get the specific clue - removed coordinates const clue = await queryOne( "SELECT id, title, description, location FROM clues WHERE id = ?", [clueId] ); if (!clue) { return Response.json({ error: "Clue not found" }, { status: 404 }); } return Response.json(clue); } catch (error) { console.error("Admin clue fetch error:", error); return Response.json( { error: "Failed to fetch clue: " + error.message }, { status: 500 } ); } } // PUT - Update a specific clue export async function PUT(request, context) { try { // Verify admin access const { authorized, error, status } = await verifyAdmin(request); if (!authorized) { return Response.json({ error }, { status }); } const { clueId } = context.params; // Validate clueId is a number if (isNaN(parseInt(clueId))) { return Response.json({ error: "Invalid clue ID" }, { status: 400 }); } // Parse the request body - removed coordinates const { title, description, location } = await request.json(); // Validate required fields if (!title || !description) { return Response.json( { error: "Title and description are required" }, { status: 400 } ); } // Check if clue exists const clue = await queryOne("SELECT id FROM clues WHERE id = ?", [clueId]); if (!clue) { return Response.json({ error: "Clue not found" }, { status: 404 }); } // Update the clue - removed coordinates await run( ` UPDATE clues SET title = ?, description = ?, location = ? WHERE id = ? `, [title, description, location || "", clueId] ); return Response.json({ success: true, message: "Clue updated successfully", }); } catch (error) { console.error("Admin clue update error:", error); return Response.json( { error: "Failed to update clue: " + error.message }, { status: 500 } ); } }