code-review
Perform thorough code reviews with security, performance, and maintainability analysis. Use when user asks to review code, check for bugs, or audit a codebase.
Code Review Skill
You now have expertise in conducting comprehensive code reviews. Follow this structured approach:
Review Checklist
1. Security (Critical)
Check for:
- Injection vulnerabilities: SQL injection, command injection, XSS, LDAP injection
- Authentication issues: Hardcoded credentials, weak authentication mechanisms
- Authorization flaws: Missing access controls, IDOR, privilege escalation
- Data exposure: Sensitive data in logs, error messages, or stack traces
- Cryptography: Weak algorithms, improper key management, plaintext secrets
- Dependencies: Known vulnerabilities in third-party libraries
# Quick security scans for Java projects
mvn dependency-check:check # OWASP dependency check
./gradlew dependencyCheckAnalyze # Gradle equivalent
grep -r "password\|secret\|api_key\|apiKey" --include="*.java" --include="*.yml" --include="*.properties"
2. Correctness
Check for:
- Logic errors: Off-by-one, null handling, edge cases
- Race conditions: Concurrent access without synchronization, shared mutable state
- Resource leaks: Unclosed streams, connections, or resources (missing try-with-resources)
- Error handling: Swallowed exceptions, overly broad catch blocks, missing error paths
- Type safety: Unchecked casts, raw types, missing generics
3. Performance
Check for:
- N+1 queries: Database/API calls in loops (common with JPA/Hibernate)
- Memory issues: Large object allocations, retained references, improper caching
- Blocking operations: Blocking I/O in reactive/async code paths
- Inefficient algorithms: O(n^2) when O(n) is possible, unnecessary object creation
- Missing caching: Repeated expensive computations or database lookups
- String concatenation: Using
+in loops instead ofStringBuilder
4. Maintainability
Check for:
- Naming: Clear, consistent, descriptive (follows Java conventions)
- Complexity: Methods > 50 lines, deep nesting > 3 levels, cyclomatic complexity
- Duplication: Copy-pasted code blocks violating DRY
- Dead code: Unused imports, unreachable branches, commented-out code
- Comments: Outdated Javadoc, redundant comments, or missing documentation where needed
- SOLID principles: Single responsibility, proper abstractions, dependency injection
5. Testing
Check for:
- Coverage: Critical paths and business logic tested
- Edge cases: Null, empty, boundary values, error conditions
- Mocking: External dependencies properly isolated (Mockito, WireMock)
- Assertions: Meaningful, specific checks (not just
assertNotNull) - Test naming: Descriptive names following conventions (e.g.,
shouldReturnEmpty_whenInputIsNull)
Review Output Format
## Code Review: [file/component name]
### Summary
[1-2 sentence overview]
### Critical Issues
1. **[Issue]** (line X): [Description]
- Impact: [What could go wrong]
- Fix: [Suggested solution]
### Improvements
1. **[Suggestion]** (line X): [Description]
### Positive Notes
- [What was done well]
### Verdict
[ ] Ready to merge
[ ] Needs minor changes
[ ] Needs major revision
Common Patterns to Flag
Java
// Bad: SQL injection
String query = "SELECT * FROM users WHERE id = " + userId;
stmt.executeQuery(query);
// Good: Use parameterized queries
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
ps.setString(1, userId);
// Bad: Resource leak
InputStream is = new FileInputStream("file.txt");
// processing without close
// Good: try-with-resources
try (InputStream is = new FileInputStream("file.txt")) {
// processing
}
// Bad: Swallowed exception
try { riskyOperation(); } catch (Exception e) { }
// Good: Log or rethrow
try { riskyOperation(); } catch (Exception e) {
log.error("Operation failed", e);
throw new ServiceException("Operation failed", e);
}
// Bad: Mutable shared state without synchronization
private List<String> cache = new ArrayList<>();
// Good: Use concurrent collections or synchronization
private List<String> cache = new CopyOnWriteArrayList<>();
// Bad: N+1 query in JPA
List<Order> orders = orderRepo.findAll();
orders.forEach(o -> o.getItems().size()); // triggers lazy load per order
// Good: Use fetch join
@Query("SELECT o FROM Order o JOIN FETCH o.items")
List<Order> findAllWithItems();
Spring Boot
// Bad: Hardcoded secrets
@Value("sk-abc123xyz")
private String apiKey;
// Good: Use externalized configuration
@Value("${api.key}")
private String apiKey;
// Bad: Missing validation
@PostMapping("/users")
public User create(@RequestBody User user) { ... }
// Good: Validate input
@PostMapping("/users")
public User create(@Valid @RequestBody User user) { ... }
Review Commands
# Show recent changes
git diff HEAD~5 --stat
git log --oneline -10
# Find potential issues
grep -rn "TODO\|FIXME\|HACK\|XXX" --include="*.java" .
grep -rn "password\|secret\|token" --include="*.java" --include="*.properties" --include="*.yml" .
# Check for common issues
mvn spotbugs:check # Static analysis
mvn checkstyle:check # Code style
./gradlew spotbugsMain # Gradle equivalent
# Run tests with coverage
mvn test jacoco:report
./gradlew test jacocoTestReport
# Check dependencies
mvn versions:display-dependency-updates
./gradlew dependencyUpdates
Review Workflow
- Understand context: Read PR description, linked issues, and acceptance criteria
- Run the code: Build, run tests, start locally if possible (
mvn spring-boot:run) - Read top-down: Start with controllers/entry points, follow the call chain
- Check tests: Are changes tested? Do tests pass? Is coverage adequate?
- Security scan: Run SpotBugs, OWASP dependency check
- Manual review: Use checklist above, focus on business logic correctness
- Write feedback: Be specific, suggest fixes, be kind and constructive