Engineering · 2026.10.02 · 5 min · Updated 2026.10.26
Claude Code /code-review on an Entire Frontend: The Four Most Instructive Kinds Among 70-Plus Findings
I ran Claude Code's /code-review max over a whole frontend and confirmed 70-plus issues. Here are the four most instructive kinds, the rule that every test must fail on the unfixed build, and Playwright cross-browser results.
Reading
A confirmation dialog said "Pause", but what actually got sent was a resume. That was one of the findings when Claude Code's /code-review max went over my lending platform's frontend.
Across the whole frontend I confirmed seventy-plus real findings, and most were like that one: an action sending the wrong thing, or state drawn wrong.
The most important acceptance rule: every fix's test must fail on the unfixed build.
And the cross-browser matrix ran nearly three thousand tests but caught just one real platform difference.
Acceptance: tests must fail on the unfixed build
I set the rules before fixing anything. Each finding is first confirmed against the code before it gets fixed, and findings that don't hold up get a written reason.
Every fix needs a test, and that same test must fail on the unfixed build.
A test that also passes on the unfixed version proves nothing about the fix.

The four most instructive kinds of bugs
After fixing them all and looking back, many issues were of the same kind. These four carried the most lessons.
Copy that doesn't match backend behavior
Here you first have to confirm which side reflects the intended design.
The suspension copy said the bot stops once an account is suspended, but the backend didn't actually stop it. Suspended users can't log in, and operations has no UI to pause the bot on their behalf, so a bot that kept placing offers couldn't be stopped by anyone.
That one got fixed in the backend. The engine now excludes suspended users when it fetches its list, in-flight offers are canceled by the existing cancellation schedule, and the user's own lending toggle is left alone.
The reverse case: the maintenance page said the bot stops placing new offers during maintenance, but the design doc explicitly says maintenance doesn't stop the engine. That one got a copy fix.
Temporary failures treated as permanent
Refresh logged people out on any 5xx, and a failed promotions API call was treated as "no campaign running".
Refresh now only treats the session as invalid when the backend explicitly rejects it (400, 401, 403).
A 429, a 5xx or a network error throws refresh's own error instead of reusing the original request's 401 or 403. The reason: the layout redirects people to the homepage on its own when it sees either status.
"Unknown" drawn as another state
Missing data showed up as 0, and a suspension was shown as "paused by you".
For the suspension case I didn't add a new state value. It's still paused, and the cause is derived by a separate function. The Topbar stays safe without any changes and keeps using the same set of words as the states in the admin console.
Settings that lag behind a state change
After a key swap, the lending settings stayed bound to the old key. The status said running, but not a single offer was being placed.
Rebinding now happens the moment the key's state changes. When a key is added, or when a health check disables one, the backend immediately points the settings at the active key.
Relying on the user to hit save on the lending page isn't enough. When the form has no changes, the save button doesn't even appear.

Playwright cross-browser: one real bug
Playwright ran 10 platform profiles covering Chrome, WebKit and Firefox on desktop and mobile. For real browsers I used Safari in the iOS simulator, Chrome in the Android emulator, and Safari and Chrome locally on a Mac.
There's no real Windows machine, only the engines with a Windows UA as emulation.
It caught just one real issue. At sign-up, the interface language was sent in the Accept-Language header, which doesn't work in Firefox and WebKit, so the value the page set never reached the backend.
It now goes in the request body: the backend has a new language field and only falls back to the header when it's absent.
All the other platform differences came from bad assumptions in the tests themselves.
One is worth remembering. When Playwright emulates a locale in WebKit and Firefox, it overrides Accept-Language at the network layer.
Header assertions on those two engines can't be trusted; check the value the backend saved instead.
The final full matrix on main: 2936 passed, 44 failed.
Thirty of those were Turnstile (Cloudflare's CAPTCHA alternative) tests missing the matching build, and they all passed once it was added. The other 14 were one-off flaky failures on a single platform each, and they passed on rerun.

Parallel agents overloaded the machine
The fixes were split into multiple PRs and handed to parallel agents, each with its own git worktree.
The agents didn't commit. The main session reviewed their diffs and did all the commits, so every line was visible before integration.
The second batch was 15 PRs, and this 16GB Mac couldn't keep up.
Eight agents running at once caused the session to restart, and every agent was interrupted at the same time. Luckily the changes stayed in their worktrees, and most of them could be reviewed and wrapped up directly.
Since then my limit is two things at once: one agent plus my own build or tests, or two agents while I only do things that don't eat resources.
Before launching parallel agents, work out whether the machine can handle them.

Engineering
A JWT Expiry Race, 2FA Copy, and Client-Side Password Encryption: Three Account Security Fixes
My lending platform can reach users' exchange API keys, so after launch I fixed three account security issues: checking security copy against the backend, parsing JWTs once to avoid an expiry race, and encrypting passwords before sending.
Letters
Loading comments…