TUTORIAL 06

Code Review Workflow

@dev submitted PR#42 "feat(tasks): add task filtering by status". You're @lead reviewing it.

โฑ ~15 min ยท Hands-on

/agile-code-pr-review /agile-code-review /agile-code-merge
Scenario

Your teammate @dev has opened PR#42 with a new task filtering feature. The PR adds a FilterService, updates TaskController, and includes new tests. You're @lead โ€” it's your job to review before this merges to develop.

Step 1: Read the PR Diff

Before running any commands, read the diff and understand what changed. Don't jump to nitpicking โ€” understand intent first.

PR#42 โ€” feat(tasks): add task filtering by status

Files changed: 4 files, +187 lines, -12 lines

Step 2: Run Structured Review

Use /agile-code-pr-review for a systematic, severity-classified review.

/agile-code-pr-review
PR Review โ€” #42 feat(tasks): add task filtering by status
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

๐Ÿ”ด S0 โ€” BLOCKS MERGE
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[1] SQL Injection in FilterService.java:34
    String query = "SELECT * FROM tasks WHERE status = '" + status + "'";
    โ†’ User input concatenated directly into SQL. Must use parameterized query.

๐ŸŸ  S1 โ€” MUST FIX
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[2] SRP Violation in FilterService.java
    FilterService handles both filtering AND sorting (methods: filterByStatus,
    filterByPriority, sortByDate, sortByPriority). These are two responsibilities.
    โ†’ Split into FilterService and SortService.

๐ŸŸก S2 โ€” SHOULD FIX
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[3] Poor naming in TaskController.java:67
    List<Task> data = filterService.filterByStatus(status);
    โ†’ 'data' is generic. Use 'filteredTasks' for clarity.

๐Ÿ”ต S3 โ€” NIT
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[4] Import order in FilterService.java:1-8
    Imports are not grouped (java.util mixed with org.springframework).
    โ†’ Follow project convention: java.* โ†’ javax.* โ†’ org.* โ†’ com.*

โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
Verdict: โŒ CHANGES REQUESTED (1 blocker, 1 must-fix)

Step 3: Understand the Severity System

SeverityLabelActionBlocks Merge?
๐Ÿ”ด S0 Critical Security vulnerability, data loss, crash YES
๐ŸŸ  S1 Major Design flaw, SRP violation, missing error handling YES
๐ŸŸก S2 Minor Naming, readability, minor improvements No (should fix)
๐Ÿ”ต S3 Nit Style, formatting, personal preference No (optional)

Rule: Any ๐Ÿ”ด S0 or ๐ŸŸ  S1 finding blocks the merge. ๐ŸŸก S2 should be fixed but doesn't block. ๐Ÿ”ต S3 is at the author's discretion.

Step 4: Author Addresses Findings

@dev pushes fixes for each finding:

๐Ÿ”ด S0 Fix: Parameterized Query

โŒ Before (SQL Injection)
String query = "SELECT * FROM tasks WHERE status = '" + status + "'";
โœ… After (Parameterized)
String query = "SELECT * FROM tasks WHERE status = ?";
PreparedStatement stmt = conn.prepareStatement(query);
stmt.setString(1, status);

๐ŸŸ  S1 Fix: Split Responsibilities

@dev extracts sorting logic into a new SortService:

๐ŸŸก S2 Fix: Rename Variable

// Before
List<Task> data = filterService.filterByStatus(status);

// After
List<Task> filteredTasks = filterService.filterByStatus(status);

๐Ÿ”ต S3: Acknowledged

@dev reorders imports to follow project convention. Quick fix, no debate needed.

Step 5: Re-Review

@dev pushes the fixes and requests re-review. Run /agile-code-pr-review again.

/agile-code-pr-review
PR Re-Review โ€” #42 feat(tasks): add task filtering by status
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

Previous Findings:
  ๐Ÿ”ด S0 [1] SQL Injection .............. โœ… RESOLVED (parameterized query)
  ๐ŸŸ  S1 [2] SRP Violation .............. โœ… RESOLVED (SortService extracted)
  ๐ŸŸก S2 [3] Poor naming ................ โœ… RESOLVED (renamed to filteredTasks)
  ๐Ÿ”ต S3 [4] Import order ............... โœ… RESOLVED (reordered)

New Findings: (none)

โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
Verdict: โœ… APPROVED โ€” merge to develop

Step 6: Merge with /agile-code-merge

With the PR approved, merge the feature branch using the agile command:

/agile-code-merge
๐Ÿ”€ Merge โ€” PR #42
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Pre-merge checks:
  โœ… PR approved by @lead
  โœ… CI passing on branch
  โœ… No merge conflicts
  โœ… Branch up to date with develop

Merging: feature/task-filtering โ†’ develop
Strategy: merge --no-ff (project convention)

Merge complete.
Branch feature/task-filtering deleted (was 7b2e4d1).

โœ… PR #42 merged to develop.
โœ… PR#42 Merged

The task filtering feature lands on develop with a critical SQL injection caught before it reached users. /agile-code-merge verified all pre-merge conditions, applied the project's merge strategy, and cleaned up the branch automatically. This is why code review exists.

Best Practices: As a Reviewer

Best Practices: As an Author

What You Practiced

Knowledge Check

Which severity levels block a PR merge?