Lifestyle & Setup • 10 min read • 07/20/2026

Dev Tool Stack 2026: From Cursor and Claude Code to an AI-Assisted Code Review Workflow

Bài này có bản tiếng Việt. Đọc bản tiếng Việt →

Nguyen Hai Trinh

Nguyen Hai Trinh • Senior Software Engineer @ SmileViet

A developer's desk
Photo: Kskhh · CC BY-SA 4.0

A junior once asked me: do you still write code yourself, or do you hand it all to AI? I still write it. Just a lot less.

Over the past two or three years my day has shifted a lot. From typing every line by hand to making decisions, reviewing, and steering agents. The hard part isn’t picking tools. It’s drawing the line: what goes to AI, and what I keep.

The daily kit

Cursor is my main editor for most interactive coding. I need the full context of the codebase, diffs I can see right there, and the ability to go back and forth within one session. What I like most about Cursor is that it understands context across many files at once, so I don’t have to describe it again by hand every time I ask.

Claude Code plays a very different role. It’s where I hand off well-scoped tasks, running in the terminal, and it can run in the background while I work on something else. For example: writing tests for a module, refactoring a chunk of code to a new convention, or researching an unfamiliar part of the codebase before I start changing it. It gets to use tools (read files, run commands, run tests), so it can verify its own work before reporting back. Very different from guessing at code and handing it to me.

Gemini CLI is for tasks that need a very large context window. Reading an entire large service to summarize its architecture. Cross-checking several long log files to find unusual patterns. Not a daily tool. But when I need to swallow a huge amount of information in one go, nothing else replaces it.

My PR review process before merging

Before a PR gets merged, I go through exactly three steps.

  1. AI review first: run an automated review pass focused on logic errors, missed edge cases, and patterns inconsistent with the rest of the codebase. A quick filter. Most obvious errors get caught here, the ones I’m likely to miss because I’m too used to the code I just wrote.
  2. Re-read it myself: read the whole diff once more, paying closest attention to anything touching money, customer data, or schema changes. I never skip this step, no matter what the AI said in step one.
  3. Peer review with a teammate: for high-risk changes (migrations, API contract changes, payment logic) another person on the team still has to sign off. AI can’t replace human accountability for a production change.

Those three steps sit in a straight line, and I don’t skip any of them.

flowchart TD
    A["PR opened"] --> B["1. Automated AI review<br/>logic errors, edge cases, inconsistent patterns"]
    B --> C["2. Re-read the whole diff myself<br/>money, customer data, schema"]
    C --> D{"High risk?<br/>migration, API contract, payments"}
    D -->|Yes| E["3. Peer review with a teammate"]
    D -->|No| F["Merge"]
    E --> F

I treat AI as a very diligent reviewer that lacks business context. It can point out “this section is missing null handling”. It doesn’t know that field is allowed to be null when a customer books a tour as a group and hasn’t picked all the members yet. Bugs get found faster, for real. But final responsibility still sits with whoever presses merge.

What AI runs on its own, and what I do by hand

I think this is the most important part. It’s also the part most easily abused without clear discipline.

Hand more to AI:

  • Writing test cases for logic that already exists and is clear: pure functions, no complex side effects.
  • Syntax refactors, renaming variables, standardizing code style to an agreed convention.
  • Writing docs, READMEs, and explanatory comments for old code that has none.
  • Research, and reading through an unfamiliar part of the codebase before I change it myself.

Keep tight hands-on control, and limit what AI decides on its own:

  • Logic that touches money: price calculation, applying promotions, handling refunds, payment reconciliation.
  • Race conditions, concurrency, transaction boundaries in the database. This class of bug is extremely hard to spot in a quick review, and the consequences are heavy. I have two separate posts on cache invalidation and payment race conditions.
  • Production schema changes or migrations that run on real data. Always write them myself, review every line of SQL myself, and never let an agent run a migration against an environment with real data.
  • Architecture decisions with long-term impact: picking patterns, picking technologies. AI can propose options. The decision is still mine, because I’m the one maintaining it two years from now.

The two lists look clean, but the boundary between them is blurrier than it seems.

flowchart LR
    T["Task to do"] --> Q{"Touches money, schema,<br/>concurrency or long-term architecture?"}
    Q -->|No| AI["Hand to AI<br/>tests, refactors, docs, research"]
    Q -->|Yes| HAND["Write and review it myself"]
    AI --> CK["Agent verifies itself<br/>tests, type-check, build"]
    CK --> PR["Small PR, reviewable in one read"]
    HAND --> PR

The one thing I never give up: any action that can cause damage (deleting data, deploying, migrating) must have a pause where a human confirms before it executes.

Habits when working with agents

  • Define the scope clearly before handing off a task. A vague task like “make it better” always ends in a rambling result, with the agent refactoring parts nobody asked about.
  • Ask the agent to verify itself before reporting results (run tests, run the type-check, try a build) instead of taking the code and trusting it blindly.
  • Keep tasks small enough to review in one read. When an AI-generated PR is too large, the reviewer can’t review it carefully, which means a shallow review and missed bugs.
  • Save important context as text: READMEs, comments, notes on architecture decisions. So the agent doesn’t have to guess from scratch next time, and so I don’t forget, a few months on, the reason behind a decision.
  • Never let an agent decide on its own what needs user confirmation.

The toolset, and what’s still missing

The current toolset lets me get more done in the same amount of time. The nature of the work hasn’t changed: understand the problem correctly, make the right decision, and take responsibility for that decision.

AI works best when it’s given well-scoped work and checked carefully. The button that produces correct code with nobody reviewing it again still doesn’t exist. I don’t see it coming soon either.

Need a developer for a contract or freelance project?

I take on fullstack projects — Go backends, React/Next.js frontends, or both ends. Send a few lines about the scope and timeline and I'll reply within 48 hours.