import { NextResponse } from "next/server"; import { gte, and, isNotNull, sql } from "drizzle-orm"; import { db } from "@/lib/db"; import { claws } from "@/lib/db/schema"; import { getCacheHeatmap, setCacheHeatmap } from "@/lib/redis"; export async function GET() { try { const cached = await getCacheHeatmap(); if (cached) { return NextResponse.json(JSON.parse(cached)); } const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000); const activeClaws = await db .select({ city: claws.city, country: claws.country, latitude: claws.latitude, longitude: claws.longitude, count: sql`count(*)`, }) .from(claws) .where( and( gte(claws.lastHeartbeat, fiveMinutesAgo), isNotNull(claws.latitude), isNotNull(claws.longitude) ) ) .groupBy( claws.city, claws.country, claws.latitude, claws.longitude ); const points = activeClaws.map((row) => ({ lat: Number(row.latitude), lng: Number(row.longitude), weight: row.count, clawCount: row.count, city: row.city, country: row.country, })); const lastUpdated = new Date().toISOString(); const responseData = { points, lastUpdated }; await setCacheHeatmap(JSON.stringify(responseData)); return NextResponse.json(responseData); } catch (error) { console.error("Heatmap error:", error); return NextResponse.json( { error: "Internal server error" }, { status: 500 } ); } }