This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 2.4 kB View raw
1import { db } from "../../../libs/db"; 2import { users as usersTable, takes as takesTable } from "../../../libs/schema"; 3import { handleApiError } from "../../../libs/apiError"; 4import { eq, sql } from "drizzle-orm"; 5 6// Time data cache to reduce database queries 7const timeCache = new Map< 8 string, 9 { 10 data: { 11 userId: string; 12 totalTakesTime: number; 13 dailyStats: { date: string; seconds: number }[]; 14 }; 15 timestamp: number; 16 } 17>(); 18const TIME_CACHE_TTL = 5 * 60 * 1000; // 5 minutes cache TTL 19 20export async function time(url: URL): Promise<Response> { 21 try { 22 const userId = url.searchParams.get("user"); 23 24 if (!userId) { 25 return new Response( 26 JSON.stringify({ 27 error: "User ID is required", 28 }), 29 { 30 headers: { 31 "Content-Type": "application/json", 32 }, 33 status: 400, 34 }, 35 ); 36 } 37 38 // Check cache before database query 39 const cacheKey = `time_${userId}`; 40 const cached = timeCache.get(cacheKey); 41 if (cached && Date.now() - cached.timestamp < TIME_CACHE_TTL) { 42 return new Response(JSON.stringify(cached.data), { 43 headers: { 44 "Content-Type": "application/json", 45 }, 46 }); 47 } 48 49 // Get user's total takes time from the database 50 const userData = await db 51 .select({ 52 totalTakesTime: usersTable.totalTakesTime, 53 }) 54 .from(usersTable) 55 .where(eq(usersTable.id, userId)) 56 .limit(1); 57 58 if (!userData[0]) { 59 return new Response( 60 JSON.stringify({ 61 error: "User not found", 62 }), 63 { 64 headers: { 65 "Content-Type": "application/json", 66 }, 67 status: 404, 68 }, 69 ); 70 } 71 72 // Get time logged per day 73 const dailyStats = await db 74 .select({ 75 date: sql<string>`DATE(${takesTable.createdAt})`, 76 dailyTotal: sql<number>`SUM(${takesTable.elapsedTime})`, 77 }) 78 .from(takesTable) 79 .where(eq(takesTable.userId, userId)) 80 .groupBy(sql`DATE(${takesTable.createdAt})`) 81 .orderBy(sql`DATE(${takesTable.createdAt}) DESC`); 82 83 const responseData = { 84 userId, 85 totalTakesTime: userData[0].totalTakesTime || 0, 86 dailyStats: dailyStats.map((day) => ({ 87 date: day.date, 88 seconds: day.dailyTotal, 89 })), 90 }; 91 92 // Store in cache 93 timeCache.set(cacheKey, { 94 data: responseData, 95 timestamp: Date.now(), 96 }); 97 98 return new Response(JSON.stringify(responseData), { 99 headers: { 100 "Content-Type": "application/json", 101 }, 102 }); 103 } catch (error) { 104 return handleApiError(error, "userTime"); 105 } 106}