Vibe Code
Giáo trình/Phần 6 — Cao cấp nhất

Vòng phản hồi thật

Lớp 8 của sơ đồ — thu thập lỗi và góp ý, biến thành ticket ai cũng thấy, phân loại ưu tiên, rồi về backlog. Lớp mà hầu hết người học vẽ thiếu.

Cấp 630 phút đọc

Lớp cuối của sơ đồ Vibe Stack nối vòng về lớp 4: góp ý của người dùng thành việc trong GitHub, đi qua cổng kiểm soát, rồi lên bản thật. Không có lớp này, bạn làm app trong bóng tối.

Vấn đề gốc: người dùng không báo lỗi

Đây là điều người mới hiểu sai nhất. Bạn tưởng gặp lỗi thì người ta sẽ nói. Thực tế:

  • Họ thử lại vài lần, rồi bỏ.
  • Họ tự chế ra cách đi vòng — ghi ra giấy rồi nhập sau, dùng Excel song song.
  • Họ nói với đồng nghiệp, không nói với bạn.
  • Ba tháng sau, họ nói với sếp: "cái app ấy khó dùng".

Tỉ lệ người gặp lỗi mà chủ động báo là rất thấp. Nên lớp 8 không phải là "mở một kênh để nghe" — nó là đi tìm.

Thu thập: bốn nguồn, ba nguồn đầu không cần ai nói gì

Nguồn 1 — Lỗi tự báo về (đáng tin nhất).

Bắt lỗi phía trình duyệt và gửi về máy chủ của bạn:

window.addEventListener("error", (e) => baoLoi({
  loai: "js", tin: e.message, file: e.filename, dong: e.lineno
}));
window.addEventListener("unhandledrejection", (e) => baoLoi({
  loai: "promise", tin: String(e.reason)
}));

let daGui = 0;
function baoLoi(d) {
  if (daGui++ > 5) return;                       // chặn bão lỗi
  navigator.sendBeacon("/api/bao-loi", JSON.stringify({
    ...d, duong: location.pathname, man: innerWidth + "x" + innerHeight,
    ua: navigator.userAgent.slice(0, 120), phien_ban: APP_VERSION,
  }));
}

Ba chi tiết: chặn bão lỗi (một lỗi trong vòng lặp có thể bắn hàng nghìn lượt), kèm phiên bản app (biết lỗi thuộc bản nào), và sendBeacon (gửi được cả khi người dùng đang đóng tab).

Nguồn 2 — Dấu hiệu hành vi. Người dùng không nói, nhưng hành vi thì nói:

Dấu hiệu Nghĩa là
Bấm cùng một nút 3 lần trong 5 giây Không có phản hồi khi bấm
Vào màn hình rồi thoát ngay, lặp lại Không tìm thấy thứ cần
Một tính năng không ai dùng trong 30 ngày Làm ra vô ích — cân nhắc gỡ
Số lượt dùng đột ngột giảm Có gì đó vừa hỏng

Nguồn 3 — Nhật ký nghiệp vụ. Số lỗi 400 tăng ở một đường API nghĩa là người dùng đang nhập thứ bạn không lường trước — thường là lỗi thiết kế form, không phải lỗi người dùng.

Nguồn 4 — Hỏi thẳng, đúng cách.

Đừng hỏi "app có ổn không?" — ai cũng trả lời "ổn". Hỏi những câu cụ thể:

"Hôm qua chị làm việc X, có chỗ nào phải làm thủ công thêm không?" "Có lúc nào chị phải ghi ra giấy rồi nhập lại sau không?" "Nếu em sửa được đúng một thứ trong app, chị muốn sửa cái gì?"

Câu cuối là câu hiệu quả nhất. Nó buộc người ta chọn, và cái họ chọn gần như luôn là vấn đề thật.

Người dùng mô tả giải pháp, không mô tả vấn đềchuyên gia insight & case thực tế

Khách nói: "Em thêm cho anh nút xuất Excel ở màn hình này."

Nếu làm ngay, bạn có một nút. Nếu hỏi thêm "anh xuất ra để làm gì ạ?" — câu trả lời có thể là "để anh gửi cho kế toán đối chiếu mỗi tối". Và giải pháp đúng hóa ra là tự động gửi email báo cáo lúc 17h30, không ai phải bấm gì.

Luật tôi dùng: nhận yêu cầu thì hỏi ngược một câu "để làm gì", trước khi ước lượng thời gian. Mất 30 giây, và khoảng một phần ba số lần nó đổi hẳn việc phải làm — thường theo hướng ít việc hơn và giá trị hơn.

Nhưng cẩn thận với mặt trái: hỏi "để làm gì" quá nhiều lần làm khách thấy bị chất vấn. Hỏi một lần, rồi làm.

Ticket — ai cũng thấy

Nguyên tắc: mọi góp ý phải rời khỏi hộp thoại riêng và vào một chỗ ai cũng thấy. Góp ý nằm trong tin nhắn Zalo riêng của bạn là góp ý sẽ mất.

Với người làm một mình, GitHub Issues là đủ và miễn phí. Mỗi góp ý một issue, nhãn phân loại, không cần công cụ gì thêm.

gh issue create --title "Bang don hang bi cuon ngang tren iPhone" \
  --label "loi,mobile" \
  --body "Nguoi bao: chi Lan (ke toan). Ngay 08/10.
Mo /don-hang tren iPhone 12 → cuon ngang, cot Ghi chu bi che.
Phien ban app: V1.11. Da thu tren Safari va Chrome, deu bi."

Bốn thông tin tối thiểu trong mỗi issue: ai báo · làm gì thì ra · mong đợi gì · phiên bản/thiết bị. Thiếu phiên bản là ba tuần sau không biết lỗi đó đã sửa chưa.

Phân loại — xếp ưu tiên, đừng xếp theo thứ tự đến

Hai trục, bốn ô:

                  Ảnh hưởng NHIỀU người
                          │
      LÀM NGAY            │      LÊN KẾ HOẠCH
   (lỗi chặn việc,        │   (tính năng lớn ai
    mất dữ liệu)          │    cũng cần)
  ────────────────────────┼────────────────────────
      LÀM KHI RẢNH        │      NÓI KHÔNG
   (lỗi nhỏ, 1-2 người,   │   (tính năng lớn cho
    có cách đi vòng)      │    một người)
                          │
                  Ảnh hưởng ÍT người

Ô "Nói không" là ô khó nhất và quan trọng nhất. Tính năng tốn hai tuần cho đúng một người dùng là hai tuần không làm thứ cả trăm người cần. Cách từ chối không làm mất lòng:

"Việc này em làm được, mất khoảng hai tuần. Hiện em đang làm X mà cả phòng kế toán đang chờ. Anh muốn em đổi thứ tự không?"

Đưa cái giá ra, để người có quyền quyết định. Gần như luôn luôn, họ tự rút lại.

Và một quy tắc cứng, bất kể ô nào: lỗi mất dữ liệu hoặc lỗ hổng bảo mật luôn lên đầu, kể cả khi mới ảnh hưởng một người.

Backlog — và kỷ luật đóng

[Mới]  →  [Đã phân loại]  →  [Đang làm]  →  [Chờ duyệt]  →  [Xong]
                   │
                   └──→  [Không làm]  (ghi rõ lý do, rồi ĐÓNG)

Hai luật giữ cho backlog không thành bãi rác:

  1. "Đang làm" tối đa 3 việc. Nhiều hơn là bạn đang chia nhỏ sự chú ý và không xong cái nào.
  2. Việc nằm quá 3 tháng không ai nhắc → đóng với lý do "không còn cần". Mở lại được nếu có người hỏi. Một backlog 200 việc là một backlog không ai dám mở.

Đóng vòng — bước ai cũng quên

Khi sửa xong, quay lại báo cho người đã góp ý:

"Chị Lan ơi, chỗ bảng bị cuốn ngang trên iPhone em sửa rồi, bản V1.12, chị thử lại giúp em."

Tin nhắn này có tác dụng lớn hơn bạn tưởng:

  • Người đó sẽ báo lỗi lần sau. Nếu góp ý rơi vào im lặng, họ thôi.
  • Nó xác minh rằng bạn sửa đúng cái họ gặp, không phải cái bạn tưởng.
  • Nó biến người dùng thành người kiểm thử cho bạn — và họ kiểm trên thiết bị thật, mạng thật.
Tôi làm một tính năng suốt hai tuần, không ai dùngngười dùng bình thường góp ý

Khách nói muốn "biểu đồ phân tích doanh thu". Tôi làm biểu đồ rất đẹp, nhiều bộ lọc.

Ba tháng sau tôi xem nhật ký: màn hình đó được mở 4 lần, tất cả đều là tôi mở để kiểm.

Tôi hỏi lại khách. Hóa ra ý của anh ấy là: "anh muốn biết hôm nay bán được bao nhiêu" — một con số, trên màn hình đầu tiên. Tôi làm cái đó trong một buổi chiều, và nó được mở mỗi ngày.

Bài học của tôi, hơi đau: "muốn xem doanh thu" không có nghĩa là "muốn một trang phân tích". Giờ tôi luôn hỏi một câu trước khi làm: "Anh xem cái này lúc nào, và xem xong anh làm gì tiếp?"

Dựng đường nhận lỗi và bảng phản hồichuyên gia thực thi
Thêm lớp thu thập phản hồi cho app:

1. Bắt lỗi phía trình duyệt (error + unhandledrejection), gửi về
   POST /api/bao-loi bằng sendBeacon. Kèm: đường dẫn, cỡ màn hình,
   trình duyệt, APP_VERSION, người dùng (nếu đã đăng nhập).
   Chặn tối đa 5 lượt mỗi phiên để tránh bão lỗi.

2. Bảng loi_client trong D1: loai, tin, duong, phien_ban, nguoi,
   man_hinh, ua, luc. Index theo (phien_ban, luc DESC).

3. Nút "Góp ý" ở chân mọi màn hình: một ô chữ, tự đính kèm đường
   dẫn hiện tại và APP_VERSION. Lưu vào bảng gop_y.

4. Trang quản trị /admin/phan-hoi:
   - Lỗi 7 ngày gần nhất, GỘP THEO nội dung lỗi, sắp theo số lượt
   - Cột: số lượt, số người khác nhau, phiên bản, lần cuối
   - Danh sách góp ý chưa xử lý
   - Tính năng KHÔNG AI DÙNG trong 30 ngày (dựa trên nhat_ky)

Gộp theo nội dung lỗi là bắt buộc — 400 dòng của cùng một lỗi phải
hiện thành MỘT dòng với số lượt 400.

Mục cuối — tính năng không ai dùng — là mục cho bạn thứ không ai nói ra: những thứ bạn làm mà vô ích.

Chốt review bài nàychuyên gia review
  • Đủ: vì sao người dùng không báo lỗi, bốn nguồn thu thập, mẫu ticket, ma trận phân loại, kỷ luật backlog, đóng vòng.
  • Nhấn mạnh: ô "Nói không" và việc hỏi "để làm gì" — hai thứ tiết kiệm nhiều thời gian nhất.
  • Rủi ro còn lại: lớp này cho bạn dữ liệu, không cho bạn quyết định. Vẫn có lúc đúng là làm thứ chưa ai yêu cầu — người dùng không yêu cầu được thứ họ chưa biết là có thể. Dùng phản hồi để loại bỏ cái sai, đừng dùng nó để thay cho phán đoán của bạn.
Bài tập chốt
  1. Dựng đường nhận lỗi tự động theo đề trên. Để chạy một tuần.
  2. Mở bảng lỗi, đọc 5 lỗi nhiều lượt nhất. Phần lớn sẽ là thứ bạn chưa từng nghe ai nói.
  3. Tạo GitHub Issue cho từng lỗi đó, phân loại theo ma trận bốn ô.
  4. Hỏi ba người dùng thật đúng một câu: "Nếu em sửa được đúng một thứ trong app, anh/chị muốn sửa cái gì?" So ba câu trả lời với danh sách việc bạn đang định làm.

Việc 4 thường làm người ta ngạc nhiên nhất — và nó mất đúng 10 phút.