import { query, queryOne, run } from "@/lib/db"; import { getToken } from "next-auth/jwt"; export const dynamic = "force-dynamic"; // Disable caching export async function GET(request) { try { const token = await getToken({ req: request, secret: process.env.NEXTAUTH_SECRET || "your-fallback-secret-should-be-at-least-32-chars", }); if (!token) { console.log("API: Unauthorized request to /api/clues - no token"); return Response.json({ error: "Unauthorized" }, { status: 401 }); } // Check if user has a team if (!token.teamId) { console.log("API: User without team tried to access clues"); return Response.json( { error: "You must be part of a team to view clues" }, { status: 403 } ); } // First, ensure the team_clues table has the 'skipped' column try { // Check if team_clues table exists, create it if it doesn't 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) ) `); // Check if skipped column exists const tableInfo = await query("PRAGMA table_info(team_clues)"); const hasSkippedColumn = tableInfo.some((col) => col.name === "skipped"); if (!hasSkippedColumn) { console.log("Adding 'skipped' column to team_clues table"); await run( "ALTER TABLE team_clues ADD COLUMN skipped BOOLEAN DEFAULT 0" ); } } catch (schemaError) { console.error("Error ensuring database schema:", schemaError); // Continue execution - if this fails, the main query might still work // with existing columns } // Get all clues with explicit ordering const clues = await query(` SELECT id, title, description, location FROM clues ORDER BY id ASC `); // For each clue, check if the team has found it const cluesWithStatus = await Promise.all( clues.map(async (clue) => { let clueStatus; try { clueStatus = await queryOne( "SELECT found_at, skipped FROM team_clues WHERE team_id = ? AND clue_id = ?", [token.teamId, clue.id] ); } catch (error) { console.error(`Error querying status for clue ${clue.id}:`, error); // Fallback if query fails (e.g., skipped column still doesn't exist) clueStatus = await queryOne( "SELECT found_at FROM team_clues WHERE team_id = ? AND clue_id = ?", [token.teamId, clue.id] ); } return { ...clue, found: !!clueStatus && !(clueStatus.skipped === 1), skipped: !!clueStatus && clueStatus.skipped === 1, available: false, // Will be determined after processing all clues }; }) ); // Determine which clues should be available let firstUnavailableFound = false; const finalClues = cluesWithStatus.map((clue, index, arr) => { if (clue.found || clue.skipped) { return { ...clue, available: true }; } // If we haven't found an unavailable clue yet, this one is available if (!firstUnavailableFound) { firstUnavailableFound = true; return { ...clue, available: true }; } return { ...clue, available: false }; }); console.log(`API: Returning ${finalClues.length} clues`); return Response.json(finalClues, { headers: { "Cache-Control": "no-store, no-cache, must-revalidate", Pragma: "no-cache", Expires: "0", }, }); } catch (error) { console.error("Error fetching clues:", error); return Response.json( { error: "Failed to fetch clues: " + error.message }, { status: 500 } ); } }