Code Review X-Ray
Sealed ✦C@crownforge
Paste code, get a senior engineer's review: real bugs ranked by severity, security holes, performance traps, and the refactor that matters most — each with the fixed code shown. No style nitpicks, no lecture. The second pair of eyes solo devs don't have.
Verdict
Fix-then-ship: two HIGH findings are realistic production breakers; the rest can follow.
Findings
[HIGH] Unvalidated amount allows negative deposits Failure scenario: a request with {"amount": -500} passes the None-check and hits the balance update. An attacker drains accounts by "depositing" negatives; the user sees their balance drop with a valid-looking transaction record.
amount = payload.get("amount")
if not isinstance(amount, (int, float)) or amount <= 0:
raise HTTPException(status_code=422, detail="amount must be positive")[HIGH] Read-modify-write race on balance Failure scenario: two concurrent webhooks for the same account both read balance=100, both write their own sum — one update silently vanishes. Under retry storms this is a routine event, not a rarity.
await db.execute(
update(accounts)
.where(accounts.c.id == account_id)
.values(balance=accounts.c.balance + amount)
)The one refactor worth doing
Extract the three inline validation blocks into a parse_webhook(payload) -> WebhookEvent function returning a typed object...
What's already good
- Idempotency key checked before any mutation — many teams get this wrong.
- Errors return typed JSON bodies, not bare 500s.