stats.get.ts
1 import { PrismaClient } from "@prisma/client"; 2 import { H3Event } from "h3"; 3 import { TimeRangeEnum } from "~~/lib/stats"; 4 import type { TimeRange } from "~~/lib/stats"; 5 import { z } from "zod"; 6 import { calculateStats } from "~~/server/utils/stats"; 7 import { handleApiError} from "~~/server/utils/logging"; 8 9 const prisma = new PrismaClient(); 10 11 const apiKeySchema = z.string().uuid(); 12 13 export default defineEventHandler(async (event: H3Event) => { 14 try { 15 const authHeader = getHeader(event, "authorization"); 16 if (!authHeader || !authHeader.startsWith("Bearer ")) { 17 throw handleApiError(401, "External Stats API: Missing or invalid API key format in header.", "API key is missing or improperly formatted."); 18 } 19 20 const apiKey = authHeader.substring(7); 21 const validationResult = apiKeySchema.safeParse(apiKey); 22 23 if (!validationResult.success) { 24 throw handleApiError(401, `External Stats API: Invalid API key format. Key prefix: ${apiKey.substring(0,4)}...`, "Invalid API key format."); 25 } 26 27 const user = await prisma.user.findUnique({ 28 where: { apiKey }, 29 select: { id: true, apiKey: true }, 30 }); 31 32 if (!user || user.apiKey !== apiKey) { 33 throw handleApiError(401, `External Stats API: Invalid API key. Key prefix: ${apiKey.substring(0,4)}...`, "Invalid API key."); 34 } 35 36 const query = getQuery(event); 37 const timeRange = String(query.timeRange || "today"); 38 const midnightOffsetSeconds = query.midnightOffsetSeconds ? Number(query.midnightOffsetSeconds) : undefined; 39 40 if (!Object.values(TimeRangeEnum).includes(timeRange as any)) { 41 throw handleApiError(400, `External Stats API: Invalid timeRange value: ${timeRange}. User ID: ${user.id}`, "Invalid time range specified."); 42 } 43 44 return await calculateStats(user.id, timeRange as TimeRange, midnightOffsetSeconds); 45 } catch (error: any) { 46 if (error && typeof error === "object" && error.statusCode) throw error; 47 const detailedMessage = error instanceof Error ? error.message : "An unknown error occurred fetching external stats."; 48 const apiKeyPrefix = getHeader(event, "authorization")?.substring(7,11) || "UNKNOWN"; 49 throw handleApiError(500, `External Stats API: Failed to fetch statistics. API Key prefix: ${apiKeyPrefix}... Error: ${detailedMessage}`, "Failed to fetch statistics."); 50 } 51 });