skills / code

code-review-excellence

what it does

Master effective code review practices to provide constructive feedback, catch bugs early, and foster knowledge sharing while maintaining team morale. Use when reviewing pull requests, establishing review standards, or mentoring developers.

Verified Before and after: 2 models 1 try per case View source Download .zip

Compare the answers

Answers from Claude Sonnet 5.5 and GPT-6.1 Sol · try 1 of 1

Same request, same model, once with the skill and once without. Read both and judge for yourself.

“Review this before I merge please. It's the CSV contact import we talked about.”

Source material given with the request

PR #92 "Contact import from CSV" Description: Parses the uploaded CSV and inserts each row as a contact. Returns how many were imported so the UI can show "Imported N of M contacts". Tested locally with a 3-row file. --- /dev/null +++ b/src/import/importContacts.ts @@ -0,0 +1,19 @@ +import { Db } from "../db"; +import { CsvRow, toContact } from "./csv"; + +export interface ImportResult { + imported: number; + total: number; +} + +export async function importContacts(rows: CsvRow[], db: Db): Promise<ImportResult> { + let imported = 0; + + rows.forEach(async (row) => { + const contact = toContact(row);
Show the rest (7 more lines)
+ await db.contacts.insert(contact); + imported++; + }); + + return { imported, total: rows.length }; +}
with the skill
## Summary The import logic has a bug that will make the feature report the wrong number every time, so I'd hold off merging. It's a small fix. ## 🔴 [blocking] `forEach(async ...)` isn't awaited, so `imported` is returned as 0 ```ts rows.forEach(async (row) => { ... await db.contacts.insert(contact); imported++; }); return { imported, total: rows.length }; ``` `Array.prototype.forEach` ignores the promises returned by an async callback. Each callback runs until its first `await`, then `forEach` moves on. The function reaches `return` before any insert has finished, so the UI will show "Imported 0 of 3 contacts" even when every row is saved. The inserts do still run in the background, which can make a quick local test look fine if you checked the DB rather than the returned count. ## 🔴 [blocking] Errors become unhandled promise rejections
Show the rest (53 more lines)
Nothing catches errors inside the callback. If `toContact(row)` throws on a malformed row, or `insert` fails (duplicate key, constraint violation, connection error), the rejection is detached from the caller. On Node 15+ an unhandled rejection crashes the process by default. The caller also can't tell that anything went wrong. ## 🟡 [important] Unbounded concurrency Even once awaited correctly, `rows.map(...)` with `Promise.all` fires every insert at once. A 50k-row file would exhaust the connection pool and starve other requests. Process rows sequentially, in bounded batches, or with a bulk insert. ## 🟡 [important] Decide what partial failure means "Imported N of M" implies some rows can fail, but the result doesn't say which ones or why. Users will want to know which rows to fix. Also decide whether the import should be all-or-nothing (a transaction) or best-effort. ## Suggested fix (best-effort, sequential) ```ts export interface ImportResult { imported: number; total: number; failed: { index: number; error: string }[]; } export async function importContacts(rows: CsvRow[], db: Db): Promise<ImportResult> { let imported = 0; const failed: ImportResult["failed"] = []; for (const [index, row] of rows.entries()) { try { await db.contacts.insert(toContact(row)); imported++; } catch (err) { failed.push({ index, error: err instanceof Error ? err.message : String(err) }); } } return { imported, total: rows.length, failed }; } ``` If throughput matters, chunk the rows (e.g. 100 at a time) with `Promise.allSettled`, or use a bulk insert if `Db` supports one. If you'd rather it be all-or-nothing, wrap the loop in a transaction and let it throw. ## 💡 [suggestion] Tests "Tested locally with a 3-row file" isn't enough here, and a basic test would have caught the first bug. Cases I'd want: - All rows succeed, so `imported === total`. - One row fails in `toContact` or `insert`, so it's counted in `failed` and the rest still import. - Empty input returns `{ imported: 0, total: 0, failed: [] }`. - Ideally, a larger input that checks concurrency stays bounded. ## ❓ Questions - Should duplicates (same email) be skipped, updated, or reported as failures? - Is there a max file or row size enforced upstream? I only see this one file, so I can't tell whether `csv.ts` or the upload handler limit it. ## Verdict 🔄 **Request changes.** The first two items must be fixed before merge. The rest can be handled here or in a follow-up. Happy to look at the updated version or the tests.
without
**Don't merge yet: there's a blocking bug.** ## Blocking: `forEach(async ...)` isn't awaited ```ts rows.forEach(async (row) => { ... await db.contacts.insert(contact); imported++; }); return { imported, total: rows.length }; ``` `forEach` ignores the promises returned by its callback. The function reaches `return` right after kicking off the inserts, before any `await` has resolved, so: - **`imported` will be `0`** in the result (the increments happen later). The UI would show "Imported 0 of 3 contacts" even though the rows are being inserted. - **Errors are unhandled.** If `toContact` throws (bad row) or `insert` rejects (constraint violation, DB down), it becomes an unhandled promise rejection. That can crash the process on modern Node, and the caller never learns about it. - **All inserts fire at once**, which for a large CSV means thousands of concurrent DB calls. The 3-row local test likely looked fine because the rows did get inserted. The returned count is what's wrong, and it's easy to miss if you only checked the DB. ## Suggested fix ```ts
Show the rest (39 more lines)
export interface ImportResult { imported: number; total: number; errors: { row: number; message: string }[]; } export async function importContacts(rows: CsvRow[], db: Db): Promise<ImportResult> { let imported = 0; const errors: ImportResult["errors"] = []; for (const [i, row] of rows.entries()) { try { await db.contacts.insert(toContact(row)); imported++; } catch (err) { errors.push({ row: i, message: err instanceof Error ? err.message : String(err) }); } } return { imported, total: rows.length, errors }; } ``` Sequential `for...of` is simple and safe. If speed matters, use a bulk insert if `Db` supports it, or process in bounded batches with `Promise.allSettled`. ## Design questions - **Failure policy:** should one bad row skip that row (as above) or abort the whole import in a transaction? The "N of M" UI suggests partial success is intended, but it's worth confirming. - **Row numbers:** `i` is the index in the parsed rows. If you want to show users a line number, add 2 to account for the header and 1-based counting (assuming a header row). - **Duplicates:** what happens when a contact with the same email already exists? Right now that depends on DB constraints, and with the fix it would show up as a per-row error. ## Tests to add 1. All rows succeed: `imported === total`. 2. One `insert` rejects: `imported === total - 1` and `errors` has one entry, with no unhandled rejection. 3. `toContact` throws on a malformed row, handled the same way. 4. Empty array returns `{ imported: 0, total: 0, errors: [] }`. Test 1 would have caught the original bug. A mock `db` whose `insert` resolves on a later tick makes the problem obvious.

Answers are shown exactly as the model wrote them, from the first try, and nothing is picked by hand.

The models

2 models

Claude Sonnet 5.5

made by Anthropic

claude-sonnet-5-5 · revision not reported by the provider

1 try per case · tested 3 Nov 2026

GPT-6.1 Sol

made by OpenAI

gpt-6.1-sol · revision not reported by the provider

1 try per case · tested 3 Nov 2026

The tasks

written by Carte Blanche
py-chunked-clean-diff

“Quick review before I merge? Mostly want to know if anything blocks it.”

py-search-injection-pagination

“Can you review this PR? It adds order search to our internal admin API.”

py-wallet-withdraw-race

“Please review this change to our wallet service.”

ts-async-foreach-import

“Review this before I merge please. It's the CSV contact import we talked about.”

ts-file-delete-first-pr

“This is Priya's first PR since she joined the team last week. Can you review it? I'll paste your comments into GitHub.”

Install

Download the .zip and unzip it. Put its files, in a folder named code-review-excellence, here:

Claude Code~/.claude/skills/Every project. For one project only, use .claude/skills/ inside it.
Codex~/.agents/skills/Every project. For one repository only, use .agents/skills/ inside it.
Cursor~/.cursor/skills/Cursor also reads the Claude Code and Codex folders above.

Then start a new session and ask for what the skill does. Other agents that read SKILL.md have their own skills folder; check their docs.

Coming after launch: get skills from inside your agent, no download needed.