Skip to content

feat: add issue tracker metrics widget — open/closed issues trend #180#279

Open
zishanq7861 wants to merge 12 commits into
Priyanshu-byte-coder:mainfrom
zishanq7861:feat-issue-metrics
Open

feat: add issue tracker metrics widget — open/closed issues trend #180#279
zishanq7861 wants to merge 12 commits into
Priyanshu-byte-coder:mainfrom
zishanq7861:feat-issue-metrics

Conversation

@zishanq7861
Copy link
Copy Markdown

Closes #180

Implemented the Issue Tracker Metrics widget matching all acceptance criteria:

  • Added Next.js route handler to aggregate issue metrics using the involves filter constraint.
  • Built a custom IssueMetrics component rendering total open, weekly open/closed stats, and average resolution velocity.
  • Integrated a historical 12-week Recharts trend line graph respecting light/dark CSS vars.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 17, 2026

@zishanq7861 is attempting to deploy a commit to the PRIYANSHU DOSHI's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your first PR on DevTrack! 🎉

A maintainer will review it within 48 hours. While you wait:

  • Make sure CI is passing (type-check + lint)
  • Double-check the PR description is filled out and the issue is linked
  • Feel free to ask questions in Discussions if you need help

@Priyanshu-byte-coder
Copy link
Copy Markdown
Owner

The trend chart and weekly breakdown are good ideas, but a few correctness issues:

1. Wrong session field for username:

// Replace:
const username = searchParams.get("username") || session.user?.name || "";
// With:
const username = searchParams.get("username") || session.githubLogin || "";

session.user?.name is the display name, not the GitHub login — will produce wrong API results.

2. Authorization header format:

// Replace:
headers: { Authorization: `token ${session.accessToken}` }
// With:
headers: { Authorization: `Bearer ${session.accessToken}` }

3. involves: query is too broad — it matches issues where the user is mentioned, assigned, subscribed, or commented. Use author:${githubLogin} to match only issues the user opened.

4. issue: any in forEach — add a proper type or at least as { state: string; created_at: string; closed_at: string | null }.

Fix these and push.

Copy link
Copy Markdown
Owner

@Priyanshu-byte-coder Priyanshu-byte-coder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes Required

1. [SECURITY] username query param allows fetching any user's data

const username = searchParams.get("username") || session.githubLogin || "";

Any authenticated user can call /api/metrics/issues?username=other-user and get that user's issue stats. Remove the username param entirely — use only session.githubLogin:

const username = session.githubLogin;
if (!username) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

2. revalidate=300 conflicts with force-dynamic
export const dynamic = "force-dynamic" disables all caching. export const revalidate = 300 is silently ignored. Remove the revalidate line — it creates confusion.

3. Missing EOF newlines
Both route.ts and IssueMetrics.tsx end with } and no trailing newline. Add one to each.

4. Hardcoded Tailwind colors in IssueMetrics.tsx

text-blue-500    text-[var(--accent)]
text-green-500   text-[var(--success)]
text-red-500     text-[var(--destructive)]
text-amber-500   no direct CSS var; use text-[var(--accent)] or add --warning to globals.css

5. useState<any> and catch (error: any)

const [data, setData] = useState<any>(null);         // → typed interface
catch (error: any) { setError(error.message); }       // → error instanceof Error ? error.message : "Failed"

Define an explicit interface for the API response shape to enable type safety throughout the component.

@Priyanshu-byte-coder Priyanshu-byte-coder added level:intermediate GSSoC: Intermediate difficulty (35 pts) gssoc26 GSSoC 2026 contribution type:feature GSSoC type bonus: new feature type:security GSSoC type bonus: security (+20 pts) labels May 20, 2026
Copy link
Copy Markdown
Owner

@Priyanshu-byte-coder Priyanshu-byte-coder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issues found in this PR:

  • Missing EOF newline — add a trailing newline to all modified files.

  • Raw Tailwind color classes — replace text-red-* / bg-red-* with text-[var(--destructive)] / appropriate CSS var equivalents. All colors must use CSS variables for theme support.

  • Raw green color classes — replace text-green-* / bg-green-* with text-[var(--success)] or appropriate CSS var.

@Priyanshu-byte-coder Priyanshu-byte-coder added the gssoc:approved GSSoC: PR approved for scoring label May 24, 2026
@Priyanshu-byte-coder
Copy link
Copy Markdown
Owner

This PR has merge conflicts with main. Please rebase on the latest main branch and re-request review. The approach is approved — just needs conflict resolution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gssoc:approved GSSoC: PR approved for scoring gssoc26 GSSoC 2026 contribution level:intermediate GSSoC: Intermediate difficulty (35 pts) type:feature GSSoC type bonus: new feature type:security GSSoC type bonus: security (+20 pts)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] Add issue tracker metrics widget — open/closed issues trend

2 participants