Spaces:
Sleeping
Sleeping
Commit ·
21a3ed1
1
Parent(s): 56515b1
apply new changes
Browse files
src/app/api/contributor/dashboard-summary/route.ts
CHANGED
|
@@ -19,21 +19,46 @@ export async function GET(request: NextRequest) {
|
|
| 19 |
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
| 20 |
}
|
| 21 |
|
|
|
|
|
|
|
| 22 |
// Fetch GitHub contributions in parallel with local data
|
|
|
|
| 23 |
const [allItems, trackedRepos, userRecord, githubData] = await Promise.all([
|
| 24 |
// Get all issues/PRs by this contributor from the database
|
| 25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
// Get tracked repos
|
| 27 |
-
|
| 28 |
-
.
|
| 29 |
-
.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
// Get user's GitHub token
|
| 31 |
-
|
| 32 |
-
.
|
| 33 |
-
.
|
| 34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
// Fetch GitHub contributions (will use cache or make API call)
|
| 36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
]);
|
| 38 |
|
| 39 |
// Calculate metrics from database records
|
|
@@ -73,9 +98,12 @@ export async function GET(request: NextRequest) {
|
|
| 73 |
|
| 74 |
} catch (error: any) {
|
| 75 |
console.error("Contributor dashboard-summary error:", error);
|
|
|
|
|
|
|
| 76 |
|
| 77 |
return NextResponse.json({
|
| 78 |
-
error: "Failed to fetch dashboard data. Please try again."
|
|
|
|
| 79 |
}, { status: 500 });
|
| 80 |
}
|
| 81 |
}
|
|
|
|
| 19 |
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
| 20 |
}
|
| 21 |
|
| 22 |
+
console.log("[Dashboard Summary] User:", user.username);
|
| 23 |
+
|
| 24 |
// Fetch GitHub contributions in parallel with local data
|
| 25 |
+
console.log("[Dashboard Summary] Starting parallel queries...");
|
| 26 |
const [allItems, trackedRepos, userRecord, githubData] = await Promise.all([
|
| 27 |
// Get all issues/PRs by this contributor from the database
|
| 28 |
+
(async () => {
|
| 29 |
+
console.log("[Dashboard Summary] Fetching issues...");
|
| 30 |
+
const items = await db.select().from(issues).where(eq(issues.authorName, user.username));
|
| 31 |
+
console.log("[Dashboard Summary] Found %d issues", items.length);
|
| 32 |
+
return items;
|
| 33 |
+
})(),
|
| 34 |
// Get tracked repos
|
| 35 |
+
(async () => {
|
| 36 |
+
console.log("[Dashboard Summary] Fetching tracked repos...");
|
| 37 |
+
const repos = await db.select({ repoFullName: userRepositories.repoFullName })
|
| 38 |
+
.from(userRepositories)
|
| 39 |
+
.where(eq(userRepositories.userId, user.id));
|
| 40 |
+
console.log("[Dashboard Summary] Found %d tracked repos", repos.length);
|
| 41 |
+
return repos;
|
| 42 |
+
})(),
|
| 43 |
// Get user's GitHub token
|
| 44 |
+
(async () => {
|
| 45 |
+
console.log("[Dashboard Summary] Fetching user token...");
|
| 46 |
+
const userData = await db.select({ githubAccessToken: users.githubAccessToken })
|
| 47 |
+
.from(users)
|
| 48 |
+
.where(eq(users.id, user.id))
|
| 49 |
+
.limit(1);
|
| 50 |
+
console.log("[Dashboard Summary] User token fetch complete");
|
| 51 |
+
return userData;
|
| 52 |
+
})(),
|
| 53 |
// Fetch GitHub contributions (will use cache or make API call)
|
| 54 |
+
(async () => {
|
| 55 |
+
console.log("[Dashboard Summary] Fetching GitHub contributions...");
|
| 56 |
+
const ghData = await fetchGitHubContributions(user.username, null).catch(err => {
|
| 57 |
+
console.log("[Dashboard Summary] GitHub fetch failed:", err);
|
| 58 |
+
return null;
|
| 59 |
+
});
|
| 60 |
+
return ghData;
|
| 61 |
+
})()
|
| 62 |
]);
|
| 63 |
|
| 64 |
// Calculate metrics from database records
|
|
|
|
| 98 |
|
| 99 |
} catch (error: any) {
|
| 100 |
console.error("Contributor dashboard-summary error:", error);
|
| 101 |
+
console.error("Error stack:", error?.stack);
|
| 102 |
+
console.error("Error message:", error?.message);
|
| 103 |
|
| 104 |
return NextResponse.json({
|
| 105 |
+
error: "Failed to fetch dashboard data. Please try again.",
|
| 106 |
+
details: error?.message || "Unknown error"
|
| 107 |
}, { status: 500 });
|
| 108 |
}
|
| 109 |
}
|
src/app/api/contributor/my-issues/route.ts
CHANGED
|
@@ -17,12 +17,16 @@ export async function GET(request: NextRequest) {
|
|
| 17 |
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
| 18 |
}
|
| 19 |
|
|
|
|
|
|
|
| 20 |
const { searchParams } = new URL(request.url);
|
| 21 |
const page = parseInt(searchParams.get("page") || "1");
|
| 22 |
const limit = parseInt(searchParams.get("limit") || "10");
|
| 23 |
const isPRParam = searchParams.get("isPR");
|
| 24 |
const repoParam = searchParams.get("repo");
|
| 25 |
|
|
|
|
|
|
|
| 26 |
// Build filters
|
| 27 |
const filters: { authorName: string; isPR?: boolean; repoName?: string } = {
|
| 28 |
authorName: user.username
|
|
@@ -41,10 +45,14 @@ export async function GET(request: NextRequest) {
|
|
| 41 |
}
|
| 42 |
|
| 43 |
// Get issues from database with filters
|
|
|
|
| 44 |
const issuesData = await getIssuesWithTriage(filters, page, limit);
|
| 45 |
|
|
|
|
|
|
|
| 46 |
// If database has results, return them
|
| 47 |
if (issuesData.total > 0) {
|
|
|
|
| 48 |
return NextResponse.json({
|
| 49 |
items: issuesData.issues,
|
| 50 |
total: issuesData.total,
|
|
@@ -151,8 +159,13 @@ export async function GET(request: NextRequest) {
|
|
| 151 |
pages: 0,
|
| 152 |
limit,
|
| 153 |
});
|
| 154 |
-
} catch (error) {
|
| 155 |
-
console.error("
|
| 156 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
}
|
| 158 |
}
|
|
|
|
| 17 |
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
| 18 |
}
|
| 19 |
|
| 20 |
+
console.log("[My Issues] User:", user.username);
|
| 21 |
+
|
| 22 |
const { searchParams } = new URL(request.url);
|
| 23 |
const page = parseInt(searchParams.get("page") || "1");
|
| 24 |
const limit = parseInt(searchParams.get("limit") || "10");
|
| 25 |
const isPRParam = searchParams.get("isPR");
|
| 26 |
const repoParam = searchParams.get("repo");
|
| 27 |
|
| 28 |
+
console.log("[My Issues] Query params - page:", page, "limit:", limit);
|
| 29 |
+
|
| 30 |
// Build filters
|
| 31 |
const filters: { authorName: string; isPR?: boolean; repoName?: string } = {
|
| 32 |
authorName: user.username
|
|
|
|
| 45 |
}
|
| 46 |
|
| 47 |
// Get issues from database with filters
|
| 48 |
+
console.log("[My Issues] Calling getIssuesWithTriage...");
|
| 49 |
const issuesData = await getIssuesWithTriage(filters, page, limit);
|
| 50 |
|
| 51 |
+
console.log("[My Issues] Got %d issues from database", issuesData.issues.length);
|
| 52 |
+
|
| 53 |
// If database has results, return them
|
| 54 |
if (issuesData.total > 0) {
|
| 55 |
+
console.log("[My Issues] Returning %d results from database", issuesData.issues.length);
|
| 56 |
return NextResponse.json({
|
| 57 |
items: issuesData.issues,
|
| 58 |
total: issuesData.total,
|
|
|
|
| 159 |
pages: 0,
|
| 160 |
limit,
|
| 161 |
});
|
| 162 |
+
} catch (error: any) {
|
| 163 |
+
console.error("[My Issues] Error:", error);
|
| 164 |
+
console.error("[My Issues] Error stack:", error?.stack);
|
| 165 |
+
console.error("[My Issues] Error message:", error?.message);
|
| 166 |
+
return NextResponse.json({
|
| 167 |
+
error: "Internal server error",
|
| 168 |
+
details: error?.message || "Unknown error"
|
| 169 |
+
}, { status: 500 });
|
| 170 |
}
|
| 171 |
}
|
src/lib/db/queries/issues.ts
CHANGED
|
@@ -202,6 +202,8 @@ export async function getIssuesWithTriage(filters: IssueFilters, page = 1, limit
|
|
| 202 |
const offset = Math.max(0, (page - 1) * limit);
|
| 203 |
const safePage = Math.max(1, page);
|
| 204 |
|
|
|
|
|
|
|
| 205 |
// Build conditions (identical to getIssues)
|
| 206 |
const conditions = [];
|
| 207 |
if (filters.repoId) conditions.push(eq(issues.repoId, filters.repoId));
|
|
@@ -234,6 +236,8 @@ export async function getIssuesWithTriage(filters: IssueFilters, page = 1, limit
|
|
| 234 |
|
| 235 |
const whereClause = conditions.length > 0 ? and(...conditions) : undefined;
|
| 236 |
|
|
|
|
|
|
|
| 237 |
// Get total count
|
| 238 |
const countResult = await db.select({ count: count() })
|
| 239 |
.from(issues)
|
|
@@ -241,8 +245,11 @@ export async function getIssuesWithTriage(filters: IssueFilters, page = 1, limit
|
|
| 241 |
const total = countResult[0]?.count || 0;
|
| 242 |
const totalPages = Math.ceil(total / limit);
|
| 243 |
|
|
|
|
|
|
|
| 244 |
// ✅ Single JOIN query: issues LEFT JOIN triageData
|
| 245 |
// Database executes this in one round-trip, no N+1
|
|
|
|
| 246 |
const results = await db.select({
|
| 247 |
issue: issues,
|
| 248 |
triage: triageData,
|
|
@@ -254,6 +261,8 @@ export async function getIssuesWithTriage(filters: IssueFilters, page = 1, limit
|
|
| 254 |
.limit(limit)
|
| 255 |
.offset(offset);
|
| 256 |
|
|
|
|
|
|
|
| 257 |
// Transform [ {issue, triage}, {issue, triage}, ... ] into [ {issue, triage}, ... ]
|
| 258 |
const issuesWithTriage = results.map(row => ({
|
| 259 |
...row.issue,
|
|
|
|
| 202 |
const offset = Math.max(0, (page - 1) * limit);
|
| 203 |
const safePage = Math.max(1, page);
|
| 204 |
|
| 205 |
+
console.log("[getIssuesWithTriage] Starting query with filters:", filters, "page:", page, "limit:", limit);
|
| 206 |
+
|
| 207 |
// Build conditions (identical to getIssues)
|
| 208 |
const conditions = [];
|
| 209 |
if (filters.repoId) conditions.push(eq(issues.repoId, filters.repoId));
|
|
|
|
| 236 |
|
| 237 |
const whereClause = conditions.length > 0 ? and(...conditions) : undefined;
|
| 238 |
|
| 239 |
+
console.log("[getIssuesWithTriage] Built where clause, fetching count...");
|
| 240 |
+
|
| 241 |
// Get total count
|
| 242 |
const countResult = await db.select({ count: count() })
|
| 243 |
.from(issues)
|
|
|
|
| 245 |
const total = countResult[0]?.count || 0;
|
| 246 |
const totalPages = Math.ceil(total / limit);
|
| 247 |
|
| 248 |
+
console.log("[getIssuesWithTriage] Total count:", total, "totalPages:", totalPages);
|
| 249 |
+
|
| 250 |
// ✅ Single JOIN query: issues LEFT JOIN triageData
|
| 251 |
// Database executes this in one round-trip, no N+1
|
| 252 |
+
console.log("[getIssuesWithTriage] Executing JOIN query...");
|
| 253 |
const results = await db.select({
|
| 254 |
issue: issues,
|
| 255 |
triage: triageData,
|
|
|
|
| 261 |
.limit(limit)
|
| 262 |
.offset(offset);
|
| 263 |
|
| 264 |
+
console.log("[getIssuesWithTriage] Query returned %d results", results.length);
|
| 265 |
+
|
| 266 |
// Transform [ {issue, triage}, {issue, triage}, ... ] into [ {issue, triage}, ... ]
|
| 267 |
const issuesWithTriage = results.map(row => ({
|
| 268 |
...row.issue,
|