tangled
alpha
login
or
join now
dunkirk.sh
/
smokie
1
fork
atom
a fun bot for the hc slack
1
fork
atom
overview
issues
pulls
pipelines
feat: add userName to projects too
dunkirk.sh
10 months ago
bc6daa01
9631f6b2
verified
This commit was signed with the committer's
known signature
.
dunkirk.sh
SSH Key Fingerprint:
SHA256:DqcG0RXYExE26KiWo3VxJnsxswN1QNfTBvB+bdSpk80=
+72
-1
1 changed file
expand all
collapse all
unified
split
src
features
api
routes
projects.ts
+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";
0
5
6
export type Project = {
7
projectName: string;
···
10
/** Total time spent on takes, in seconds */
11
totalTakesTime: number;
12
userId: string;
0
13
};
14
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
15
export async function projects(url: URL): Promise<Response> {
16
const user = url.searchParams.get("user");
17
try {
···
39
);
40
}
41
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
42
return new Response(
43
JSON.stringify({
44
-
projects: user ? projects[0] : projects,
0
0
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: {