Code Review and Refactoring
Use AI as a tireless code reviewer that catches bugs, suggests improvements, and helps you refactor with confidence.
Premium Course Content
This lesson is part of a premium course. Upgrade to Pro to unlock all premium courses and content.
- Access all premium courses
- 1000+ AI skills included
- New content added weekly
Your Most Patient Reviewer
In the previous lesson, we explored testing and quality assurance. Now let’s build on that foundation. Human code reviewers are invaluable. They also have meetings, deadlines, and bad days. They skim the fourth PR of the morning. They miss the subtle type coercion bug buried in line 247.
AI doesn’t skim. It doesn’t have bad days. It catches the same patterns whether it’s the first review of the day or the hundredth.
This doesn’t mean AI replaces human reviewers. It means AI handles the mechanical checks—bugs, security issues, performance patterns, style consistency—so human reviewers can focus on architecture, design decisions, and business logic.
The AI Code Review Prompt
Here’s the prompt structure that gets the best reviews:
Review this code for a pull request. Focus on:
1. Bugs and logic errors
2. Security vulnerabilities
3. Performance issues
4. Readability and maintainability
Context: This is a [description of what the code does]
in our [tech stack]. It [what it's part of].
Existing conventions to check against:
- [list your team's key conventions]
[paste code]
For each issue, specify:
- Severity (critical/warning/suggestion)
- Line number or section
- What's wrong
- How to fix it
A Review in Action
Let’s see this work on real code. Here’s a user authentication endpoint:
app.post('/api/login', async (req, res) => {
const { email, password } = req.body;
const user = await db.query(
`SELECT * FROM users WHERE email = '${email}'`
);
if (user.rows.length === 0) {
return res.status(401).json({ error: 'User not found' });
}
if (password === user.rows[0].password) {
const token = jwt.sign(
{ id: user.rows[0].id, role: user.rows[0].role },
'my-secret-key',
{ expiresIn: '24h' }
);
res.json({ token, user: user.rows[0] });
} else {
return res.status(401).json({ error: 'Wrong password' });
}
});
AI will flag multiple issues here, roughly in this order:
Critical: SQL Injection (Line 5)
The email is interpolated directly into the SQL query. An attacker could send ' OR 1=1 -- as the email. Fix: Use parameterized queries.
Critical: Plain-text password comparison (Line 11) Passwords are compared as plain text, meaning they’re stored unhashed in the database. Fix: Use bcrypt.compare().
Critical: Hardcoded JWT secret (Line 13) The secret key is in the source code. Fix: Use an environment variable.
Warning: Different error messages for invalid email vs. password (Lines 9, 17) This leaks information—an attacker can enumerate valid emails. Fix: Use the same message for both: “Invalid credentials.”
Warning: Returning the full user object (Line 16)
user.rows[0] likely includes the password hash and other sensitive fields. Fix: Select only needed fields or sanitize before returning.
Suggestion: No input validation (Line 2) Email and password are used without validation. Add input validation before the database query.
That’s six issues, three of them critical security vulnerabilities. A tired human reviewer might catch some of these. AI catches all of them, every time.
Focused Reviews
Sometimes you don’t need a general review—you need a specific focus:
Security-Focused Review
Review this code specifically for security vulnerabilities.
Check for:
- Injection attacks (SQL, XSS, command injection)
- Authentication/authorization bypasses
- Sensitive data exposure
- Missing input validation
- Insecure cryptographic practices
Performance-Focused Review
Review this code for performance issues.
Check for:
- N+1 query patterns
- Unnecessary memory allocation
- Missing database indexes (based on query patterns)
- Opportunities for caching
- Blocking operations in async contexts
Readability-Focused Review
Review this code for readability and maintainability.
Check for:
- Unclear variable/function names
- Functions doing too many things
- Missing or misleading comments
- Complex conditional logic that could be simplified
- Inconsistent patterns compared to the rest of our codebase
Each focus area gets you deeper, more relevant feedback than a generic “review this code.”
Quick Check: What Would AI Flag?
Look at this code. What issues would AI catch?
def process_order(order):
total = 0
for item in order['items']:
total += item['price'] * item['qty']
if total > 100:
total = total * 0.9 # 10% discount
order['total'] = total
send_email(order['email'], f"Your order total: ${total}")
charge_payment(order['payment_info'], total)
save_to_database(order)
return {'status': 'success'}
AI would likely flag: no error handling (what if payment fails after email?), mutating the input order dict, no validation of order structure, potential floating-point issues with money, hardcoded discount logic, and the email/payment/save operations should be in a transaction.
AI-Assisted Refactoring
Refactoring is where AI really earns its keep. The process:
Step 1: Assess the Code
Here's a function that's grown to 200 lines and handles
too many responsibilities. Identify the distinct concerns
and suggest how to break it apart.
[paste the long function]
AI will map out the responsibilities: validation, business logic, database operations, notifications, error handling. It’ll suggest how to separate them.
Step 2: Plan the Refactoring
Based on your analysis, create a refactoring plan.
For each step:
1. What change to make
2. What tests to add/modify
3. How to verify nothing broke
The function currently has these tests:
[paste existing tests]
Step 3: Execute Incrementally
Don’t refactor everything at once. Extract one concern at a time:
Refactor step 1: Extract the validation logic from
processOrder into a separate validateOrder function.
Here's the current code:
[paste current state]
Requirements:
- New function should throw descriptive errors
- Existing tests must still pass
- Add new tests for the extracted function
After each step, run your tests. Verify. Then move to the next extraction.
Step 4: Verify the Refactoring
After all steps are complete:
Here's the original function and the refactored version.
Verify that:
1. All original behaviors are preserved
2. No edge cases were lost in the refactoring
3. Error handling is equivalent or better
Original:
[paste original]
Refactored:
[paste refactored version]
Common Refactoring Patterns AI Handles Well
Extract Method: AI identifies natural boundaries in long functions and extracts them into well-named helper functions.
Replace Conditional with Polymorphism: When you have a massive switch/case or if/else chain, AI can suggest a strategy or factory pattern.
Simplify Complex Conditions:
// Before (AI identifies this is hard to read)
if (user.role === 'admin' || (user.role === 'manager'
&& user.department === dept && !user.suspended))
// After (AI suggests extraction)
const canAccess = isAdmin(user) || isActiveDeptManager(user, dept)
Remove Duplication: Paste two similar functions and ask AI to identify the shared logic and create a common abstraction.
Building a Review Checklist
Over time, you’ll develop patterns for what AI catches well in your codebase. Build a reusable checklist:
Review this PR against our standard checklist:
[ ] No SQL injection or XSS vulnerabilities
[ ] Error handling covers all failure modes
[ ] Input validation present for all external inputs
[ ] No secrets or credentials hardcoded
[ ] Database queries are optimized (no N+1)
[ ] Consistent with existing code patterns
[ ] Functions are under 50 lines
[ ] New code has corresponding tests
[ ] No TODO or FIXME comments without tickets
[ ] Logging present for debugging production issues
[paste the PR diff]
The AI will check each item and flag any violations.
Key Takeaways
- AI catches mechanical issues consistently—security flaws, performance patterns, style violations
- Focused reviews (security, performance, readability) give deeper, more actionable feedback
- Use AI review before human review to catch the obvious issues first
- Refactor incrementally: assess, plan, execute step-by-step, verify
- Build reusable review checklists for your team’s standards
- Human reviewers should focus on architecture, design, and business logic
Next up: documentation. The thing every developer knows they should do but never finds time for. AI changes that equation completely.
Up next: In the next lesson, we’ll dive into Documentation and Knowledge Sharing.
Knowledge Check
Complete the quiz above first
Lesson completed!