Usecase: Team Debug Production Bug Hệ Thống Thanh Toán
⚠️ Lưu ý: Đây là usecase giả định nhằm minh họa cách sử dụng. Kết quả AI trả lời trong thực tế có thể khác so với ví dụ bên dưới.
Khi một bug thanh toán lọt lên production, phản ứng tự nhiên là sửa nhanh nhất có thể. Superpowers dạy bạn cách chậm lại đúng lúc để sửa đúng cách -- có hệ thống, có bằng chứng, có review.
Bối Cảnh
Hãy tưởng tượng bạn đang làm việc trong một team nhỏ 2-3 dev, quản lý hệ thống e-commerce. Một ngày, team nhận được báo cáo từ khách hàng:
"Tôi mua sản phẩm giảm giá 20%, dùng voucher 10% nhưng giá không đúng. Tôi bị tính nhiều hơn mức giá tôi kỳ vọng."
Sau khi kiểm tra, bạn phát hiện:
- Sản phẩm: Áo thun giá gốc 500,000đ, giảm giá 20%
- Voucher: SAVE10, giảm 10%
- Expected: 500,000 x 0.8 = 400,000 -> 400,000 x 0.9 = 360,000đ
- Actual: Hệ thống tính ra 350,000đ
Chênh lệch 10,000đ. Khách hàng bị tính thiếu, nhưng logic sai có thể gây chênh lệch lớn hơn với các sản phẩm giá cao hoặc voucher lớn hơn.
Tech stack: Node.js, TypeScript, hàm calculateFinalPrice()
Bạn Sẽ Học Được Gì
Qua usecase này, bạn sẽ thực hành:
- Systematic Debugging 4 Phases -- quy trình debug có hệ thống thay vì đoán mò (xem thêm Debug & Xác Minh)
- TDD Fix -- viết test tái hiện bug TRƯỚC khi sửa (xem thêm TDD)
- Code Review hai chiều -- người gửi chuẩn bị context, người review đọc kỹ trước khi phản hồi (xem thêm Code Review)
- Verification Gate -- chỉ tuyên bố "đã fix" khi có bằng chứng rõ ràng (xem thêm Debug & Xác Minh)
Từng Bước Thực Hành
Bước 1: Phase 1 -- Điều Tra Nguyên Nhân Gốc
Trước khi sửa bất kỳ dòng code nào, bạn cần hiểu đầy đủ vấn đề. Không được phép đoán mò.
1.1. Đọc báo cáo lỗi từ khách hàng
Khách hàng gửi feedback:
"Tôi mua sản phẩm Áo thun giá 500,000đ, trang sản phẩm ghi giảm giá 20%. Tôi áp dụng voucher SAVE10 giảm thêm 10%. Tôi kỳ vọng trả 360,000đ nhưng hệ thống tính 350,000đ."
🧑 Người dùng cung cấp cho AI nội dung báo cáo lỗi từ khách hàng. Ghi lại chính xác các con số — không diễn giải lại, làm việc với dữ liệu gốc. Ví dụ prompt:
"Khách hàng báo bug thanh toán: mua Áo thun 500,000đ giảm 20%, dùng voucher SAVE10 giảm 10%, kỳ vọng 360,000đ nhưng hệ thống tính 350,000đ. Hãy giúp tôi debug theo quy trình systematic."
🤖 AI nhận báo cáo, ghi nhận các con số cụ thể (giá gốc, % giảm, voucher, expected vs actual). AI không đoán nguyên nhân ngay mà bắt đầu quy trình điều tra có hệ thống.
1.2. Tái hiện lỗi
🤖 AI đọc file src/utils/pricing.ts — hàm calculateFinalPrice() nhận Product (có discountPercent) và Voucher (tùy chọn, có discountPercent), trả về giá sau giảm. Thoạt nhìn, logic trông có vẻ đúng: áp dụng product discount trước, rồi voucher sau. Nhưng đây là code AI nghĩ đang chạy. AI tiếp tục kiểm tra code thực tế trên production.
🧑 Người dùng quan sát AI đọc code và xác nhận đây là file/hàm đúng cần kiểm tra. Nếu AI đọc sai file, hãy chỉnh hướng.
1.3. Kiểm tra thay đổi gần đây
🤖 AI chạy git log để xem các commit gần đây:
git log --oneline -10
Kết quả:
a1b2c3d feat: add loyalty points calculation
f4e5d6a refactor: simplify discount calculation <-- ĐÂY RỒI
b7c8d9e fix: update shipping fee for remote areas
...
🤖 AI nhận ra commit f4e5d6a với message "refactor: simplify discount calculation" rất đáng nghi, và kiểm tra diff:
git diff f4e5d6a~1..f4e5d6a -- src/utils/pricing.ts
🧑 Người dùng xem kết quả git log cùng AI. Nếu biết thêm context (ví dụ: "commit đó là của dev mới, tuần trước merge vào"), hãy cung cấp cho AI để thu hẹp phạm vi điều tra.
1.4. Phát hiện code thực tế (code lỗi)
🤖 AI kiểm tra diff của commit f4e5d6a và phát hiện code thực tế trên production đã bị thay đổi: thay vì áp dụng discount tuần tự (giá x 0.8 rồi x 0.9), người refactor đã cộng dồn phần trăm (20% + 10% = 30%) rồi áp dụng một lần (giá x 0.7). AI báo cáo phát hiện cho người dùng.
🧑 Người dùng đọc phân tích của AI và xác nhận: "Đúng rồi, logic business đúng phải là áp dụng tuần tự." Nếu business rule khác (ví dụ cộng dồn mới đúng), hãy nói rõ để AI điều chỉnh hướng điều tra.
Vấn đề: Đây là lỗi logic — "đơn giản hóa" đã thay đổi kết quả tính toán.
1.5. Theo dõi luồng dữ liệu
🤖 AI trace luồng tính toán với cả hai cách, trình bày rõ ràng cho người dùng:
Với code lỗi (cộng dồn):
totalDiscount = 20 + 10 = 30
price = 500,000 * (1 - 30/100)
price = 500,000 * 0.7
price = 350,000đ
Còn logic đúng (tuần tự):
price = 500,000 * (1 - 20/100) = 500,000 * 0.8 = 400,000
price = 400,000 * (1 - 10/100) = 400,000 * 0.9 = 360,000đ
Chênh lệch: 360,000 - 350,000 = 10,000đ. 🤖 AI cảnh báo: với sản phẩm giá cao hơn hoặc voucher lớn hơn, chênh lệch sẽ lớn hơn nhiều.
🧑 Người dùng xác nhận phép tính của AI đúng và đồng ý với kết luận. Đây là checkpoint quan trọng — đảm bảo cả hai bên thống nhất về nguyên nhân trước khi tiến hành bước tiếp theo.
Lưu ý: Ở bước này bạn chỉ điều tra, chưa sửa gì cả. Bằng chứng trước lý thuyết.
Bước 2: Phase 2 -- Phân Tích Mô Hình
Khi đã tái hiện bug, hãy tìm kiếm các mô hình.
2.1. Tìm các ví dụ hoạt động đúng
🤖 AI tự động kiểm tra nhiều trường hợp khác nhau để xác định khi nào bug xuất hiện và khi nào không:
Trường hợp 1: Chỉ có product discount (không có voucher)
Input: product = { price: 500000, discountPercent: 20 }, no voucher
Code: totalDiscount = 20, price = 500000 * 0.8 = 400,000
Result: 400,000đ -- ĐÚNG
Trường hợp 2: Chỉ có voucher (product không giảm giá)
Input: product = { price: 300000, discountPercent: 0 }, voucher = { discountPercent: 10 }
Code: totalDiscount = 0 + 10 = 10, price = 300000 * 0.9 = 270,000
Result: 270,000đ -- ĐÚNG
Trường hợp 3: Cả hai discount cùng lúc
Input: product = { price: 500000, discountPercent: 20 }, voucher = { discountPercent: 10 }
Code: totalDiscount = 20 + 10 = 30, price = 500000 * 0.7 = 350,000
Result: 350,000đ -- SAI (expected 360,000đ)
🧑 Người dùng xem qua các trường hợp AI liệt kê. Nếu có trường hợp đặc biệt mà AI chưa xét (ví dụ: "Hệ thống còn có loại discount thứ 3 cho khách VIP"), hãy bổ sung để AI phân tích thêm.
2.2. So sánh và kết luận mô hình
🤖 AI tổng hợp kết quả và rút ra mô hình: bug chỉ xuất hiện khi CẢ HAI discount được áp dụng đồng thời. AI giải thích lý do toán học:
- Cộng dồn:
price * (1 - (a + b) / 100) - Tuần tự:
price * (1 - a/100) * (1 - b/100)
Hai biểu thức này KHÔNG tương đương về mặt toán học (trừ khi a hoặc b bằng 0).
🧑 Người dùng xác nhận mô hình AI đưa ra có khớp với hành vi thực tế hệ thống. Nếu có thêm báo cáo lỗi từ khách hàng khác, cung cấp cho AI để cross-check.
Bước 3: Phase 3 -- Giả Thuyết và Kiểm Tra
3.1. Phát biểu giả thuyết rõ ràng
🤖 AI phát biểu giả thuyết một cách rõ ràng, có cấu trúc:
Giả thuyết: Bug xảy ra vì hàm
calculateFinalPrice()cộng dồn phần trăm giảm giá (20% + 10% = 30%) thay vì áp dụng tuần tự (giá x 0.8 x 0.9). Commitf4e5d6a("refactor: simplify discount calculation") đã refactor logic từ áp dụng tuần tự sang cộng dồn.
🧑 Người dùng đọc giả thuyết và đánh giá xem có hợp lý không. Nếu đồng ý, xác nhận để AI tiến hành kiểm chứng. Nếu không đồng ý hoặc có giả thuyết khác, hãy nêu ra. Viết ra giấy hoặc ghi vào comment — không để giả thuyết chỉ tồn tại trong đầu.
3.2. Kiểm tra một biến tại một thời điểm
🤖 AI thêm console.log vào hàm calculateFinalPrice() để trace từng bước tính toán, sau đó chạy với input từ báo cáo khách hàng:
[DEBUG] Initial price: 500000
[DEBUG] Product discount: 20
[DEBUG] Voucher discount: 10
[DEBUG] Total discount (cộng dồn): 30
[DEBUG] Final price: 350000
🤖 AI trình bày kết quả debug cho người dùng, chỉ rõ dòng nào chứng minh giả thuyết.
🧑 Người dùng xem output debug và đối chiếu với dữ liệu từ báo cáo khách hàng. Xác nhận kết quả khớp với hành vi lỗi được báo cáo.
3.3. Xác nhận giả thuyết bằng con số cụ thể
🤖 AI tạo bảng so sánh với nhiều bộ input khác nhau để chứng minh mức độ ảnh hưởng của bug:
| Trường hợp | Cộng dồn (bug) | Tuần tự (đúng) | Chênh lệch |
|---|---|---|---|
| 500k, 20% + 10% voucher | 350,000 | 360,000 | 10,000 |
| 1,000k, 30% + 15% voucher | 550,000 | 595,000 | 45,000 |
| 2,000k, 50% + 20% voucher | 600,000 | 800,000 | 200,000 |
Chênh lệch tăng theo giá sản phẩm và mức giảm giá. 🤖 AI kết luận: giả thuyết được xác nhận.
🧑 Người dùng review bảng so sánh, đánh giá mức độ nghiêm trọng của bug dựa trên dữ liệu thực tế (ví dụ: "Sản phẩm đắt nhất của mình là 5 triệu, vậy chênh lệch tối đa có thể lên tới..."). Quyết định mức độ ưu tiên fix.
Bước 4: Phase 4 -- TDD Fix
Bây giờ bạn đã biết chính xác nguyên nhân. Thay vì lao vào sửa code, hãy làm đúng quy trình TDD: viết test trước, sửa code sau.
🤖 AI hỏi trước khi hành động: "Giả thuyết đã được xác nhận: bug do cộng dồn phần trăm thay vì áp dụng tuần tự. Bạn có đồng ý để tôi tiến hành fix theo quy trình TDD — viết test tái hiện bug trước, sửa code sau?"
🧑 Người dùng xác nhận: "Đồng ý, tiến hành."
RED: Viết Test Thất Bại Tái Hiện Bug
🤖 AI tạo file src/utils/__tests__/pricing.test.ts với 5 test cases:
- Áp dụng cả product discount và voucher tuần tự (expected 360,000)
- Chỉ có product discount (expected 400,000)
- Chỉ có voucher trên sản phẩm không giảm giá (expected 270,000)
- Không có discount nào (expected 200,000)
- Làm tròn số với giá lẻ (expected 263,500)
🤖 AI chạy npm test -- --grep "calculateFinalPrice" → 2 FAIL, 3 PASS. Test 1 thất bại đúng như dự đoán: expected 360,000 nhưng received 350,000. Test 5 cũng thất bại vì logic cộng dồn tính sai.
Các test 2, 3, 4 pass vì chúng chỉ có một loại discount, nên cộng dồn và tuần tự cho kết quả giống nhau.
🧑 Người dùng review danh sách test cases — bổ sung nếu thiếu trường hợp đặc biệt của hệ thống (ví dụ: "Còn trường hợp khách VIP được giảm thêm 5% nữa").
GREEN: Sửa Hàm Để Tất Cả Test Pass
🤖 AI sửa src/utils/pricing.ts — khôi phục logic áp dụng discount tuần tự: product discount trước, voucher discount sau (trên giá đã giảm). Chạy lại test → 5/5 PASS.
🧑 Người dùng đọc diff code fix, xác nhận logic đúng với business rule của hệ thống.
REFACTOR: Thêm Guard Clause
🤖 AI thêm validation cho edge case trong src/utils/pricing.ts: price không âm, discount trong khoảng 0-100. Thêm 2 test cases cho guard clause vào file test. Chạy lại toàn bộ test suite → tất cả pass, không có regression.
🧑 Người dùng review guard clause — xác nhận các giới hạn validation phù hợp với quy định business (ví dụ: discount có thể lên 100% không, hay tối đa 80%?).
Bước 5: Code Review Hai Chiều
Bug đã được fix và test đã pass. Nhưng trước khi merge, cần code review.
Dev A (người fix) gửi review request
🧑 Người dùng yêu cầu AI tạo PR. 🤖 AI tạo pull request với thông tin có cấu trúc đầy đủ:
## WHAT
Fix bug tính giá sai khi áp dụng đồng thời product discount và voucher discount.
## ROOT CAUSE
Commit f4e5d6a ("refactor: simplify discount calculation") đã thay đổi logic
từ áp dụng tuần tự sang cộng dồn phần trăm giảm giá.
Cộng dồn: 500000 * (1 - (20+10)/100) = 350,000 (SAI)
Tuần tự: 500000 * 0.8 * 0.9 = 360,000 (ĐÚNG)
## PLAN
- Khôi phục logic áp dụng discount tuần tự
- Thêm 5 test cases bao phủ các trường hợp: cả hai discount, chỉ product,
chỉ voucher, không discount, và làm tròn số
- Thêm guard clause cho input validation
## CHANGES
- src/utils/pricing.ts: sửa hàm calculateFinalPrice()
- src/utils/__tests__/pricing.test.ts: thêm 7 test cases
## BASE_SHA -> HEAD_SHA
f4e5d6a -> g7h8i9j
Lưu ý: Dev A cung cấp đầy đủ context để Dev B có thể review hiệu quả. Người gửi có trách nhiệm giúp người review hiểu vấn đề.
Dev B (reviewer) review theo quy trình
🧑 Dev B (hoặc AI của Dev B) không vội phản hồi. Thay vào đó, thực hiện quy trình 5 bước:
1. READ -- Đọc toàn bộ PR description và diff
2. UNDERSTAND -- Hiểu vấn đề và cách fix
Dev B tự tính toán lại:
Cộng dồn: 500000 * (1 - 30/100) = 500000 * 0.7 = 350,000
Tuần tự: 500000 * 0.8 * 0.9 = 400000 * 0.9 = 360,000
Xác nhận: phép tính của Dev A là đúng.
3. VERIFY -- Kiểm tra code và test
Dev B đọc code fix, đọc từng test case, xác nhận mỗi test case là có ý nghĩa và đúng.
4. EVALUATE -- Đánh giá edge case
Dev B đặt câu hỏi:
- Nếu tổng discount vượt 100% thì sao? (Đã xử lý bằng guard clause)
- Nếu price = 0 thì sao? (0 * bao nhiêu cũng = 0, ok)
- Nếu voucher.discountPercent = 0 thì sao? (price * 1 = price, ok)
- Có ảnh hưởng đến các hàm khác không? (Kiểm tra các caller của calculateFinalPrice)
5. RESPOND -- Phản hồi cụ thể, có xây dựng
Dev B không viết:
"Looks good! LGTM"
Dev B viết:
## Review: Fix calculateFinalPrice
### Đã xác nhận
- Logic áp dụng tuần tự là đúng. Tôi đã tự tính lại với 3 bộ input khác nhau.
- Test cases bao phủ đầy đủ các trường hợp cơ bản.
- Guard clause cho input validation là hợp lý.
### Góp ý
1. Nên thêm test case cho trường hợp voucher.discountPercent = 0
để đảm bảo nó không ảnh hưởng giá.
2. Cần kiểm tra hàm `applyPromotion()` ở file promotion.ts --
hàm này cũng gọi calculateFinalPrice() và có thể có logic
tương tự cần sửa.
3. Nên thêm comment giải thích tại sao áp dụng tuần tự chứ không
cộng dồn, để tránh người khác lại "simplify" trong tương lai.
### Kết luận
Approve với 3 góp ý trên. Góp ý 2 nên kiểm tra trước khi merge.
Dev A phản hồi
Dev A đọc góp ý và xử lý:
- Thêm test case cho voucher.discountPercent = 0 -- Done
- Kiểm tra hàm
applyPromotion()-- xác nhận hàm này chỉ gọicalculateFinalPrice()và không có logic discount riêng -- Không cần sửa - Thêm comment giải thích -- Done
Dev A thêm comment giải thích vào hàm calculateFinalPrice() — ghi rõ lý do áp dụng tuần tự chứ không cộng dồn, để tránh người khác lại "simplify" trong tương lai. Push commit mới và reply xác nhận đã xử lý cả 3 góp ý.
Bước 6: Verification Gate
Trước khi tuyên bố bug đã được fix, áp dụng quy trình xác minh 5 bước.
🧑 Người dùng yêu cầu: "Chạy verification đầy đủ trước khi merge."
1. XÁC ĐỊNH -- Test nào cần chạy
🤖 AI liệt kê danh sách test cần chạy:
- Unit tests cho calculateFinalPrice: 7 test cases
- Integration tests cho checkout flow: 3 test cases
- Regression test suite: toàn bộ
🧑 Người dùng bổ sung nếu cần (ví dụ: "Chạy thêm e2e test cho checkout page nữa").
2. CHẠY -- Thực thi test
🤖 AI chạy toàn bộ test:
# Unit tests
npm test -- --grep "calculateFinalPrice"
# Integration tests
npm test -- --grep "checkout"
# Full regression
npm test
3. ĐỌC -- Đọc kết quả từng dòng
🤖 AI đọc và trình bày kết quả:
Test Suites: 24 passed, 24 total
Tests: 187 passed, 187 total
Snapshots: 0 total
Time: 12.34s
Tất cả 187 test pass. Không có regression.
4. XÁC NHẬN -- Đối chiếu kết quả
🤖 AI tổng hợp checklist xác nhận:
- 7 test cases cho calculateFinalPrice: PASS
- 3 integration tests cho checkout flow: PASS
- 187 test tổng cộng: PASS
- Không có test nào bị skip hoặc pending
🧑 Người dùng kiểm tra thủ công trên staging environment với chính xác input từ báo cáo khách hàng:
- Sản phẩm 500,000đ, giảm 20%, voucher 10%
- Kết quả: 360,000đ -- ĐÚNG
5. TUYÊN BỐ -- Kết luận có bằng chứng
🤖 AI đưa ra kết luận dựa trên bằng chứng:
Bug đã được fix. Hàm
calculateFinalPrice()đã được sửa từ cộng dồn discount sang áp dụng tuần tự. Verified bằng 7 unit test, 3 integration test, và kiểm tra thủ công trên staging. Không có regression. Sẵn sàng deploy lên production.
🧑 Người dùng xác nhận lần cuối và approve merge/deploy.
Kết Quả
Sau khi áp dụng quy trình Superpowers, team đã đạt được:
- Bug được fix đúng cách -- không phải hotfix tạm thời mà là fix có hệ thống, có bằng chứng
- 7 test cases được thêm -- ngăn bug này quay lại trong tương lai
- Team học được quy trình debug -- từ reaction mode ("sửa nhanh nhất có thể") sang systematic mode ("sửa đúng nhất có thể")
- Comment được thêm vào code -- người tiếp theo đọc sẽ hiểu tại sao logic phải là tuần tự, không ai dám "simplify" lại
Tổng thời gian: khoảng 2-3 giờ cho toàn bộ quy trình. Có vẻ lâu hơn việc "sửa nhanh", nhưng:
- Không có khả năng bug quay lại
- Không có khả năng tạo thêm bug mới từ việc sửa vội
- Team có test để tự tin refactor trong tương lai
Key Takeaways
1. Không bao giờ đoán mò khi debug
Tuân theo 4 giai đoạn có hệ thống: Điều tra -> Phân tích mô hình -> Giả thuyết -> TDD Fix. Mỗi giai đoạn có output cụ thể trước khi chuyển sang giai đoạn tiếp theo.
2. git log là bạn
Commit "refactor: simplify discount calculation" chính là nguyên nhân. Thói quen chạy git log --oneline -10 và git diff trước khi đoán nguyên nhân sẽ giúp bạn tiết kiệm hàng giờ debug sai hướng.
3. Viết test tái hiện bug TRƯỚC khi fix
Test là bằng chứng bug tồn tại. Khi test thất bại (RED), bạn có bằng chứng. Khi test pass sau khi fix (GREEN), bạn có bằng chứng bug đã được sửa. Không có test = không có bằng chứng.
4. Code review hai chiều
- Người gửi: Chuẩn bị context đầy đủ (WHAT, ROOT CAUSE, PLAN, CHANGES). Giúp người review hiểu vấn đề nhanh chóng.
- Người review: Đọc kỹ trước khi phản hồi. Không viết "LGTM" nếu chưa thực sự kiểm tra. Góp ý cụ thể, có xây dựng.
5. Evidence before claims
Chỉ tuyên bố "đã fix" khi có bằng chứng verification rõ ràng: test pass, không có regression, kiểm tra thủ công thành công. Một lời tuyên bố không có bằng chứng là một lời hứa không có bảo đảm.
Tham Khảo
- Debug & Xác Minh -- Quy trình debug 4 giai đoạn đầy đủ
- TDD -- Chu kỳ RED-GREEN-REFACTOR
- Code Review -- Quy trình review hai chiều
- Iron Laws -- Các quy tắc bất khả xâm phạm của Superpowers