a fun bot for the hc slack
at v0.2.0 2.5 kB view raw
1import { eq, desc, or } from "drizzle-orm"; 2import { db } from "../../../libs/db"; 3import { takes as takesTable, users as usersTable } from "../../../libs/schema"; 4import { handleApiError } from "../../../libs/apiError"; 5 6export type RecentTake = { 7 id: string; 8 userId: string; 9 notes: string; 10 createdAt: Date; 11 mediaUrls: string[]; 12 /* elapsed time in seconds */ 13 elapsedTime: number; 14 project: string; 15 /* total time in seconds */ 16 totalTakesTime: number; 17}; 18 19export async function recentTakes(url: URL): Promise<Response> { 20 try { 21 const userId = url.searchParams.get("user"); 22 23 if (userId) { 24 // Verify user exists if userId provided 25 const user = await db 26 .select() 27 .from(usersTable) 28 .where(eq(usersTable.id, userId)) 29 .limit(1); 30 31 if (user.length === 0) { 32 return new Response( 33 JSON.stringify({ 34 error: "User not found", 35 takes: [], 36 }), 37 { 38 status: 404, 39 headers: { 40 "Content-Type": "application/json", 41 }, 42 }, 43 ); 44 } 45 } 46 47 const recentTakes = await db 48 .select() 49 .from(takesTable) 50 .orderBy(desc(takesTable.createdAt)) 51 .where(eq(takesTable.userId, userId ? userId : takesTable.userId)) 52 .limit(40); 53 54 if (recentTakes.length === 0) { 55 return new Response( 56 JSON.stringify({ 57 takes: [], 58 }), 59 { 60 headers: { 61 "Content-Type": "application/json", 62 }, 63 }, 64 ); 65 } 66 67 // Get unique user IDs 68 const userIds = [...new Set(recentTakes.map((take) => take.userId))]; 69 70 // Query users from takes table 71 const users = await db 72 .select() 73 .from(usersTable) 74 .where(or(...userIds.map((id) => eq(usersTable.id, id)))); 75 76 // Create map of user data by ID 77 const userMap = users.reduce( 78 (acc, user) => { 79 acc[user.id] = user; 80 return acc; 81 }, 82 {} as Record<string, (typeof users)[number]>, 83 ); 84 85 const takes: RecentTake[] = 86 recentTakes.map((take) => ({ 87 id: take.id, 88 userId: take.userId, 89 notes: take.notes, 90 createdAt: new Date(take.createdAt), 91 mediaUrls: take.media ? JSON.parse(take.media) : [], 92 elapsedTime: take.elapsedTime, 93 project: userMap[take.userId]?.projectName || "unknown project", 94 totalTakesTime: 95 userMap[take.userId]?.totalTakesTime || take.elapsedTime, 96 })) || []; 97 98 return new Response( 99 JSON.stringify({ 100 takes, 101 }), 102 { 103 headers: { 104 "Content-Type": "application/json", 105 }, 106 }, 107 ); 108 } catch (error) { 109 return handleApiError(error, "recentTakes"); 110 } 111}