Mở đầu — vì sao bài này quan trọng
Khi bạn còn là Designer, một cái wireframe đẹp, gọn gàng, đúng grid là sản phẩm cuối cùng. Bạn đưa nó cho developer, developer nhìn vào, gật gù, rồi… code ra một thứ khác 30% so với ý bạn. Bạn bực. Họ bực. QA thì tìm không ra "đúng sai" vì chẳng có gì để đối chiếu.
Vấn đề không nằm ở cái wireframe. Vấn đề nằm ở khoảng trống giữa những gì bạn vẽ ra và những gì hệ thống phải làm. Một nút "Đặt hàng" trên wireframe trông rất rõ ràng với con người, nhưng developer cần biết: bấm vào thì gọi API nào, khi nào nút bị disable, nếu API lỗi thì hiện gì, số lượng tối đa là bao nhiêu, giá lấy từ đâu. Wireframe không tự trả lời được những câu đó.
Đây chính là nơi vai trò của bạn thay đổi hoàn toàn khi chuyển sang BA. Wireframe không còn là sản phẩm cuối — nó trở thành khung xương để treo đặc tả (spec) lên. Kỹ năng bạn cần học ở bài này là wireframe annotation: nghệ thuật chú thích wireframe sao cho mỗi pixel trên màn hình đều "biết nói", đều trả lời được câu hỏi của developer và QA trước khi họ kịp hỏi.
Bài này là cây cầu (bridge) rất cụ thể giữa hai thế giới bạn đang đứng giữa: thế giới Design mà bạn xuất thân, và thế giới Spec mà bạn sắp sống trong đó. Làm tốt annotation, bạn tiết kiệm cho team hàng chục vòng hỏi-đáp qua Slack, giảm bug, và quan trọng nhất — bạn chứng minh mình đã tư duy như một BA thực thụ.
Khái niệm cốt lõi
Annotation là gì và không phải là gì
Wireframe annotation là lớp chú thích đặt cạnh (hoặc chồng lên) wireframe, giải thích hành vi, dữ liệu, và quy tắc đằng sau từng thành phần giao diện. Nếu wireframe trả lời câu hỏi "màn hình trông thế nào", thì annotation trả lời "màn hình hoạt động thế nào".
Annotation không phải là viết lại toàn bộ SRS lên hình. Nó cũng không phải là mô tả màu sắc, font chữ hay khoảng cách — đó là việc của Design system và spec visual. Annotation của BA tập trung vào logic nghiệp vụ và luồng dữ liệu, không phải thẩm mỹ.
Bốn câu hỏi mà mọi thành phần phải trả lời
Đây là khung tư duy quan trọng nhất của bài. Với mỗi thành phần có ý nghĩa trên màn hình (một trường dữ liệu, một nút, một danh sách, một badge trạng thái), annotation phải trả lời được bốn câu hỏi:
- Data từ đâu? — Giá trị hiển thị lấy từ field nào, API endpoint nào, hay do người dùng nhập? Ví dụ: "Tên hiển thị =
user.fullNametừGET /api/v1/profile". - Khi nào hiển thị / ẩn? — Điều kiện (business rule) quyết định thành phần này xuất hiện, ẩn, disable hay đổi trạng thái. Ví dụ: "Nút 'Hoàn tiền' chỉ hiện khi
order.status = DELIVEREDvà trong vòng 7 ngày kể từdeliveredAt". - Hành vi khi tương tác? — Bấm/nhập/chọn thì gì xảy ra? Gọi API nào, chuyển màn nào, hiện message gì? Bao gồm cả các trạng thái loading, success, error.
- Ràng buộc và ngoại lệ (edge case)? — Validation, giới hạn, giá trị mặc định, trạng thái rỗng (empty state), quá dài, quá tải, mất mạng.
Ba loại annotation thường dùng
- Callout (chú thích đánh số): đánh số 1, 2, 3 lên các thành phần, kèm bảng giải thích bên cạnh. Phổ biến nhất, dễ đọc.
- Inline note (ghi chú tại chỗ): ghi chú ngắn ngay cạnh phần tử, hợp với ràng buộc đơn giản (max 50 ký tự, bắt buộc nhập).
- State table (bảng trạng thái): khi một thành phần có nhiều trạng thái (default / hover / disabled / error / loading / empty), tách riêng bảng liệt kê điều kiện và biểu hiện của từng trạng thái.
Quan hệ với các artefact khác
Annotation không sống một mình. Nó là điểm giao (bridge) nối wireframe với:
- Business rules (bạn học ở Bài 23) — annotation tham chiếu rule bằng ID, không chép nguyên văn.
- API spec / OpenAPI (Bài 21) — annotation trỏ tới endpoint, không mô tả lại toàn bộ payload.
- Acceptance criteria / Gherkin (Bài 17) — annotation nêu hành vi, AC sẽ formalize nó thành điều kiện kiểm thử.
Tình huống thực tế
Ví dụ 1 — Tiki: màn hình giỏ hàng và cái nút "vô hình" giữa các trạng thái
Một BA (vừa từ UX chuyển sang) tại một sàn thương mại điện tử kiểu Tiki nhận việc đặc tả lại màn hình giỏ hàng. Cô vẽ wireframe rất đẹp: danh sách sản phẩm, ô nhập số lượng, nút "Tiến hành đặt hàng". Cô gửi cho team dev ở TP.HCM và nghĩ mọi thứ đã rõ.
Sprint sau, bug đổ về hàng loạt: nút "Tiến hành đặt hàng" vẫn bấm được khi giỏ trống; khi một sản phẩm hết hàng thì app crash; số lượng nhập được tới 9999 chiếc. Mỗi bug là một cuộc họp.
Gốc rễ: wireframe không có annotation. Cô làm lại theo khung bốn câu hỏi, riêng cho nút "Tiến hành đặt hàng":
- Data: tổng tiền = tính từ
sum(item.price * item.qty), hiển thị định dạng VNĐ. - Khi nào hiện/disable: nút disable khi
cart.items.length = 0HOẶC tồn tại item cóstock = 0. - Hành vi: bấm → gọi
POST /api/cart/checkout→ chuyển màn thanh toán. Trong lúc chờ, nút chuyển trạng thái loading, chặn bấm lần hai. - Edge case: ô số lượng chỉ nhận 1–
item.maxPerOrder(mặc định 10). Nếu API trảOUT_OF_STOCK, hiện toast "Sản phẩm X vừa hết hàng" và tự cập nhật lại giỏ.
maxPerOrder, về hành vi khi hết hàng — những câu mà lẽ ra phải làm rõ trước khi dev viết dòng code đầu tiên. Số bug liên quan tới màn hình này ở sprint kế giảm từ 11 xuống 2.Ví dụ 2 — Ví điện tử (kiểu MoMo): trạng thái quyết định tất cả
Một BA đặc tả màn hình chi tiết giao dịch cho một ví điện tử. Thành phần trung tâm là badge trạng thái giao dịch. Ban đầu annotation chỉ ghi vỏn vẹn: "Hiện trạng thái giao dịch". Dev hỏi lại: có bao nhiêu trạng thái? Màu gì? Cái nào cho bấm "Khiếu nại"?
Anh nhận ra thành phần này cần một state table riêng thay vì một dòng callout:
Trạng thái (txn.status) | Badge hiển thị | Nút "Khiếu nại" | Ghi chú |
|---|---|---|---|
PENDING | "Đang xử lý" (vàng) | Ẩn | Poll lại mỗi 5s |
SUCCESS | "Thành công" (xanh) | Hiện nếu trong 90 ngày | |
FAILED | "Thất bại" (đỏ) | Hiện | Kèm mã lỗi errorCode |
REFUNDED | "Đã hoàn tiền" (xám) | Ẩn |
Ví dụ 3 — Startup logistics ở Đông Nam Á: empty state bị bỏ quên
Một team nhỏ làm app quản lý đơn giao hàng cho tài xế. BA annotate rất kỹ màn hình "Danh sách đơn hôm nay" khi có đơn: mỗi dòng lấy data từ đâu, bấm vào ra sao. Nhưng ngày go-live, tài xế mới chưa có đơn nào mở app lên thấy màn hình trắng trơn, tưởng app hỏng, gọi tổng đài loạn cả lên.
Nguyên nhân: annotation chỉ mô tả "happy path" (trường hợp lý tưởng, có dữ liệu), quên mất empty state và error state. BA bổ sung:
- Empty state: khi
orders.length = 0→ hiện minh họa + dòng chữ "Chưa có đơn nào hôm nay. Kéo xuống để làm mới." - Error state: khi API lỗi mạng → "Không tải được danh sách. Thử lại" kèm nút retry.
- Loading state: skeleton 3 dòng trong lúc chờ.
Hướng dẫn từng bước
Bước 1 — Chuẩn hóa wireframe. Đặt wireframe lên khung có chỗ trống bên phải hoặc bên dưới để chứa annotation. Trên Figma, dùng một section riêng "Annotations" cạnh mỗi màn. Đừng annotate lên bản màu mè cuối cùng — dùng bản low/mid-fidelity để chú thích nổi bật.
Bước 2 — Đánh số các thành phần có nghĩa. Quét màn hình, gắn số 1, 2, 3… lên từng phần tử mang logic nghiệp vụ. Bỏ qua trang trí. Nếu bạn không chắc một phần tử có "đáng số" không, hãy tự hỏi: developer có cần thêm thông tin để code nó không? Nếu có, đánh số.
Bước 3 — Áp khung bốn câu hỏi cho từng số. Với mỗi callout, viết một bảng nhỏ: Data từ đâu / Khi nào hiện / Hành vi / Edge case. Không phải phần tử nào cũng cần đủ bốn — một tiêu đề tĩnh chỉ cần "Data từ đâu". Nhưng nút và trường nhập gần như luôn cần cả bốn.
Bước 4 — Tách state table cho thành phần đa trạng thái. Bất cứ phần tử nào đổi hình theo trạng thái (nút, badge, dòng danh sách) đều tách bảng riêng với hai cột tối thiểu: điều kiện và biểu hiện.
Bước 5 — Thêm bốn trạng thái màn hình. Với mọi màn có dữ liệu động, annotate rõ loading / có dữ liệu / empty / error.
Bước 6 — Trỏ tới, đừng chép. Thay vì viết nguyên rule, ghi tham chiếu: "Áp dụng BR-014" hoặc "Xem endpoint POST /checkout trong API spec". Giữ annotation gọn, nguồn sự thật (source of truth) nằm ở rule catalog và API spec.
Bước 7 — Rà bằng góc nhìn dev và QA. Đọc lại và tự đóng vai developer: "Tôi có code được không mà không hỏi thêm?" Rồi đóng vai QA: "Tôi viết được test case từ đây chưa?" Chỗ nào còn phải hỏi, đó là chỗ annotation còn thiếu.
Bước 8 — Review cùng dev trước khi chốt. Ngồi 15 phút với một dev đi qua annotation. Đây là cách rẻ nhất để phát hiện chỗ bạn tưởng rõ mà thực ra mơ hồ.
Lỗi thường gặp & mẹo
Lỗi 1 — Annotate như Designer, mô tả visual. Ghi "khoảng cách 16px, màu xanh #0A68FF" là việc của Design system, không phải BA. Annotation của bạn nói về hành vi và dữ liệu. Mẹo: nếu câu chú thích không chứa từ khóa về data, điều kiện, hay hành vi, có lẽ nó không thuộc về bạn.
Lỗi 2 — Chỉ annotate happy path. Đây là lỗi phổ biến nhất của người mới từ Design sang. Mẹo: với mỗi màn, buộc mình liệt kê đủ loading / empty / error trước khi coi là xong.
Lỗi 3 — Chép nguyên rule vào hình. Dẫn tới hai nguồn sự thật lệch nhau. Mẹo: luôn tham chiếu bằng ID (BR-xxx), sửa một chỗ.
Lỗi 4 — Annotation quá dài, thành cả một tài liệu trên hình. Nếu chú thích dài hơn nửa màn hình, tách sang tài liệu riêng và để callout ngắn gọn trỏ tới. Wireframe phải còn đọc được.
Lỗi 5 — Quên cập nhật khi wireframe đổi. Annotation lệch với hình còn tệ hơn không có. Mẹo: coi annotation là một phần của wireframe, sửa hình thì sửa chú thích cùng lúc; đặt "review annotation" vào Definition of Done.
Mẹo vàng: dùng đúng một template callout cố định cho cả dự án (Data / Điều kiện / Hành vi / Edge case). Sự nhất quán giúp dev và QA đọc nhanh, và giúp bạn không bỏ sót câu hỏi nào.
Bài tập thực hành
- Chọn một màn hình quen thuộc. Lấy màn hình đăng nhập hoặc màn hình chi tiết sản phẩm của một app bạn hay dùng (Shopee, MoMo, Grab…). Vẽ lại wireframe low-fidelity của nó.
- Đánh số và áp khung bốn câu hỏi. Gắn số lên mọi thành phần có nghĩa. Với mỗi số, viết bảng: Data từ đâu / Khi nào hiện / Hành vi / Edge case. Mục tiêu: ít nhất 6 callout hoàn chỉnh.
- Viết một state table. Chọn thành phần đa trạng thái (nút submit hoặc badge trạng thái) và lập bảng trạng thái với cột điều kiện + biểu hiện.
- Bổ sung bốn trạng thái màn hình. Annotate rõ loading / có dữ liệu / empty / error cho màn bạn chọn.
- Tự kiểm bằng vai QA. Từ annotation của bạn, viết thử 5 test case. Nếu có case nào không viết được vì thiếu thông tin, quay lại bổ sung annotation — đó chính là lỗ hổng requirement bạn vừa phát hiện.
Tóm tắt
Wireframe annotation là cây cầu cụ thể nhất đưa bạn từ tư duy Designer sang tư duy BA. Wireframe trả lời "màn hình trông thế nào"; annotation trả lời "màn hình hoạt động thế nào". Với mỗi thành phần có nghĩa, hãy trả lời bốn câu hỏi: data từ đâu, khi nào hiển thị, hành vi khi tương tác, và ràng buộc/ngoại lệ. Dùng state table cho thành phần đa trạng thái, và luôn annotate đủ bốn trạng thái màn hình (loading, có dữ liệu, rỗng, lỗi) — vì bug và trải nghiệm tệ thường nằm ngoài happy path.
Nguyên tắc cốt lõi: trỏ tới, đừng sao chép — annotation tham chiếu tới business rule và API spec chứ không chép lại, để chỉ có một nguồn sự thật. Và phép thử cuối cùng cho một bản annotation tốt rất đơn giản: developer code được mà không cần hỏi, QA viết được test case ngay. Khi bạn đạt được điều đó, bạn không còn chỉ là người vẽ màn hình — bạn đã là người biến ý tưởng thành đặc tả mà cả team tin cậy.