DEV Community

Cover image for How I Finished My AI Code Reviewer Using GitHub Copilot
Mohit Pandey
Mohit Pandey

Posted on

How I Finished My AI Code Reviewer Using GitHub Copilot

GitHub “Finish-Up-A-Thon” Challenge Submission

This is a submission for the GitHub Finish-Up-A-Thon Challenge


What I Built

In college, nobody really reviews your code. You submit assignments, get a grade, and move on. There's no one telling you "this function is doing too much" or "you're ignoring this edge case." I got tired of that, so I built Bugloo.

Bugloo is a free AI code reviewer for students. Paste any snippet, in any language, and you get back a breakdown of bugs, style issues, improvements, a quality score, and a plain-English explanation of what your code is actually doing. The whole thing runs on FastAPI, Supabase, and Groq's llama3-70b-8192, all free tier, no credit card.

Live demo: bugloo.vercel.app


Demo

Home Page — paste your code and the language is detected automatically
Home Page

Review Output — bugs, style issues, improvements, and a quality score in one shot
Features

Dashboard — every review you've run, saved to your account
Dashboard

API Docs — auto-generated by FastAPI, all endpoints documented out of the box
API Documentation

🔗 bugloo.vercel.app


The Comeback Story

Honest version of where this project started: it worked on my laptop, barely. The Groq integration was functional but the rest was a mess. No real auth flow, raw Supabase error objects printing directly to the UI, manual language selection that nobody would actually use, and .pyc files committed to Git like I had no shame.

I knew what I wanted to build. I just kept hitting friction and leaving it half-done.

Here's what I actually finished for this challenge:

  • Auth that makes sense. Replaced the old broken two-page login flow with a single page that toggles between login and signup without a reload. Also disabled Supabase's email confirmation so new users don't get stuck waiting for an email that might land in spam.
  • Auto language detection. Wired up highlight.js to detect the language as you type. A badge updates in real time. Nobody has to pick from a dropdown.
  • Proper error handling. Every API failure, Groq timeouts, Supabase errors, network issues, now maps to a readable message instead of a 500 page or a raw error object.
  • PDF export. Users can download any review as a PDF to save or share.
  • Actual security. JWT stored in HttpOnly cookies, Supabase RLS policies per user, and a get_current_user dependency on every protected route.
  • Clean project structure. Removed the compiled files, added .env.example, set up render.yaml for deployment.

Before this challenge it was a prototype I was embarrassed to share. Now it's something I'd actually put in front of a recruiter.


How It Works

User pastes code
      ↓
highlight.js detects language (client-side)
      ↓
POST /api/review → FastAPI
      ↓
Groq API (llama3-70b-8192) analyzes code
      ↓
Structured JSON response parsed
      ↓
Review saved to Supabase + displayed to user
Enter fullscreen mode Exit fullscreen mode

My Experience with GitHub Copilot

I used Copilot mostly for the stuff I kept putting off because it felt tedious.

The error mapper was the clearest example. I needed a function that takes raw Supabase and Groq error messages and returns something a human can read. I wrote two cases by hand, Copilot filled in the rest. I just checked it over and adjusted a few strings.

def map_auth_error(error_msg: str) -> str:
    msg_lower = error_msg.lower()
    if any(term in msg_lower for term in ["connection", "network", "timeout", "offline", "cannot connect", "failed to connect", "unreachable"]):
        return "Authentication service is unavailable. Please try again shortly."
    if "invalid login credentials" in msg_lower or "invalid_credentials" in msg_lower:
        return "Incorrect email or password. Please try again."
    if "already registered" in msg_lower or "user_already_exists" in msg_lower:
        return "An account with this email already exists. Try logging in."
    if "weak_password" in msg_lower or "password should be at least" in msg_lower:
        return "Password must be at least 8 characters."
    if "invalid_email" in msg_lower or "valid email" in msg_lower:
        return "Please enter a valid email address."
    return "Something went wrong. Please try again."

def map_groq_error(status_code: int, error_msg: str) -> dict:
    if status_code == 400:
        return {"status": 400, "message": "Please paste at least 10 characters of code."}
    elif status_code == 504:
        return {"status": 504, "message": "The AI took too long to respond. Please try again."}
    elif status_code == 429:
        return {"status": 429, "message": "You've hit the rate limit. Please wait 30 seconds and try again."}
    elif status_code == 503:
        return {"status": 503, "message": "Couldn't reach the AI service. Check your connection and retry."}
    else:
        return {"status": 500, "message": "Internal configuration error. Please contact the admin."}
Enter fullscreen mode Exit fullscreen mode

Prompt engineering was another area where Copilot saved me real time. Getting Groq to consistently return clean JSON without markdown fences or any extra text took more iteration than I expected. Copilot helped me try variations faster than I could write them myself.

The highlight.js debounce logic for the language detection badge was also Copilot-assisted. JavaScript isn't where I'm strongest and I was avoiding that part. I described the behavior, it gave me a working implementation, I read through it, tweaked it, and moved on.

Mainly what Copilot gave me was speed on the parts I was putting off. Once those were done the project actually started feeling finished.


Connect With Me :)

Built and maintained by Mohit Pandey


Top comments (0)