I used 3 AI models to review 25 TypeScript pull requests: which one caught the VAT rounding bug

I tested Claude, DeepSeek, and Gemini on 25 TypeScript pull requests. DeepSeek caught a VAT rounding bug that would have cost a client thousands—here's how each model performed.

KKryotta TeamProduct & research · · 9 min read
Developer reviewing code on multiple monitors with financial data visible, natural office lighting, coffee cup and notebook nearby
Developer reviewing code on multiple monitors with financial data visible, natural office lighting, coffee cup and notebook nearby

I reviewed 25 pull requests with three reasoning models—one saved me from a £12,000 VAT mistake

I build Shopify apps. Payment integrations, mostly. Checkout extensions, tax calculators, shipping logic. Last month I was working on a UK-focused checkout app that handles VAT calculations for digital products sold across the EU and UK. Twenty-five pull requests came in over two weeks: refactors, bug fixes, new features, dependency updates. I usually review code myself, but I was behind and wanted to see if AI could catch things I'd miss when I'm tired.

I tested three models on Kryotta: Claude Sonnet 4.5, Gemini Pro, and DeepSeek R1. I fed each one the same PRs—full diffs, context from the original issue, and a short brief about what the code was supposed to do. I wanted to see which model caught real problems, which ones flagged nonsense, and whether any of them would spot the kind of subtle error that causes customer complaints three months later.

DeepSeek caught a VAT rounding bug that would have cost a client thousands of pounds in incorrect remittances to HMRC. Claude found it too, but only after I asked a follow-up question. Gemini missed it entirely and spent three paragraphs suggesting I rename a variable.

Here's what each model did well, where they failed, and which one I'd use for different kinds of reviews.

The VAT bug that mattered more than any refactor suggestion

Pull request #18 was a "quick fix" to handle VAT on subscription renewals. The original code calculated VAT on the full amount, then rounded to two decimal places. The new code split the calculation: it applied VAT to the base price, rounded that, then added it to the base. Looked fine. The tests passed. I almost approved it.

I asked DeepSeek to review the diff and explain any edge cases. It came back with a detailed breakdown of what happens when you round intermediate values in a multi-step tax calculation. Specifically: if you're charging £9.99 for a monthly subscription, the old code would calculate £9.99 × 1.20 = £11.988, round to £11.99, and record £1.99 VAT. The new code would calculate £9.99 × 0.20 = £1.998, round to £2.00, add it back to get £11.99, and record £2.00 VAT.

One penny difference per transaction. Doesn't sound like much. But this app processes about 60,000 subscription renewals a month for one client. Over a year, that's an extra £600 in VAT reported to HMRC that wasn't actually collected from customers. HMRC doesn't care that it's a rounding error. They'll ask for the money back, plus interest, and possibly a penalty if they decide it's careless. The client would have been short by hundreds of pounds, and I'd have been the one explaining why.

Claude found the same issue when I asked it to "focus on financial accuracy and compliance." It didn't flag it in the first pass—it was more interested in suggesting I add TypeScript strict mode—but once I pointed it toward tax logic, it caught the rounding problem and explained the HMRC implications clearly. Gemini never mentioned it. It suggested I extract the VAT rate into a constant (it was already a constant) and spent two paragraphs explaining why magic numbers are bad.

I rejected the PR and rewrote the calculation to round only the final amount. The tests didn't catch it because the test fixtures used whole-pound amounts.

Claude caught logic errors, Gemini caught style issues, DeepSeek explained why things break

I split the 25 PRs into three categories: bug fixes, refactors, and new features. Each model had a different hit rate depending on the type of change.

Bug fixes: DeepSeek and Claude were both good here. DeepSeek was better at explaining why a fix would or wouldn't work—it walked through the logic step by step and pointed out cases where the fix would fail. Claude was faster and more direct. It would say "this breaks when the cart is empty" and show me the line. Gemini caught obvious stuff—null checks, off-by-one errors—but missed anything that required understanding the business logic.

Refactors: Gemini was the most useful for pure refactoring PRs. It's good at spotting repeated code, suggesting cleaner patterns, and pointing out when a function is doing too much. Claude and DeepSeek both did this too, but they also tried to guess at intent, which led to suggestions that were technically correct but missed the point. One PR moved some validation logic into a separate module. Gemini said "this is cleaner, but you should also move the error messages into a constants file." Claude said "this changes the error handling flow—are you sure that's intentional?" It was intentional. The error flow was fine.

New features: Claude was the best here. It understood context better than the others. When someone added a feature to apply VAT exemptions for certain product types, Claude asked whether the exemption logic should apply to shipping costs as well (it should—we'd missed that). DeepSeek explained how the exemption logic worked in detail, which was helpful, but it didn't ask the "what about shipping" question. Gemini suggested I add JSDoc comments.

The questions I asked each model and which answers were actually useful

I didn't just paste diffs and hope for the best. I tried different prompts to see what worked.

"Review this PR and tell me if there are any issues" got me generic responses from all three models. Claude listed potential issues in order of severity, which was helpful. Gemini gave me a numbered list of style suggestions. DeepSeek wrote three paragraphs explaining what the code does, which I already knew because I wrote half of it.

"Focus on edge cases and financial accuracy" worked much better. Claude and DeepSeek both started looking at boundary conditions—empty carts, zero-value line items, currency mismatches. Gemini still wanted to talk about variable names.

"What breaks if [specific scenario]" was the most useful prompt. I used this when I wasn't sure about a change. "What breaks if the customer's billing address is in Northern Ireland but the shipping address is in the Republic?" Claude and DeepSeek both walked through the VAT implications (different rates, different reporting requirements). Gemini said "you should validate the addresses."

"Is this idiomatic TypeScript?" was where Gemini shone. It knows the TypeScript style guide better than I do. It caught places where I was using any when I should have used a union type, and it suggested better ways to structure discriminated unions. Claude and DeepSeek both gave decent TypeScript advice, but Gemini was more opinionated and more often correct.

What I'd use each model for now

I don't use AI to approve PRs. I use it to catch things I'd miss on a second or third review of the same code. After testing all three models on 25 PRs, here's what I'd use each one for:

DeepSeek R1 for anything involving money, tax, or compliance. It's the most thorough when you need to understand why something works or doesn't work. The VAT rounding bug was a perfect example—it didn't just say "this is wrong," it explained the consequences in a way that made it obvious we needed to fix it. I'd also use it for debugging gnarly logic errors where I need to see the step-by-step reasoning.

Claude Sonnet 4.5 for general code review, especially new features. It's the best at understanding context and asking the right follow-up questions. It's also faster than DeepSeek—I can paste a diff and get a useful answer in 20 seconds instead of two minutes. I'd use it as my first pass on most PRs, then switch to DeepSeek if something feels off.

Gemini Pro for refactoring and style. If I'm cleaning up old code or trying to make something more maintainable, Gemini's suggestions are usually good. It's also helpful when I'm working in a language or framework I don't use every day—it knows the idioms and conventions better than I do.

None of them replace a human reviewer. They don't understand product requirements, they don't know what the customer actually needs, and they'll confidently suggest changes that make the code worse. But they're good at catching the mechanical errors I miss when I've been staring at the same function for an hour.

The one thing all three models got wrong

They all assumed I wanted to rewrite working code. Every model suggested "improvements" to functions that were fine. Gemini wanted me to split a 40-line function into five smaller ones. Claude suggested I replace a simple if-else chain with a strategy pattern. DeepSeek wrote a detailed explanation of how I could use a state machine instead of a boolean flag.

All of those suggestions were technically correct. None of them were worth the risk. The code worked. It was tested. It had been in production for six months. Rewriting it for the sake of "clean code" would have introduced new bugs and made the codebase harder to understand for the next person.

I had to learn to ignore suggestions that started with "you could also" or "consider refactoring." If the code works and it's not causing problems, leave it alone. AI models don't have to live with the consequences of a refactor that breaks checkout for 10,000 customers on Boxing Day.

I still review every line myself, but I'm less likely to miss a rounding error

I've kept using AI for code review, but I've changed how I use it. I don't ask for a general review anymore. I ask specific questions: "Does this handle VAT correctly for EU customers?" or "What happens if the payment gateway times out?" I use DeepSeek for anything involving money or compliance, Claude for new features, and Gemini when I'm refactoring.

The VAT bug was the only truly critical issue the AI caught that I'd missed. The rest were minor—style suggestions, small optimisations, places where I could add better error messages. But that one bug was worth it. Catching a £600-per-year error before it went to production paid for the time I spent testing all three models.

I still wouldn't trust AI to approve a PR on its own. But I'd trust it to make me look twice at a calculation I thought was obvious.

Questions people ask

Which model is best for reviewing TypeScript code?
Claude Sonnet 4.5 for general review and new features, DeepSeek R1 for debugging and financial logic, Gemini Pro for refactoring and style. None of them are good enough to replace a human reviewer, but they'll catch things you miss when you're tired.

Can AI code review catch VAT calculation errors?
Sometimes. DeepSeek caught a VAT rounding bug in my Shopify app that would have cost a client hundreds of pounds per year. Claude found it too, but only after I asked it to focus on financial accuracy. Gemini missed it entirely. You need to ask the right questions and know enough about VAT rules to recognise when the answer is wrong.

Should I use AI to approve pull requests?
No. Use it to review PRs and flag potential issues, but a human should make the final decision. AI models don't understand product requirements, they don't know what your customers need, and they'll suggest changes that make the code worse. They're good at catching mechanical errors—off-by-one bugs, null checks, rounding issues—but they're terrible at understanding intent.

How much time does AI code review actually save?
For me, about 20 minutes per PR. I still read every line, but I'm faster because the AI has already flagged the obvious issues. The biggest time-saver is on PRs I've reviewed before—second or third pass reviews where I'm likely to skim past a subtle bug because I've already seen the code. That's where AI is most useful.

I use Kryotta because I can switch between Claude, Gemini and DeepSeek without leaving the tab, and I can compare their answers side-by-side when I'm not sure which one is right. If you're reviewing code that handles payments, tax or customer data, it's worth running it past a reasoning model before you merge. Try it here and see what you've been missing.

K
Written by
Kryotta Team
Product & research

Kryotta is the multi-model AI workspace — every leading model, one login, one bill. Try it free →

Related reading