PRD: Khuyến mãi, phương thức & quy tắc phân khúc
| Module | Định giá | PRD ID | PRD-PROMO-001 |
| Trạng thái | Sẵn sàng dev | FEAT | PROMO |
| Epic | — | Plane | BANA-1573 |
| Ngày | 2026-06-15 | Phiên bản | v1.0 |
| Gói | @nx/pricing | URD | PROMO |
| Surface | Client · Chủ/QL | ||
| Phụ trách | Phát Nguyễn | ||
Khuyến mãi, phương thức & quy tắc phân khúc là gì
Feature này cho phép merchant cấu hình một chiến dịch giảm giá như một đối tượng độc lập, hoàn chỉnh: một khuyến mãi (Promotion) mang đúng một phương thức (Promotion Method) - số tiền cố định hoặc phần trăm; nhắm vào dòng hàng, cả đơn hàng, hoặc vận chuyển; phân bổ theo từng món, trải đều, hoặc một lần - và một cơ chế: giảm thẳng (tiêu chuẩn) hoặc deal mua-X-tặng-Y (mua-tặng). Ba tập quy tắc phân khúc chiến dịch: điều kiện quyết định ai/khi nào đủ điều kiện, nguồn quyết định cần mua gì, đích quyết định cái gì được giảm. Toàn bộ đồ thị - khuyến mãi, phương thức, cả ba tập quy tắc - được tạo và sửa trong một aggregate nguyên tử; số đếm quy tắc được lưu lúc tạo và chưa được tính lại khi cập nhật aggregate.
Việc áp giảm giá khi thanh toán là một bước sau này có chủ đích; PRD này đặc tả aggregate cấu hình khuyến mãi - khuyến mãi, phương thức và ba tập quy tắc.
Vì sao cần một đối tượng khuyến mãi hạng nhất
Định giá đã chọn fare (FARE) và tính thuế (TAX), nhưng merchant chưa có cách diễn đạt một chiến dịch giảm giá - "giảm 10% đồ uống trước 17h", "mua 2 cà phê tặng 1", "giảm 50.000₫ cho đơn trên 300.000₫". Một chiến dịch không phải là một fare: nó trải trên nhiều dòng hàng, có thể nhắm vào đơn hàng hoặc vận chuyển thay vì một món, và phải nói không chỉ giảm bao nhiêu mà còn ai đủ điều kiện, cái gì kích hoạt, và cái gì được giảm.
Không có đối tượng khuyến mãi hạng nhất, chủ merchant hoàn toàn không thể dựng các ưu đãi này, và dữ liệu cần để áp chúng khi thanh toán cũng không tồn tại. Bước tăng trưởng này lấp khoảng trống cấu hình: cho chủ merchant một khuyến mãi với một phương thức, một cơ chế tiêu chuẩn hoặc mua-tặng, và ba tập quy tắc riêng biệt, tất cả được soạn và sửa như một đơn vị nguyên tử - nên một chiến dịch luôn được lưu trọn vẹn hoặc không lưu gì cả, không bao giờ dựng dở.
Một ví dụ từ đầu tới cuối
| Bước | Việc xảy ra | Kết quả |
|---|---|---|
| Chủ merchant tạo khuyến mãi "Mua 2 cà phê, tặng 1" | Gửi một request duy nhất: cơ chế mua-tặng, một phương thức phần trăm giá trị 100 nhắm dòng hàng (nguồn-tối-thiểu 2, đích 1), một quy tắc nguồn (đồ uống đủ điều kiện), một quy tắc đích (đồ uống được tặng), một quy tắc điều kiện giới hạn kênh dùng tại chỗ | Khuyến mãi, phương thức và cả ba quy tắc được lưu cùng nhau trong một lần gọi nguyên tử; số đếm quy tắc đọc lại đúng |
| Sau đó chủ merchant sửa lại chiến dịch | Gửi một cập nhật aggregate: bỏ quy tắc kênh, nâng giới hạn lượt dùng | Toàn bộ thay đổi được lưu trong một lần lưu nguyên tử duy nhất |
Chỗ dễ sai nhất
Số đếm quy tắc không tự cập nhật khi sửa aggregate
Số đếm quy tắc điều kiện / nguồn / đích được ghi một lần lúc tạo aggregate. Cập nhật aggregate về sau - thêm, sửa, hoặc xóa quy tắc - chưa tính lại các con số này, nên số đếm hiển thị có thể lệch khỏi số quy tắc thực sự đang lưu sau một lần sửa.