Tech debt = vay tiền
| Tài chính | Code | Khi nào OK |
|---|---|---|
| Vay mua nhà | Hardcode config, skip test để ship nhanh | ✅ Khi cần ship deadline, có kế hoạch trả |
| Thẻ tín dụng | Copy-paste code, không refactor | ⚠️ Chấp nhận ngắn hạn, phải trả sớm |
| Vay nặng lãi | Không có type, spaghetti code, no docs | ❌ Đừng bao giờ — lãi suất quá cao |
Khi nào chấp nhận nợ
Startup giai đoạn validate: code “vừa đủ tốt” để ship nhanh = đúng. Hoàn hảo hoá trước khi biết ai dùng = sai. Nhưng: ghi TODO comment, tạo ticket, đặt deadline trả nợ. Nợ không ghi = nợ quên = nợ mãi.
// File: tech-debt.ts
// ✅ Tech debt CÓ GHI CHÚ — sẽ trả
// TODO(@minh, 2026-09): Refactor sang Strategy pattern
// khi có thêm payment provider. Hiện tại chỉ có Stripe.
// Ticket: PROJ-234
function processPayment(amount: number) {
// Hardcode Stripe — tạm chấp nhận cho MVP
return stripe.charges.create({ amount })
}
// ❌ Tech debt KHÔNG GHI — sẽ quên
function processPayment(amount: number) {
// eslint-disable-next-line
return (stripe as any).charges.create({ amount: amount as any })
// Ai viết cái này? Tại sao? Bao giờ fix?
}
Dấu hiệu nợ quá nhiều (phải trả NGAY)
| Dấu hiệu | Nghĩa là |
|---|---|
| Fix 1 bug → tạo 3 bug mới | Code quá entangled, không có ranh giới module rõ ràng |
| Thêm feature mất 3x thời gian dự kiến | Foundation quá yếu, mỗi thay đổi ảnh hưởng 10 chỗ |
| Developer mới mất 2+ tuần mới code được | Docs thiếu, code không self-explanatory |
| Không ai dám refactor vì sợ vỡ | Thiếu test → không biết refactor có an toàn không |
| “Chỉ có Minh hiểu code này” | Bus factor = 1, nếu Minh nghỉ → team tê liệt |
💡 Quy tắc 20%
Dành 20% thời gian sprint cho trả nợ kỹ thuật: refactor, viết test, cải thiện docs. Không phải sprint riêng — mà MỖI sprint. Giống trả góp: nhỏ nhưng đều đặn.
❓ Khi nào tech debt là chấp nhận được?
- Review codebase: liệt kê top 5 “nợ” lớn nhất
- Ghi TODO + ticket cho mỗi debt
- Áp dụng quy tắc 20% sprint cho trả nợ
- Đảm bảo bus factor > 1 cho mọi module quan trọng