Tôi bắt đầu dùng checklist này sau một tuần rất khó chịu: ba PR đều “gần đúng”, cả ba đều do AI coding tăng tốc, và cả ba đều tốn review hơn làm tay. Không có lỗi nào lớn. Nhưng cộng lại là một pattern: assistant sửa rộng hơn ticket, thêm fallback không cần thiết, viết test chỉ assert render, và deploy note nghe hay nhưng không nói đã smoke gì. Từ đó tôi gom lại thành anti-pattern checklist trước khi ship.

Checklist này không nhằm làm chậm AI coding. Nó bắt lỗi AI coding tạo ra rất thường xuyên: output sạch nhưng sai ngữ cảnh.

1. AI chưa đọc code đã sửa

Dấu hiệu:

  • Assistant tạo file mới trong khi project đã có helper.
  • Gọi endpoint bằng đường dẫn đoán.
  • Tự dựng mock data.
  • Không nhắc tới file hiện hữu liên quan.

Cách chặn: bắt đầu bằng orientation. Yêu cầu AI liệt kê files, hooks, endpoints, config, unknowns trước khi edit. Nếu nó không chỉ ra được source of truth, chưa cho sửa.

Prompt tốt:

Read existing implementation first.
Do not edit files yet.
Find the current hook/API/helper for this behavior.
Return files and unknowns.

Anti-pattern này là gốc của rất nhiều lỗi sau. AI có thể viết code đẹp, nhưng nếu nó viết vào architecture tưởng tượng, diff đó không đáng tin.

2. Scope creep trong diff

Dấu hiệu:

  • Ticket yêu cầu thêm filter, diff đổi cả layout.
  • Sửa bug nhỏ, diff rename nhiều component.
  • Thêm abstraction mới cho một case duy nhất.
  • Format lại file lớn không liên quan.

AI thích làm code “gọn hơn”. Trong feature branch gần deploy, gọn hơn không phải lúc nào cũng tốt hơn. Scope creep làm review khó, rollback khó, và tăng xác suất bug phụ.

Câu hỏi review:

Nếu rollback change này, có phần unrelated nào cũng bị rollback không?

Nếu câu trả lời là có, diff quá rộng. Tách refactor ra sau. Ship feature trước.

3. Mock data lọt vào feature thật

Dấu hiệu:

  • const mockOrders = [...]
  • setTimeout giả API.
  • UI pass nhưng network tab không có request thật.
  • Preview URL nhìn đúng nhưng staging data không liên quan.

Mock data có chỗ dùng trong prototype. Nhưng trong product code, nhất là feature chuẩn bị deploy, mock data là thuốc mê. Nó làm reviewer tưởng feature chạy trong khi API contract chưa được test.

Rule thực dụng:

  • Nếu endpoint/hook đã tồn tại, reuse.
  • Nếu không tìm thấy, dừng và hỏi.
  • Không tự tạo fake endpoint để “hoàn thành UI”.

Feature dùng mock data có thể nhìn xong trong 30 phút nhưng tốn hai ngày khi nối API thật. Đừng gọi đó là progress.

4. Endpoint hoặc contract bị bịa

Dấu hiệu:

  • AI gọi /api/v1/orders/status dù repo không có route đó.
  • Payload field dùng camelCase trong khi backend cần snake_case.
  • Enum value viết theo label UI, không theo API.
  • Error handling assume shape không tồn tại.

Contract phải được chứng minh từ code, docs nội bộ, generated client, hoặc network call thật. Không chấp nhận “likely”. Với AI coding, chữ “likely” trong API contract là cảnh báo đỏ.

Review nhanh:

rg "useOrders" src
rg "status" src/features/orders
rg "order_status" src

Tinh thần là vậy: tìm source thật. Nếu không có source, hỏi người giữ API.

5. Test có mặt nhưng không bắt behavior

Dấu hiệu:

  • Test chỉ render component.
  • Snapshot lớn, khó đọc.
  • Assert text tĩnh, không assert action.
  • Không test URL/query/state edge case.
  • Test mock hook theo đúng output mong muốn nên không kiểm tra integration.

AI viết test rất nhanh, nhưng nhiều test chỉ làm coverage đẹp. Test tốt phải fail nếu bug thật xảy ra.

Ví dụ với status filter, test yếu:

renders status filter

Test tốt:

selecting Refunded updates URL to status=refunded and calls useOrders with refunded

Nếu không có test infra phù hợp, đừng để AI dựng test giả. Viết manual smoke checklist rõ còn tốt hơn test rỗng.

6. Error handling cho scenario không có thật

Dấu hiệu:

  • Thêm nhiều fallback không ai yêu cầu.
  • Catch error rồi swallow.
  • Return empty array khi API fail, làm user tưởng không có data.
  • Hiển thị generic message thay vì giữ existing behavior.

AI hay thêm error handling để code trông robust. Nhưng error handling sai có thể che lỗi production. Với app vận hành, fail rõ thường tốt hơn fail im lặng.

Rule của tôi: chỉ thêm error handling nếu ticket yêu cầu, existing pattern có sẵn, hoặc code path thật sự có lỗi cần xử lý. Trong try/catch, log error bằng console.error() nếu project rule yêu cầu, nhưng đừng để lại debug logs lung tung.

7. Import và file naming lệch convention

Dấu hiệu:

  • Tạo index.tsx barrel file dù project không dùng.
  • Import relative qua nhiều cấp trong khi project dùng alias.
  • Component filename không PascalCase.
  • Hook không camelCase.
  • Duplicate imports từ cùng module.

Những lỗi này không làm production cháy, nhưng làm codebase rối nhanh. AI thường học convention từ generic React project, không phải repo hiện tại. Vì vậy local rules quan trọng. Trước khi ship, scan file mới và imports. Nếu thấy index.ts, hỏi lại có thật cần không. Thường là không.

8. Diff chứa debug artifact

Dấu hiệu:

  • console.log
  • Comment kiểu “TODO: remove this”
  • Temporary CSS outline.
  • Hardcoded test ID hoặc user ID.
  • Local URL như http://localhost:3000.

Debug artifact là lỗi vệ sinh cơ bản, nhưng AI coding làm nó xuất hiện nhiều hơn vì assistant thêm log để tự kiểm tra rồi quên xoá. Trước khi ship, chạy search:

console.log
debugger
localhost
TODO: remove
mock

Không xoá mọi TODO mù quáng. Nhưng debug artifact trong files touched phải được giải thích hoặc loại bỏ.

9. PR summary thay cho bằng chứng

Dấu hiệu:

  • “Tested locally” nhưng không nói test gì.
  • “All checks pass” nhưng CI chưa chạy xong.
  • “No breaking changes” dù có API payload đổi.
  • Summary nói chỉ UI, diff có API change.

AI viết PR summary rất mượt. Đừng để độ mượt thay bằng evidence. PR tốt cần changed behavior, files touched ở mức cao, test thật, risk còn lại.

Mẫu ngắn:

Summary:
- Added Orders status filter using existing useOrders status param.
- Synced filter with `status` query param.

Testing:
- Selected Refunded on preview and confirmed ORD-1009 appears.
- Refreshed `?status=refunded` and confirmed filter persists.
- Selected All and confirmed `status` param is removed.

Đọc lên hơi khô, nhưng reviewer dùng được.

10. Deploy không có rollback point

Dấu hiệu:

  • “Merge xong deploy luôn.”
  • Không biết production đang chạy commit nào.
  • Không biết previous artifact ID.
  • Không có owner online sau deploy.
  • Smoke test chỉ là “site lên”.

Đây là anti-pattern nguy hiểm nhất ở cuối workflow. AI coding làm bạn ship nhiều hơn, nghĩa là rollback phải tốt hơn.

Trước deploy, trả lời bốn câu:

  • Artifact nào sẽ deploy?
  • Ai đã nhìn preview?
  • Smoke production bằng path nào?
  • Rollback về đâu?

Nếu không trả lời được, chưa deploy. Với change high risk, thêm câu thứ năm: migration rollback hoặc mitigation là gì?

11. Incident bắt đầu bằng thêm code

Dấu hiệu:

  • Production có lỗi, phản xạ đầu tiên là prompt AI “fix”.
  • Chưa xác nhận impact.
  • Chưa freeze deploy.
  • Chưa check latest artifact.
  • Không có timeline.

Incident cần restore trước, root cause sau. AI có thể đọc log và diff, nhưng đừng để nó kéo bạn vào hotfix khi rollback an toàn hơn.

Incident flow tối thiểu:

1. Freeze unrelated deploys.
2. Confirm symptom and impact.
3. Check latest deploy artifact.
4. Rollback if safe.
5. Smoke symptom.
6. Record timeline.
7. Investigate root cause.

Nếu team chỉ nhớ một phần của checklist này, nhớ phần freeze. Nhiều incident tệ lên không phải vì bug ban đầu, mà vì nhiều người cùng sửa trong lúc chưa biết chuyện gì xảy ra.

12. AI được tin vì nói tự tin

Dấu hiệu:

  • “The issue is likely fixed” được xem như done.
  • Reviewer đọc explanation, không đọc diff.
  • Assistant nói test pass nhưng không có command output.
  • Assistant nói endpoint tồn tại nhưng không dẫn file.

AI confidence không phải evidence. Evidence là diff, command output, preview, log, test result, screenshot, hoặc data record cụ thể. Trong workflow tốt, assistant có thể nói tự tin hay không không quan trọng. Nó phải đưa bằng chứng kiểm được.

Câu hỏi đơn giản:

Bạn biết điều đó từ file/log/test nào?

Nếu không trả lời được, đó là assumption.

Checklist ngắn trước khi ship

Đây là bản tôi muốn nhìn trước merge/deploy:

Code
- AI đã đọc existing files trước khi sửa.
- Diff chỉ đụng scope ticket.
- Không mock data, không endpoint bịa.
- Không debug logs/artifacts.
- Naming/imports theo convention repo.

Behavior
- Default state đúng.
- Edge case chính đã test.
- URL/state/API contract đúng.
- Existing flow liên quan không vỡ.

Review
- PR summary có evidence, không chỉ claim.
- Test hoặc manual smoke cụ thể.
- Unknowns được ghi rõ.

Deploy
- Preview URL đã nhìn.
- Rollback point đã biết.
- Production smoke path đã ghi.
- Owner online sau deploy.

Checklist này không cần tool đặc biệt. Có thể nằm trong PR template, ticket, hoặc comment trước merge. Nó buộc bạn chuyển từ “AI đã làm” sang “hệ thống đã được kiểm”.

AI coding hữu ích nhất khi nó được đặt trong một workflow biết nghi ngờ đúng chỗ. Không nghi ngờ mọi thứ, vì như vậy mất tốc độ. Chỉ nghi ngờ những điểm AI hay sai: context, scope, contract, evidence, deploy. Bắt được năm điểm đó, bạn vẫn ship nhanh, nhưng ít phải thức đêm vì một diff nhìn rất đẹp.