import { NextRequest, NextResponse } from "next/server"; import { eq, and, gte, sql } from "drizzle-orm"; import { db } from "@/lib/db"; import { tokenUsage } from "@/lib/db/schema"; import { authenticateRequest, getTodayDateString } from "@/lib/utils"; export async function GET(req: NextRequest) { try { const auth = await authenticateRequest(req); if (auth instanceof NextResponse) { return auth; } const { claw } = auth; const today = getTodayDateString(); // Get total usage using raw query for aggregation const totalResult = await db.execute(sql` SELECT COALESCE(SUM(input_tokens), 0) AS inputTokens, COALESCE(SUM(output_tokens), 0) AS outputTokens FROM token_usage WHERE claw_id = ${claw.id} `); const totalRow = totalResult[0] as unknown as { inputTokens: number; outputTokens: number } | undefined; const totalStats = totalRow ? { inputTokens: Number(totalRow.inputTokens || 0), outputTokens: Number(totalRow.outputTokens || 0), totalTokens: Number(totalRow.inputTokens || 0) + Number(totalRow.outputTokens || 0), } : { inputTokens: 0, outputTokens: 0, totalTokens: 0, }; // Get last 30 days history const thirtyDaysAgo = new Date(); thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30); const thirtyDaysAgoStr = thirtyDaysAgo.toISOString().split("T")[0]; const history = await db .select({ date: tokenUsage.date, inputTokens: tokenUsage.inputTokens, outputTokens: tokenUsage.outputTokens, }) .from(tokenUsage) .where( and( eq(tokenUsage.clawId, claw.id), gte(tokenUsage.date, thirtyDaysAgoStr) ) ); // Derive today's stats from history (avoids redundant query) const todayRecord = history.find((h) => h.date === today); const todayStats = todayRecord ? { inputTokens: todayRecord.inputTokens, outputTokens: todayRecord.outputTokens, totalTokens: todayRecord.inputTokens + todayRecord.outputTokens, } : { inputTokens: 0, outputTokens: 0, totalTokens: 0, }; return NextResponse.json({ clawId: claw.id, clawName: claw.name, today: todayStats, total: totalStats, history: history.map((h) => ({ date: h.date, inputTokens: h.inputTokens, outputTokens: h.outputTokens, totalTokens: h.inputTokens + h.outputTokens, })), }); } catch (error) { console.error("Token stats error:", error); return NextResponse.json( { error: "Internal server error" }, { status: 500 } ); } }