Vibe Code
Giáo trình/Phần 5 — Quy trình & vận hành

Preview → test → deploy → verify → rollback

Quy trình giao hàng không gây sự cố. Bảy bước, không đi tắt, kèm cách lùi lại trong 30 giây khi bản mới hỏng.

Cấp 535 phút đọc

Đây là bài quan trọng nhất của cả giáo trình đối với người đã có app chạy thật. Mọi kỹ thuật ở Cấp 3–4 chỉ có giá trị nếu bạn đưa được chúng tới người dùng mà không làm hỏng thứ đang chạy.

Một câu phê bình đáng khắc cốt: "Làm web thì phải qua test ngon lành mới deploy."

Bảy bước, không đi tắt

1. Sửa mã ở máy
2. Đẩy lên bản PREVIEW (link riêng, chưa ai thấy)
3. TEST TRỌN LUỒNG trên bản preview
4. Deploy lên bản thật
5. VERIFY trên bản thật
6. Commit + push lên GitHub
7. Ghi lại bài học nếu có

Hai bước người ta hay bỏ là bước 3 và bước 5. Và đó chính xác là hai bước chặn sự cố.

Bước 2 — Bản preview gắn phiên bản

npx wrangler versions upload

Khác với wrangler deploy, lệnh này không đụng tới bản thật. Nó trả về một link riêng gắn với đúng phiên bản vừa tải lên:

https://a3f91c2-app-don-hang.ten-ban.workers.dev

Với Pages:

npx wrangler pages deploy dist --project-name=app --branch=preview
Ba thứ KHÔNG chạy trên bản preview
  1. Binding rate limit — trần không có tác dụng. Thay đổi về trần phải test trên bản thật (Bảo mật).
  2. Migration của Durable Object — lần đầu phải wrangler deploy thẳng (Durable Objects).
  3. Cron Trigger — không bắn trên bản preview; test bằng wrangler dev --test-scheduled.

Biết trước ba cái này để khỏi kết luận nhầm "tính năng không chạy".

Bước 3 — Test trọn luồng, theo thứ tự rủi ro

Chi tiết ở Test như kẻ phá hoại. Mức tối thiểu không được bỏ:

a. Test cả đường ĐỌC lẫn đường GHI. Đây là bẫy đã làm lọt lỗi thật: tài khoản test chỉ có quyền xem thì không bao giờ lộ lỗi đường ghi. Lỗi "không lưu được vào cơ sở dữ liệu" đã lên tới bản thật vì lý do đúng như vậy. Phải có một tài khoản test ghi được.

b. Test cả mobile 375px LẪN desktop 1280px. Khung xem thử mặc định thường chỉ ~700–1000px — không phải desktop thật, cũng không phải mobile thật.

c. Đo bằng SỐ, đừng đoán bằng mắt. Đếm số request, đo kích thước phần tử bằng getBoundingClientRect(), đếm số dòng chữ. Mắt người rất dễ bỏ sót.

d. Console phải sạch lỗi.

App có thể hoãn vẽ lại sau thao tác — đo sớm là đo sai

Nhiều app gom nhiều thay đổi rồi mới vẽ lại một lần, trễ 1–2 giây. Nếu bạn bấm rồi đếm ngay, bạn đếm trạng thái cũ và kết luận "tính năng không chạy".

Luật: sau thao tác, chờ > 2 giây rồi mới đo. Và khi tự động hóa phép thử, đợi điều kiện xuất hiện chứ đừng đợi một khoảng thời gian cố định.

Bước 4 — Deploy lên bản thật

npx wrangler versions list                         # xem danh sách, lấy id bản vừa test
npx wrangler versions deploy <id>@100% --yes

Ưu điểm lớn của cách này: bạn deploy đúng cái đã test, không phải build lại từ mã nguồn (và do đó không có rủi ro "lần build này khác lần build trước").

Với Pages nối Git thì deploy là git push vào main, kèm cổng duyệt đã dựng ở GitHub Actions.

Bước 5 — Verify trên bản thật

Deploy báo thành công không có nghĩa là người dùng nhận được bản mới. Phải kiểm bằng chứng cứ:

# 1. Trang trả về 200
curl -I https://app-cua-ban.com

# 2. Mã đang phục vụ ĐÚNG là bản mới — grep một chuỗi chỉ có trong bản mới
curl -s https://app-cua-ban.com | findstr "V1.11"

# 3. Nếu có tách file tài nguyên: phải grep ĐÚNG file tài nguyên,
#    không grep file HTML khung (file khung thường chỉ vài KB)
curl -s https://app-cua-ban.com/assets/app-3.a1b2c3.js | findstr "tinh_nang_moi"
Grep nhầm file khung — tưởng deploy hỏng

Nhiều hệ thống build tách index.html thành app.<mã>.css + app.<mã>.js, để lại file HTML khung chỉ ~12 KB. Grep chuỗi tính năng mới trong HTML khung thì không bao giờ thấy, dù deploy hoàn toàn đúng.

Luật: tìm trong đúng file tài nguyên đang được phục vụ. Lấy tên file đó từ chính HTML khung.

Và một việc thủ công không thay được: mở app bằng cửa sổ ẩn danh, trên điện thoại thật, mạng 4G. Đây là lần duy nhất bạn nhìn thấy đúng thứ người dùng nhìn thấy.

Đánh phiên bản để kiểm được bằng mắt: đặt hằng số APP_VERSION trong mã, hiện ở menu và chân trang đăng nhập. Nhân viên tự kiểm được "đã nhận bản mới chưa", và bạn không phải hỏi "anh thử tải lại xem".

Rollback — lùi lại trong 30 giây

Khi bản thật đang hỏng: KHÔI PHỤC TRƯỚC, ĐIỀU TRA SAU.

npx wrangler deployments list                      # xem lịch sử, lấy id bản cũ đang lành
npx wrangler versions deploy <id-cu>@100% --yes

Ba điều về rollback mà người mới hay làm ngược:

  1. Đừng ngồi tìm nguyên nhân trong lúc app đang chết. Mỗi phút là một phòng ban ngồi chơi. Lùi trước, điều tra sau, trong yên tĩnh.
  2. Rollback xong phải kiểm chứng bằng người-mở-mới thật — xóa cookie, cửa sổ ẩn danh, tải lại. Đã có lần rollback rồi mà app vẫn treo, vì nguyên nhân nằm ở chỗ khác (một tác vụ nền), không phải ở bản vừa deploy.
  3. Rollback không sửa dữ liệu. Nếu bản lỗi đã ghi sai vào cơ sở dữ liệu, lùi mã không lấy lại dữ liệu. Đó là việc của sao lưu.

Triển khai dần — giảm thiệt hại khi sai

Với thay đổi rủi ro cao, đừng đẩy 100% ngay:

npx wrangler versions deploy <id-moi>@10% <id-cu>@90% --yes
# theo dõi 30 phút, xem tỉ lệ lỗi
npx wrangler versions deploy <id-moi>@100% --yes

10% người dùng gặp lỗi vẫn là sự cố, nhưng là sự cố nhỏ hơn 10 lần. Dùng cho: đổi cấu trúc dữ liệu, đổi cách xác thực, đổi định tuyến.

Thay đổi "vô hại" là thứ gây sự cố, không phải thay đổi lớnchuyên gia insight & case thực tế

Nhìn lại các sự cố thật, chúng gần như không bao giờ đến từ tính năng lớn — vì tính năng lớn thì ai cũng cẩn thận. Chúng đến từ:

  • Đổi định tuyến (đổi tiền tố API, thêm một cửa trung gian). Một lần thay chuỗi /api/ trong bước build đã phá luôn danh sách file mà hệ thống tách tài nguyên mong đợi → app phục vụ file HTML thô, mất sạch giao diện.
  • "Dọn dẹp cho gọn" — gộp hàm, đổi tên biến. Một bản vá cắt theo vị trí đã nuốt mất hai hàm, làm hỏng đường ghi trên bản thật.
  • Sửa một dòng cấu hình lúc 5 giờ chiều thứ Sáu.

Hai luật rút ra: 1. Việc đổi định tuyến hoặc đổi cấu trúc file được coi là RỦI RO CAO, dù mã thay đổi ít. Test như với tính năng lớn. 2. Sau mọi bản vá cắt theo vị trí, phải grep lại tên từng hàm của khối cũ để chắc không nuốt mất gì.

Bảng kiểm dán cạnh màn hình

TRƯỚC KHI DEPLOY
[ ] Đã test trên bản preview, cả ĐỌC và GHI
[ ] Đã test 375px và 1280px
[ ] Console sạch lỗi
[ ] Đã xem git diff --stat, số dòng đổi hợp lý
[ ] Đã tăng số phiên bản APP_VERSION
[ ] Biết id bản hiện tại để lùi lại nếu cần

SAU KHI DEPLOY
[ ] curl -I trả 200
[ ] grep đúng file tài nguyên, thấy thay đổi mới
[ ] Mở cửa sổ ẩn danh trên điện thoại thật
[ ] Theo dõi log 10 phút (wrangler tail)
[ ] git commit + push
Tôi từng deploy lúc 11 giờ đêm rồi đi ngủngười dùng bình thường góp ý

Sáng ra 40 cuộc gọi. App chết từ 11 giờ đêm, cả ca sáng không ai chấm công được.

Ba luật tôi tự đặt từ hôm đó, và giữ tới giờ:

  1. Không deploy sau 16 giờ. Nếu hỏng, còn giờ hành chính để sửa.
  2. Không deploy thứ Sáu, trừ khi đang sửa một thứ đang hỏng.
  3. Deploy xong ngồi nhìn log 10 phút. Không làm việc khác. Mười phút đó bắt được gần hết sự cố, và lúc đó sửa dễ hơn sáng hôm sau rất nhiều.

Nghe như kỷ luật công ty lớn, nhưng tôi làm một mình và nó cứu tôi nhiều lần hơn mọi công cụ.

Giao cả quy trình cho Claude Codechuyên gia thực thi
Deploy thay đổi này theo đúng quy trình, KHÔNG đi tắt:

1. wrangler versions upload → cho tôi link preview
2. Trên link preview, tự kiểm bằng curl:
   - GET / trả 200
   - GET /api/bootstrap không cookie → 401 và dưới 1 giây
   - POST /api/don-hang với dữ liệu hợp lệ (dùng tài khoản test
     GHI ĐƯỢC) → 200 và đọc lại thấy đúng dòng vừa tạo
   - POST thiếu trường bắt buộc → 400, không phải 500
3. Báo cho tôi kết quả THẬT của từng phép thử, rồi DỪNG LẠI
   chờ tôi duyệt.
4. Sau khi tôi duyệt: wrangler versions deploy <id>@100% --yes
5. Verify trên bản thật: curl bản chính, grep đúng file tài nguyên
   để chắc đang phục vụ bản mới. Báo kết quả.

Dữ liệu tiếng Việt phải ghi ra file rồi dùng curl --data-binary,
không nhét thẳng vào dòng lệnh.

Bước 3 — dừng lại chờ duyệt — là bước biến AI từ "người tự deploy" thành "người chuẩn bị để bạn duyệt". Đó đúng là ranh giới ở lớp 5 của sơ đồ.

Chốt review bài nàychuyên gia review
  • Đủ: bảy bước, lệnh cụ thể cho Workers và Pages, ba thứ không chạy trên preview, verify có bằng chứng, rollback, triển khai dần, bảng kiểm.
  • Đã trả giá thật: lỗi đường ghi lọt vì tài khoản test chỉ-xem; grep nhầm file khung; rollback mà vẫn treo vì nguyên nhân khác; thay đổi định tuyến phá hệ thống tách tài nguyên.
  • Rủi ro còn lại: quy trình này không chặn được lỗi nghiệp vụ im lặng (tính sai tiền, sai múi giờ). Nó chỉ chặn lỗi làm app hỏng thấy được. Phần kia thuộc về đối chiếu tay ở bài test.
Bài tập chốt
  1. Chạy đủ bảy bước cho một thay đổi nhỏ thật. Ghi thời gian tổng.
  2. Tập rollback khi chưa cần: deploy một bản, rồi lùi về bản trước, rồi tiến lại. Bấm giờ. Mục tiêu dưới 60 giây.
  3. Thêm APP_VERSION vào app, hiện ở chân trang.
  4. Dán bảng kiểm cạnh màn hình.

Việc 2 là việc quan trọng nhất: lần đầu bạn rollback không được là lúc app đang chết và bạn đang hoảng. Tập trước, trong lúc bình yên.