A code review example: one PR, fully annotated
Search for a code review example and you mostly get definitions: what code review is, why it's good, a numbered process. What you rarely get is an actual review. So here's one, end to end: a small AI-written PR, the comments a strong reviewer leaves on it, and the verdict with reasons. Read the diff first and form your own opinion before you read mine.
The PR
The task given to the AI assistant, as three requirements:
- Add
GET /invoices/exportreturning the requester's invoices as CSV. - Accept
fromandtodate query params to bound the range. - Columns: id, customer name, total.
And the diff it opened. Auth middleware already runs on this router, so req.user is populated:
routes/invoices.js
+11
Eleven lines, reads clean, does roughly what was asked. This is exactly the kind of diff that gets approved between two meetings. Now the review.
The review, comment by comment
Comment 1, line 3: the missing tenant scope
This queries every invoice in the range, not the requester's. The requirement says the requester's invoices, and nothing here filters by req.user. As written, any signed-in user exports the whole company's billing.
The most severe finding, and notice what makes the comment work: it doesn't say "add a filter", it names the blast radius. Missing ownership checks are among the most common holes in AI-written endpoints (broken object level authorization has topped the OWASP API Security Top 10 for years), because the model implements the sentence it saw ("export invoices between dates") and quietly drops the qualifier it didn't ("the requester's"). Requirement-vs-implementation reading catches what type checkers never will.
Comment 2, line 5: the CSV that executes
customerName goes into the CSV unescaped. A name containing a comma breaks the columns, and a name starting with = becomes a live formula the moment someone opens this export in Excel. Quote the field and prefix formula triggers, or build the file with a csv library instead of string concat.
Confession: we shipped this exact bug in DiffDojo's own admin export, and our pre-launch security audit caught it, not a reviewer. String-concatenated CSV is a classic (OWASP documents the attack) because it works perfectly on every demo dataset. The trained reflex here is simple: user-controlled text crossing into another format (CSV, HTML, SQL, shell) always gets an escaping question.
Comment 3, line 2: the parameters nobody validated
What happens when from or to is missing or not a date? If findBetween(undefined, undefined) returns everything, this endpoint dumps the full table by default. Worth validating both and failing with a 400.
Phrased as a question, and that's deliberate. The reviewer doesn't know what findBetween does with undefined, and the comment says so honestly. A question that forces the author to check is a completely valid review move; pretending to certainty you don't have is not.
What didn't get a comment
The template-string formatting, the header names, the inline handler instead of a named function: all fine. A weak review of this PR looks like the opposite of the one above: two style nitpicks about naming, an emoji, and an approve. Restraint on the small stuff is what buys your serious comments their weight.
The verdict
Request changes, and the summary comment ties it together:
Requesting changes for the tenant scoping on line 3, which I'd consider a blocker. The CSV escaping and param validation should land with it. Everything else looks good, and the shape of the endpoint is right.
Note the shape: the blocker named first, the severity made explicit, the good parts acknowledged without ceremony. An approve here, with a "maybe add validation later", would have shipped a company-wide data leak that no test suite was going to catch, because every test would use well-formed dates and its own tenant's data.
The pattern behind the comments
Every comment above has the same three parts: the observation, anchored to a line; the concrete consequence; and a way out, either a fix or an honest question. Every one of them also came from a repeatable habit rather than brilliance:
- Reread the requirements after the diff, and check each qualifier survived into the code (comment 1).
- Follow user-controlled data across format boundaries (comment 2).
- Ask what the ugliest legal input does (comment 3).
- Say nothing about what's merely different from how you'd write it.
Habits become reflexes through reps, and reviewing is no exception. That's the premise DiffDojo is built on: one realistic AI-written PR like this one every day, your comments and verdict graded against a canonical review. The daily PR is free, no signup. Today's has a different bug in it.
You've seen the annotated answer. Now try one cold: fresh PR, no annotations, your call.
Review today's PR, freeRead next: How to review AI-generated code: a guide for the human in the loop