This repository has no description
0

Configure Feed

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

feat: add userName as a field in recentTakes

+62
+62
src/features/api/routes/recentTakes.ts
··· 2 2 import { db } from "../../../libs/db"; 3 3 import { takes as takesTable, users as usersTable } from "../../../libs/schema"; 4 4 import { handleApiError } from "../../../libs/apiError"; 5 + import { fetchUserData } from "../../../libs/cachet"; 5 6 6 7 export type RecentTake = { 7 8 id: string; ··· 14 15 project: string; 15 16 /* total time in seconds */ 16 17 totalTakesTime: number; 18 + userName?: string; // Add userName field 17 19 }; 18 20 21 + // Cache for user data from cachet 22 + const userCache: Record<string, { name: string; timestamp: number }> = {}; 23 + const CACHE_TTL = 5 * 60 * 1000; // 5 minutes 24 + // Track pending requests to avoid duplicate API calls 25 + const pendingRequests: Record<string, Promise<string>> = {}; 26 + 27 + // Function to get user name from cache or fetch it 28 + async function getUserName(userId: string): Promise<string> { 29 + const now = Date.now(); 30 + 31 + // Check if user data is in cache and still valid 32 + if (userCache[userId] && now - userCache[userId].timestamp < CACHE_TTL) { 33 + return userCache[userId].name; 34 + } 35 + 36 + // If there's already a pending request for this user, return that promise 37 + // instead of creating a new request 38 + if (pendingRequests[userId]) { 39 + return pendingRequests[userId]; 40 + } 41 + 42 + // Create a new promise for this user and store it 43 + const fetchPromise = (async () => { 44 + try { 45 + const userData = await fetchUserData(userId); 46 + const userName = userData?.displayName || "Unknown User"; 47 + 48 + userCache[userId] = { 49 + name: userName, 50 + timestamp: now, 51 + }; 52 + 53 + return userName; 54 + } catch (error) { 55 + console.error("Error fetching user data:", error); 56 + return "Unknown User"; 57 + } finally { 58 + // Clean up the pending request when done 59 + delete pendingRequests[userId]; 60 + } 61 + })(); 62 + 63 + // Store the promise 64 + pendingRequests[userId] = fetchPromise; 65 + 66 + // Return the promise 67 + return fetchPromise; 68 + } 69 + 19 70 export async function recentTakes(url: URL): Promise<Response> { 20 71 try { 21 72 const userId = url.searchParams.get("user"); ··· 82 133 {} as Record<string, (typeof users)[number]>, 83 134 ); 84 135 136 + // Fetch all user names from cache or API 137 + const userNamesPromises = userIds.map((id) => getUserName(id)); 138 + const userNames = await Promise.all(userNamesPromises); 139 + 140 + // Create a map of user names 141 + const userNameMap: Record<string, string> = {}; 142 + userIds.forEach((id, index) => { 143 + userNameMap[id] = userNames[index] || "unknown"; 144 + }); 145 + 85 146 const takes: RecentTake[] = 86 147 recentTakes.map((take) => ({ 87 148 id: take.id, ··· 93 154 project: userMap[take.userId]?.projectName || "unknown project", 94 155 totalTakesTime: 95 156 userMap[take.userId]?.totalTakesTime || take.elapsedTime, 157 + userName: userNameMap[take.userId] || "Unknown User", 96 158 })) || []; 97 159 98 160 return new Response(