Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Q-Bài 23 — Business Rules — Tách logic khỏi feature

Từ QA/Tester sang BA: Lộ Trình Chuyển Đổi Bài 23/60

Mở đầu — vì sao bài này quan trọng

Bạn từng là QA. Mỗi lần viết test case, bạn phải tự hỏi: "Nếu đơn hàng dưới 500.000đ thì có được miễn phí ship không? Khách VIP thì ngưỡng đó có khác không? Voucher có cộng dồn với chương trình khuyến mãi không?" Những câu hỏi đó — về bản chất — chính là business rules (quy tắc kinh doanh). Bạn đã sống cùng business rules suốt cả sự nghiệp QA, chỉ là chưa gọi đúng tên chúng.

Đây chính là lợi thế ngầm khi bạn chuyển sang BA. Một BA thiếu kinh nghiệm thường viết requirement kiểu "hệ thống cho phép khách hàng dùng voucher" rồi để mọi logic chi tiết trôi nổi. Đến lúc dev code, QA test, mỗi người hiểu một kiểu. Bug nổ ra hàng loạt. Còn bạn — với con mắt QA đã quen soi edge case — biết rằng đằng sau một câu requirement đơn giản là cả một rừng quy tắc cần được tách ra, đặt tên, và quản lý riêng.

Bài học hôm nay dạy bạn một kỹ năng cốt lõi của BA giỏi: tách business rules ra khỏi feature. Khi bạn làm được điều này, requirement của bạn trở nên rõ ràng, dễ test, dễ thay đổi, và dev sẽ yêu quý bạn vì không phải đoán mò. Đây cũng là điểm tạo khác biệt giữa một BA "ghi chép yêu cầu" và một BA "kiến trúc tư duy nghiệp vụ".

Khái niệm cốt lõi

Business rule là gì — và không phải là gì

Business rule là một phát biểu định nghĩa hoặc ràng buộc một khía cạnh của nghiệp vụ. Nó chi phối behavior (hành vi) của hệ thống và con người trong tổ chức — chứ không phải mô tả một tính năng.

Hãy phân biệt rạch ròi:

  • Feature (tính năng): "Người dùng có thể đặt hàng và áp dụng mã giảm giá." — Đây là cái mà hệ thống làm được, là khả năng người dùng tương tác.
  • Business rule (quy tắc): "Mã giảm giá chỉ áp dụng cho đơn hàng từ 200.000đ trở lên, không cộng dồn với chương trình flash sale, và hết hạn sau 30 ngày kể từ ngày phát hành." — Đây là logic chi phối hành vi đó hoạt động như thế nào.
Một feature thường được điều khiển bởi nhiều business rule. Một business rule có thể ảnh hưởng đến nhiều feature. Đó là mối quan hệ nhiều-nhiều, và đó chính là lý do bạn phải tách chúng ra — nếu nhét rule vào trong mô tả feature, bạn sẽ lặp lại cùng một logic ở chục chỗ khác nhau, và khi business thay đổi một con số, bạn phải đi sửa cả chục chỗ.

Vì sao phải tách rule ra khỏi feature

Lý do quan trọng nhất: business rules thay đổi với tần suất khác với feature. Tính năng "áp voucher" có thể ổn định nhiều năm, nhưng con số "đơn tối thiểu 200.000đ" có thể đổi mỗi quý theo chiến dịch marketing. Nếu bạn trộn rule vào feature, mỗi lần marketing đổi ngưỡng, bạn lại phải mở lại toàn bộ tài liệu feature, dev lại phải sửa code rải rác.

Khi tách riêng, bạn có một Business Rules Catalog (danh mục quy tắc) — nơi mỗi rule có một mã định danh (ví dụ BR-VOUCHER-01), có chủ sở hữu (owner), có nguồn gốc (source: ai quyết định), và có thể tham chiếu từ nhiều requirement. Thay đổi một rule chỉ cần sửa một dòng trong catalog.

4 loại business rule

Đây là khung phân loại kinh điển (tham khảo từ Business Rules Group và BABOK). Hiểu đúng loại giúp bạn viết rule chính xác và biết đặt nó ở đâu.

1. Definitional rules (Quy tắc định nghĩa) — Định nghĩa một khái niệm nghiệp vụ. Chúng tạo ra "từ điển chung" cho cả team.

  • Ví dụ: "Khách VIP là khách hàng có tổng giá trị đơn hoàn tất trong 12 tháng gần nhất từ 50 triệu đồng trở lên."
  • Loại này trả lời câu hỏi "X nghĩa là gì?". Khi bạn nói "khách VIP được giảm 10%", trước hết phải định nghĩa rõ VIP là ai.
2. Constraint rules (Quy tắc ràng buộc) — Giới hạn điều gì được/không được phép. Thường có dạng "phải", "không được", "chỉ khi".
  • Ví dụ: "Một tài khoản không được rút quá 50 triệu đồng trong 24 giờ." hoặc "Không được hủy đơn hàng đã chuyển sang trạng thái đang giao."
  • Đây là loại QA bạn quen nhất — chính là các điều kiện biên (boundary) mà bạn từng test.
3. Derivation rules (Quy tắc dẫn xuất / tính toán) — Quy định cách tính ra một giá trị từ các giá trị khác.
  • Ví dụ: "Phí ship = 30.000đ nếu đơn dưới 300.000đ; miễn phí nếu từ 300.000đ trở lên." hoặc "Điểm thưởng = 1% giá trị đơn hàng, làm tròn xuống."
  • Loại này hay bị bỏ sót vì mọi người nghĩ "dev tự biết tính". Không. Bạn phải viết rõ công thức và quy tắc làm tròn.
4. Action-enabler rules (Quy tắc kích hoạt hành động) — Khi điều kiện X xảy ra thì hệ thống thực hiện hành động Y.
  • Ví dụ: "Khi đơn hàng quá 48 giờ chưa thanh toán, hệ thống tự động hủy đơn và hoàn kho." hoặc "Khi số dư kho của sản phẩm xuống dưới 10, gửi cảnh báo cho quản lý kho."
  • Đây là loại liên quan đến trigger và automation, rất hay xuất hiện trong các hệ thống có workflow.

Nguyên tắc viết một business rule tốt

Một business rule chuẩn phải: declarative (mô tả "cái gì đúng/sai", không mô tả "code làm thế nào"), atomic (một rule một ý, không gộp), độc lập với cách triển khai (không nói tới màn hình, nút bấm hay API cụ thể), và có thể kiểm chứng (testable — đúng tinh thần QA của bạn). Mỗi rule nên có mã định danh và được phát biểu bằng ngôn ngữ nghiệp vụ, không phải ngôn ngữ kỹ thuật.

Tình huống thực tế

Tình huống 1 — Tiki và mớ bòng bong "miễn phí ship"

Giả định bạn là BA tại một sàn TMĐT lớn theo mô hình Tiki. Tài liệu requirement ban đầu của tính năng giỏ hàng viết thế này: "Hệ thống áp dụng miễn phí vận chuyển cho khách hàng đủ điều kiện."

Với con mắt QA cũ, bạn lập tức thấy lỗ hổng. "Đủ điều kiện" là gì? Bạn ngồi xuống cùng product owner và bóc tách ra được sáu business rule riêng biệt:

  • BR-SHIP-01 (definitional): "Đơn hàng đủ điều kiện freeship khi tổng giá trị sản phẩm — chưa gồm phí ship, chưa trừ voucher — từ 250.000đ."
  • BR-SHIP-02 (constraint): "Chỉ áp dụng cho giao hàng nội thành các tỉnh/thành loại 1."
  • BR-SHIP-03 (constraint): "Không áp dụng cho sản phẩm hàng cồng kềnh (nội thất, điện máy lớn)."
  • BR-SHIP-04 (derivation): "Với khách TikiNOW Smart member, ngưỡng freeship hạ xuống 0đ cho 4 đơn đầu tháng."
  • BR-SHIP-05 (constraint): "Freeship không cộng dồn với mã giảm phí ship khác; hệ thống chọn ưu đãi có lợi nhất cho khách."
  • BR-SHIP-06 (definitional): "Tổng giá trị tính freeship dựa trên giá sau khuyến mãi sản phẩm, không tính giá niêm yết gốc."
Diễn giải: Một câu requirement mơ hồ đã nở ra thành sáu rule có mã, có loại, có thể test từng cái một. Quan trọng hơn, BR-SHIP-01 và BR-SHIP-04 đụng nhau (ngưỡng 250k vs 0đ) — nếu không tách ra, mâu thuẫn này sẽ bị giấu kín cho đến khi production nổ bug. Khi tách riêng, mâu thuẫn lộ ra ngay trên giấy, và bạn xử lý nó bằng BR-SHIP-05 (quy tắc ưu tiên).

Bài học: Đúng tinh thần QA — "đơn dưới 250.000đ, đúng 250.000đ, và 250.001đ" là ba boundary phải làm rõ. Khi bạn viết rule, hãy ghi rõ "từ 250.000đ" (bao gồm hay không bao gồm chính con số đó). Sự mơ hồ ở dấu "≥" hay ">" là nguồn bug kinh điển mà bạn đã từng bắt cả trăm lần.

Tình huống 2 — Ngân hàng số và rule rút tiền nằm rải khắp code

Một ngân hàng số kiểu Timo hoặc Cake thuê đội outsource Việt Nam phát triển tính năng chuyển tiền. Ban đầu, các điều kiện hạn mức được dev "hardcode" rải rác trong code: chỗ này kiểm tra 100 triệu/giao dịch, chỗ kia kiểm tra 300 triệu/ngày, một service khác lại kiểm tra OTP với giao dịch trên 10 triệu.

Khi Ngân hàng Nhà nước cập nhật quy định yêu cầu xác thực sinh trắc học cho giao dịch trên 10 triệu (đúng theo Quyết định 2345 áp dụng từ 2024), team mất hai tuần chỉ để tìm xem rule "10 triệu" nằm ở những đâu trong code.

Là BA mới, bạn lập một Business Rules Catalog tách bạch:

LoạiPhát biểuOwnerNguồn
BR-TXN-01ConstraintHạn mức mỗi giao dịch ≤ 100 triệuPhòng Vận hànhChính sách nội bộ
BR-TXN-02ConstraintTổng giao dịch/ngày ≤ 300 triệuPhòng Vận hànhChính sách nội bộ
BR-TXN-03Action-enablerGiao dịch > 10 triệu → bắt buộc xác thực sinh trắc họcPhòng Tuân thủQĐ 2345/NHNN
Diễn giải: Giờ đây mỗi rule có owner và nguồn gốc rõ ràng. Khi NHNN đổi ngưỡng từ 10 triệu xuống 5 triệu, BA chỉ sửa một dòng BR-TXN-03 trong catalog, dev biết chính xác cần đụng vào module nào (vì requirement tham chiếu đúng mã rule), và QA biết chính xác test case nào cần cập nhật.

Bài học: Business rule có nguồn gốc và chủ sở hữu khác nhau. BR-TXN-01 do phòng vận hành quyết — họ có thể nới lỏng. BR-TXN-03 do luật quy định — không ai trong công ty được tự ý đổi. Việc ghi rõ "source" giúp BA biết rule nào có thể đàm phán, rule nào là bất di bất dịch. Đây là điều mà tư duy QA thuần túy chưa chạm tới, nhưng là cốt lõi của tư duy BA.

Tình huống 3 — Edtech và rule "hoàn thành khóa học" bị trộn vào feature

Một nền tảng học trực tuyến (giả định tương tự một startup edtech Việt) viết requirement: "Khi học viên hoàn thành khóa học, cấp chứng chỉ." Nghe đơn giản. Nhưng "hoàn thành" được định nghĩa thẳng trong logic của màn hình bài học — và mỗi đội phát triển module khác nhau lại hiểu khác nhau. Module video coi "hoàn thành" là xem hết 90% thời lượng; module quiz coi là đạt 70% điểm; module bài tập coi là nộp bài.

Khi marketing tung chương trình "học xong nhận chứng chỉ", học viên phàn nàn ầm ầm vì người thì có chứng chỉ, người thì không, dù làm y hệt nhau.

BA tách ra một definitional rule trung tâm: BR-CERT-01: "Khóa học được coi là hoàn thành khi học viên (a) xem tối thiểu 80% thời lượng tất cả video, (b) đạt tối thiểu 70% mỗi bài quiz, và (c) nộp toàn bộ bài tập bắt buộc." Và một derivation rule: BR-CERT-02: "Tỷ lệ hoàn thành khóa = trung bình có trọng số: video 40%, quiz 40%, bài tập 20%."

Diễn giải: Định nghĩa "hoàn thành" giờ là một rule duy nhất, được mọi module tham chiếu, thay vì ba định nghĩa ngầm mâu thuẫn.

Bài học: Definitional rules là loại dễ bị bỏ qua nhất vì ai cũng nghĩ "hoàn thành thì ai chẳng hiểu". Nhưng "ai cũng hiểu" thường nghĩa là "mỗi người hiểu một kiểu". Nhiệm vụ của BA là biến cái ngầm hiểu thành cái thành văn.

Hướng dẫn từng bước

Đây là quy trình tách business rules ra khỏi feature mà bạn có thể áp dụng ngay:

Bước 1 — Đọc requirement và gạch chân các "động từ chi phối". Tìm những từ như "nếu", "khi", "chỉ", "phải", "không được", "tối thiểu", "tối đa", "tính bằng". Mỗi từ này là dấu hiệu của một business rule đang ẩn náu trong câu mô tả feature.

Bước 2 — Đặt câu hỏi QA cho từng điểm mơ hồ. Với mỗi điều kiện, hỏi: Boundary chính xác là bao nhiêu? Bao gồm hay loại trừ giá trị biên? Điều gì xảy ra khi nhiều điều kiện đụng nhau? Có ngoại lệ không? Đây là lúc cơ bắp QA của bạn phát huy.

Bước 3 — Phân loại mỗi rule vào 1 trong 4 loại. Definitional, constraint, derivation, hay action-enabler. Việc phân loại buộc bạn phát biểu rule đúng dạng và đặt nó đúng chỗ trong tài liệu.

Bước 4 — Gán mã và metadata. Mỗi rule một mã (BR-[MODULE]-[số]), một owner, một nguồn gốc, và trạng thái (active/draft/deprecated). Đưa vào một bảng Business Rules Catalog tập trung.

Bước 5 — Viết rule ở dạng declarative, không nhắc triển khai. Đúng: "Đơn từ 250.000đ được freeship." Sai: "Khi user bấm nút Checkout, hệ thống gọi API tính tổng rồi so với 250000." Rule không nói về nút bấm hay API.

Bước 6 — Liên kết ngược về requirement. Trong tài liệu feature, thay vì viết lại logic, hãy tham chiếu: "Tính phí ship theo BR-SHIP-01 đến BR-SHIP-06." Một nguồn sự thật duy nhất (single source of truth).

Bước 7 — Rà mâu thuẫn và lỗ hổng. Đặt các rule cạnh nhau, tìm cặp xung đột (như ngưỡng 250k vs 0đ ở tình huống 1) và các trường hợp chưa rule nào phủ. Bổ sung rule ưu tiên khi cần.

Lỗi thường gặp & mẹo

Lỗi 1 — Trộn rule vào mô tả tính năng. Viết "hệ thống cho phép áp voucher cho đơn trên 200k không cộng dồn flash sale hết hạn 30 ngày" trong một câu dài. Khó đọc, khó test, khó sửa. Mẹo: tách thành các rule độc lập, mỗi rule một dòng có mã.

Lỗi 2 — Viết rule mang tính kỹ thuật. "Khi field total_amount > 200000 thì set flag eligible = true." Đó là pseudo-code, không phải business rule. Mẹo: phát biểu bằng ngôn ngữ mà trưởng phòng kinh doanh đọc cũng hiểu.

Lỗi 3 — Gộp nhiều ý vào một rule. "Khách VIP được giảm 10% và miễn phí ship và ưu tiên CSKH." Ba rule trộn làm một. Mẹo: atomic — mỗi rule một ý duy nhất để test và thay đổi độc lập.

Lỗi 4 — Bỏ qua derivation và definitional rule. Mọi người nhớ constraint (vì nó dễ thấy) nhưng quên định nghĩa khái niệm và công thức tính. Mẹo: mỗi khi gặp một danh từ nghiệp vụ ("VIP", "đơn hợp lệ", "hoàn thành"), hỏi ngay "đã có rule định nghĩa nó chưa?".

Lỗi 5 — Không ghi owner và source. Rồi không ai biết được phép đổi rule nào. Mẹo: phân biệt rule do nội bộ quyết (đàm phán được) và rule do luật/regulator quyết (bất biến).

Mẹo vàng dùng lợi thế QA: Khi tách rule xong, hãy thử viết nhanh một test case cho mỗi rule trong đầu. Nếu bạn không thể nghĩ ra cách test một rule, thì rule đó còn mơ hồ — quay lại làm rõ. Khả năng "ngửi" ra rule chưa testable chính là siêu năng lực bạn mang từ QA sang.

Bài tập thực hành

Đề bài: Bạn nhận requirement sau từ một ứng dụng đặt đồ ăn kiểu ShopeeFood/GrabFood:

> "Người dùng có thể đặt món và thanh toán. Đơn được giao bởi tài xế gần nhất. Khách thân thiết được ưu đãi. Nếu quán quá tải thì tạm đóng nhận đơn."

Yêu cầu:

  • Gạch chân và liệt kê ít nhất 6 business rule đang ẩn trong đoạn này. Với mỗi rule, tự bổ sung con số/điều kiện hợp lý (vì requirement gốc còn mơ hồ — đó là điểm bạn phải làm rõ với stakeholder).
  • Phân loại mỗi rule vào 1 trong 4 loại (definitional / constraint / derivation / action-enabler).
  • Gán mã định danh theo dạng BR-[MODULE]-[số] và ghi owner giả định cho từng rule.
  • Chỉ ra ít nhất 1 cặp rule có khả năng mâu thuẫn và đề xuất một rule ưu tiên để giải quyết.
  • Với rule "khách thân thiết được ưu đãi", viết một definitional rule làm rõ "khách thân thiết" là ai.
Gợi ý chấm điểm bản thân: Một bài tốt sẽ có ít nhất một rule mỗi loại trong bốn loại, mọi con số biên đều rõ "bao gồm/loại trừ", và mỗi rule đều testable. Nếu bạn viết được rule mà ngay lập tức hình dung ra test case cho nó — bạn đã làm đúng.

Tóm tắt

  • Business rule chi phối behavior, không phải là feature. Một feature được điều khiển bởi nhiều rule; một rule ảnh hưởng nhiều feature — quan hệ nhiều-nhiều, nên phải tách riêng.
  • Tách rule ra khỏi feature vì rule thay đổi với tần suất khác, và để có một nguồn sự thật duy nhất (Business Rules Catalog) dễ sửa, dễ tham chiếu.
  • 4 loại rule: Definitional (định nghĩa khái niệm), Constraint (ràng buộc cho/không cho phép), Derivation (công thức tính), Action-enabler (điều kiện kích hoạt hành động).
  • Rule tốt: declarative, atomic, không nhắc triển khai, testable, có mã + owner + source.
  • Lợi thế QA của bạn: con mắt soi boundary và edge case giúp bạn phát hiện rule ẩn, làm rõ giá trị biên, và bắt mâu thuẫn ngay trên giấy trước khi nó thành bug. Phân biệt rule "đàm phán được" (nội bộ) với rule "bất biến" (luật/regulator) là tư duy BA mới mà bạn cần bồi đắp thêm.
Khi bạn thành thạo việc tách business rules, requirement của bạn sẽ trong veo, dev không phải đoán, QA test nhàn tênh — và bạn đã đi được một bước dài từ người viết test case sang người kiến trúc tư duy nghiệp vụ.