AllianceProject Handbook
← Knowledge

Kiểm soát chất lượng

Definition of Done

Điều kiện một hạng mục phải thoả trước khi được gọi là xong — khác nhau theo loại hạng mục và theo module, có người ký tên, và ở quy mô 500.000 người dùng thì "xong" nghĩa là đã quan sát được trên dữ liệu thật chứ không phải đã merge.

Cập nhật 13/09/2026quy trìnhchất lượngbắt buộc

Chỗ đứng của bài này

Ba bài cùng nói về vùng kiểm soát chất lượng, không thay được nhau:

BàiTrả lời câu hỏi nàoAi gác
Quality gate tự độngCI chặn được những gì, ở tầng nàoMáy
Chuẩn riêng cho Chat, Task và Bán hàngTrong lúc viết code phải làm gìDev tự gác
Bài nàyXong hay chưa xong, và ai được quyền nói câu đóNgười ký tên

Definition of Done là gate cuối do người gác. Thứ gì máy gác được thì đã nằm ở bài đầu tiên và không lặp lại ở đây.

Vì sao cần

"Xong" là từ dễ hiểu nhầm nhất trong một dự án. Dev nói xong nghĩa là code chạy trên máy mình. Tester nói xong nghĩa là đã thử hết case. PM nói xong nghĩa là người dùng đang dùng được. Ba cách hiểu này lệch nhau vài tuần công việc, và khoảng lệch chỉ lộ ra vào đúng tuần release.

Definition of Done xoá khoảng lệch đó bằng một danh sách chung, ai cũng kiểm tra được, không phụ thuộc vào việc ai đang gấp.

Phần CI đã chặn — đừng kiểm lại bằng tay

Nguyên tắc "máy kiểm tra được thì đừng bắt người kiểm tra" áp dụng trước tiên vào chính DoD. Những mục sau không nằm trong checklist của người, vì PR không merge được nếu chúng đỏ:

Đã có gate tự độngNgưỡng
Build trên mọi nền tảng đíchĐỏ là chặn
Type check, lint toàn dự ánError hoặc warning mới là chặn
Unit test, integration testMột test đỏ là chặn
Coverage trên code mớiDưới 80% là chặn
Dependency scan, secret scanLỗ hổng mức cao trở lên là chặn
Kích thước gói cài đặtTăng quá 3% so với main là chặn
Migration không có kịch bản rollbackLà chặn

Chi tiết ở Quality gate tự động. Nếu thấy mình đang kiểm tay một mục trong bảng trên, đó là dấu hiệu gate bị hỏng hoặc bị tắt — sửa gate, đừng bù bằng sức người.

DoD lõi — áp dụng cho mọi hạng mục

Tất cả các mục dưới đây là thứ CI không nhìn thấy được:

  • Thoả đủ acceptance criteria đã viết, và người viết yêu cầu xác nhận, không phải dev tự xác nhận
  • Đã qua code review và được approve
  • Đã thử tay trên cả iOS và Android, gồm ít nhất một máy ở nhóm cấu hình thấp trong device matrix
  • Các edge case đã thử: loading, empty state, mất mạng giữa chừng, server trả lỗi, và lần mở app đầu tiên khi chưa có dữ liệu
  • Accessibility mức cơ bản: dynamic type ở cỡ lớn nhất không vỡ layout, screen reader đọc được các control chính — ngưỡng đầy đủ ở Chuẩn UI trên mobile
  • Không ghi dữ liệu cá nhân hay nội dung người dùng ra log ở bất kỳ mức nào
  • Analytics event của hạng mục đã gắn và đã thấy dữ liệu về ở môi trường test — xem Analytics event là một phần của yêu cầu
  • Không vượt performance budget của màn hình bị ảnh hưởng
  • Release note hoặc tài liệu đã cập nhật nếu hành vi thay đổi

DoD thêm, theo loại hạng mục

Một bug fix và một thay đổi schema không thể dùng chung một checklist. Phần cộng thêm:

Loại hạng mụcĐiều kiện cộng thêm
Feature mớiCó feature flag và flag đặt đúng trạng thái; có kế hoạch staged rollout; đã thống nhất chỉ số nào cho phép mở nấc tiếp
Bug fixCó regression test tái hiện đúng bug, và test đó phải đỏ trên code cũ; đã trả lời được vì sao gate hiện tại không chặn được — xem shift left
Đổi schema hoặc dữ liệu trên máyĐã test upgrade từ phiên bản đang chạy ngoài production, không chỉ cài mới; có kịch bản rollback; dữ liệu cũ không mất
Đổi API contractPhiên bản app cũ vẫn gọi được — xem backward compatibility
Nâng thư việnĐã đọc changelog phần breaking change; đã chạy luồng chính bằng tay, không chỉ dựa vào test xanh
Đổi config hoặc flag ngoài productionGhi lại ai đổi, đổi gì, lúc nào; có đường về trạng thái cũ trong dưới 5 phút

DoD thêm, theo module

Ba module có ba loại rủi ro khác nhau nên gate cũng khác nhau. Không chép lại luật ở đây — điều kiện là checklist trước PR của module đó đã tick đủ, theo Chuẩn riêng cho Chat, Task và Bán hàng:

ModuleThứ dễ hỏng nhấtĐiều kiện cứng thêm
ChatThứ tự, trùng tin, mất tin khi mạng chập chờnĐã test airplane-mode round trip và gửi liên tiếp ở mạng chậm
TaskPhân quyền, trạng thái không nhất quánĐã test gọi thẳng endpoint bằng tài khoản không có quyền
Bán hàngSai tiền, đơn trùng, mất audit trail2 approve, một người là chủ module Bán hàng; bảng test tính tiền có ca biên
Tầng dùng chungHỏng một chỗ là hỏng cả ba2 approve, một người là Chủ kỹ thuật

Ai ký

Mỗi thứ có đúng một người chịu trách nhiệm. Với DoD, người đó không phải tác giả:

ViệcNgười xác nhận
Acceptance criteria đã thoảNgười viết yêu cầu
Code đủ chuẩn để mergeNgười review
Rủi ro riêng của module đã được gácChủ module
Hạng mục được đóngChủ sản phẩm

Vai trò định nghĩa ở Vai trò và trách nhiệm. Không dòng nào trong bảng được ký bằng câu "tôi thấy ổn rồi" — mỗi dòng phải trỏ tới một bằng chứng quan sát được.

"Xong" không phải là "đã merge"

Đây là chỗ quy mô 500.000 người dùng đổi luật. Merge xong, hạng mục mới chỉ hết phần rủi ro nhìn thấy trước được. Phần còn lại chỉ lộ ra trên dữ liệu thật.

Một hạng mục chỉ được đóng khi đã đi qua staged rollout và chỉ số ổn định ở nấc cuối:

 merge ──→ 0,5% ──→ 2% ──→ 10% ──→ 50% ──→ 100% ──→ ĐÓNG
          2.500    10.000  50.000  250.000  500.000
            │        │       │        │
            └────────┴───────┴────────┴──→ chỉ số xấu đi: tắt flag,
                                           mở lại hạng mục, chưa đóng

Thang nấc và thời gian chờ lấy theo Release từng phần và feature flag — bài này không giữ bản sao.

Chỉ số cần nhìn ở mỗi nấc nằm ở Quy tắc cảnh báo. Lý do phải đọc tỷ lệ ra số người nằm ở Chất lượng ở quy mô 500.000 người dùng: 0,1% không phải số nhỏ, nó là 500 người thật đang gặp lỗi.

Ngoại lệ, và đường waiver

Có ngoại lệ. Nhưng ngoại lệ phải để lại dấu vết.

Incident P0 đang diễn ra được đi tắt để vá trước, theo quy trình xử lý sự cố. Phần DoD bị nợ ghi vào sổ nợ kỹ thuật và trả trong release kế tiếp.

Mọi trường hợp khác đi qua đường waiver trong Mẫu checklist trước release: bỏ điều kiện nào, vì sao, rủi ro là gì, ai chịu, bao giờ trả — có người ký tên.

Hai việc bị cấm, không ngoại lệ:

  1. Hạ severity của một bug để nó không chặn release. Đường đúng là waiver, không phải đổi nhãn.
  2. Sửa Definition of Done giữa kỳ cho vừa với thứ đang làm dở. Đổi DoD là quyết định của cả đội, bàn ở retro, không phải quyết định của người đang kẹt deadline.

Khi thiếu thời gian, cách xử lý đúng là cắt scope hạng mục cho nhỏ lại, giữ nguyên DoD. Chất lượng là ràng buộc, không phải thứ đem ra đánh đổi.

Khi một điều kiện liên tục bị bỏ qua

Đó là tín hiệu, không phải lỗi cá nhân. Ba khả năng, xử lý khác nhau:

Hiện tượngNghĩa làViệc cần làm
Ai cũng quên một mụcMục đó viết mơ hồ, không kiểm đượcViết lại cho kiểm được, hoặc bỏ
Ai cũng làm nhưng rất tốn côngThiếu công cụTự động hoá, đẩy xuống CI
Chỉ vài hạng mục vi phạmHạng mục quá toChẻ nhỏ ở chặng làm rõ

Im lặng bỏ qua là lựa chọn tệ nhất, vì nó biến DoD thành thứ trang trí và cả đội đều biết điều đó.

Giới hạn

  • Checklist này giả định CI đã có đủ bốn tầng gate. Chưa có thì việc cần làm trước là dựng gate, không phải bắt người kiểm tay từng mục.
  • Phần accessibility ở đây mới là mức cơ bản, đủ để không chặn người dùng. Chưa phải tuân thủ một tiêu chuẩn cụ thể nào.
  • Rà lại danh sách mỗi quý ở retro. Điều kiện nào ba quý liền không bắt được lỗi nào thì bỏ — DoD dài không đồng nghĩa với DoD tốt.