import { NextRequest, NextResponse } from "next/server"; import { sql } from "drizzle-orm"; import { db } from "@/lib/db"; import { invalidateTokenLeaderboardCache } from "@/lib/redis"; import { authenticateRequest, getTodayDateString } from "@/lib/utils"; import { tokenSchema } from "@/lib/validators/schemas"; export async function POST(req: NextRequest) { try { const auth = await authenticateRequest(req); if (auth instanceof NextResponse) { return auth; } const { claw } = auth; const body = await req.json(); const parsed = tokenSchema.safeParse(body); if (!parsed.success) { return NextResponse.json( { error: "Validation failed", details: parsed.error.flatten() }, { status: 400 } ); } const { inputTokens, outputTokens, date } = parsed.data; const targetDate = date || getTodayDateString(); // Use UPSERT (INSERT ... ON DUPLICATE KEY UPDATE) for atomic operation await db.execute(sql` INSERT INTO token_usage (claw_id, date, input_tokens, output_tokens) VALUES (${claw.id}, ${targetDate}, ${inputTokens}, ${outputTokens}) ON DUPLICATE KEY UPDATE input_tokens = ${inputTokens}, output_tokens = ${outputTokens}, updated_at = NOW() `); // Invalidate leaderboard cache await invalidateTokenLeaderboardCache(); return NextResponse.json({ ok: true, date: targetDate, inputTokens, outputTokens, totalTokens: inputTokens + outputTokens, }); } catch (error) { console.error("Token report error:", error); return NextResponse.json( { error: "Internal server error" }, { status: 500 } ); } }