1. State the intended behavior
Before reading a generated implementation, write down who can perform the action and what must remain true. For an invoice endpoint, a useful rule is: an authenticated user can read an invoice only when they belong to its account.
This rule gives both a reviewer and a test suite something concrete to verify. “The endpoint works” does not distinguish a successful authorized request from an unauthorized disclosure.
2. Trace one input to its effect
Consider this illustrative endpoint:
app.get('/invoices/:id', requireSession, async (req, res) => {
const invoice = await invoices.findById(req.params.id);
res.json(invoice);
});
The session check establishes who the caller is. It does not establish whether the caller may read this invoice. Trace the identifier from the request into the database lookup and then into the response. If the lookup has no account constraint, a caller may be able to request another account's invoice.
A project-specific fix might constrain the lookup using an account identity established by trusted authentication middleware. Do not take that identity from a request field the caller controls. The exact implementation depends on your database and membership model.
3. Test the permission boundary
Write tests that distinguish the behaviors:
- A member can read an invoice in their account.
- The same member cannot read an invoice in another account.
- An unauthenticated request is rejected.
- A nonexistent invoice receives the intended response without leaking unrelated data.
- A database failure follows your error-handling policy.
A test that only checks a successful response would not catch the missing authorization rule.
4. Review more than the happy path
For each changed operation, ask what happens with empty values, invalid identifiers, retries, partial failure and concurrent requests. Check whether new logs expose credentials or sensitive content. For database changes, consider the existing data as well as newly created records.
Focus on risks relevant to the change. A static UI label does not need the same analysis as a payment callback or access-control change.
5. Use automated feedback as evidence to investigate
With CodePeel, review local changes in VS Code, a GitHub pull request or changes submitted through MCP. Inspect each finding's location, explanation and suggested fix against the actual execution path.
If a finding is valid, add a regression test and check the proposed fix. If it is incorrect, identify the guard or invariant that makes the code safe. A review with no findings is still a reason to run your tests and inspect the important boundaries.
Before you merge
Confirm that the change meets the intended behavior, relevant tests pass, and generated fixes do not introduce a new failure. Give a human reviewer enough context to understand the risk and validation. For sensitive changes, seek someone familiar with the affected system.
Next: Add automated review to GitHub, or learn how review allowances work.