a fun bot for the hc slack

feat: add userName to projects too

dunkirk.sh bc6daa01 9631f6b2

verified
+72 -1
+72 -1
src/features/api/routes/projects.ts
··· 2 import { users as usersTable } from "../../../libs/schema"; 3 import { handleApiError } from "../../../libs/apiError"; 4 import { eq } from "drizzle-orm"; 5 6 export type Project = { 7 projectName: string; ··· 10 /** Total time spent on takes, in seconds */ 11 totalTakesTime: number; 12 userId: string; 13 }; 14 15 export async function projects(url: URL): Promise<Response> { 16 const user = url.searchParams.get("user"); 17 try { ··· 39 ); 40 } 41 42 return new Response( 43 JSON.stringify({ 44 - projects: user ? projects[0] : projects, 45 }), 46 { 47 headers: {
··· 2 import { users as usersTable } from "../../../libs/schema"; 3 import { handleApiError } from "../../../libs/apiError"; 4 import { eq } from "drizzle-orm"; 5 + import { fetchUserData } from "../../../libs/cachet"; 6 7 export type Project = { 8 projectName: string; ··· 11 /** Total time spent on takes, in seconds */ 12 totalTakesTime: number; 13 userId: string; 14 + userName?: string; 15 }; 16 17 + // Cache for user data from cachet 18 + const userCache: Record<string, { name: string; timestamp: number }> = {}; 19 + const pendingRequests: Record<string, Promise<string>> = {}; 20 + const CACHE_TTL = 5 * 60 * 1000; // 5 minutes 21 + 22 + // Function to get user name from cache or fetch it 23 + async function getUserName(userId: string): Promise<string> { 24 + const now = Date.now(); 25 + 26 + // Check if user data is in cache and still valid 27 + if (userCache[userId] && now - userCache[userId].timestamp < CACHE_TTL) { 28 + return userCache[userId].name; 29 + } 30 + 31 + // If there's already a pending request for this user, return that promise 32 + // instead of creating a new request 33 + if (pendingRequests[userId]) { 34 + return pendingRequests[userId]; 35 + } 36 + 37 + // Create a new promise for this user and store it 38 + const fetchPromise = (async () => { 39 + try { 40 + const userData = await fetchUserData(userId); 41 + const userName = userData?.displayName || "Unknown User"; 42 + 43 + userCache[userId] = { 44 + name: userName, 45 + timestamp: now, 46 + }; 47 + 48 + return userName; 49 + } catch (error) { 50 + console.error("Error fetching user data:", error); 51 + return "Unknown User"; 52 + } finally { 53 + // Clean up the pending request when done 54 + delete pendingRequests[userId]; 55 + } 56 + })(); 57 + 58 + // Store the promise 59 + pendingRequests[userId] = fetchPromise; 60 + 61 + // Return the promise 62 + return fetchPromise; 63 + } 64 + 65 export async function projects(url: URL): Promise<Response> { 66 const user = url.searchParams.get("user"); 67 try { ··· 89 ); 90 } 91 92 + // Get unique user IDs 93 + const userIds = [...new Set(projects.map((project) => project.userId))]; 94 + 95 + // Fetch all user names from cache or API 96 + const userNamesPromises = userIds.map((id) => getUserName(id)); 97 + const userNames = await Promise.all(userNamesPromises); 98 + 99 + // Create a map of user names 100 + const userNameMap: Record<string, string> = {}; 101 + userIds.forEach((id, index) => { 102 + userNameMap[id] = userNames[index] || "Unknown User"; 103 + }); 104 + 105 + // Add user names to projects 106 + const projectsWithUserNames = projects.map((project) => ({ 107 + ...project, 108 + userName: userNameMap[project.userId] || "Unknown User", 109 + })); 110 + 111 return new Response( 112 JSON.stringify({ 113 + projects: user 114 + ? projectsWithUserNames[0] 115 + : projectsWithUserNames, 116 }), 117 { 118 headers: {