PRD: Quyền lợi - policy, target, grant & redemption
| Module | Bán hàng (CORE-07) | PRD ID | PRD-ENT-001 |
| Trạng thái | Shipped | Chủ sở hữu | Nhóm Bán hàng |
| Ngày | 2026-06-15 | Phiên bản | v1.0 |
| Packages | @nx/sale · @nx/core | URD | ENT |
TL;DR
Cho phép merchant bán thứ mà khách dùng dần theo thời gian - combo 10 ly cà phê, vé tập 30 ngày, gói lớp học, gói nạp phút tính theo lượng - rồi trừ dần về 0. Merchant định nghĩa một policy (bán gì, hạn mức và hiệu lực), khoanh phạm vi bằng target (áp cho món nào), và ngay khi variant quyền lợi được bán, hệ thống đúc ra một grant: một số dư theo từng khách, đóng băng một bản chụp của policy để chỉnh sửa catalog về sau không bao giờ động tới một vé đã bán. Mỗi lần dùng ghi một redemption vào grant - một sổ chỉ-thêm trừ dần bộ đếm đã-dùng, kiểm tra món được dùng so với phạm vi đã đóng băng, và hỗ trợ đảo (reversal) trả lại hạn mức. Vòng đời grant (chờ → hoạt động → cạn / hết hạn / tạm ngưng / huỷ) cho mọi người biết chính xác khách còn lại bao nhiêu.
1. Bối cảnh & Vấn đề
POS bán những món được tiêu thụ tức thì. Nhưng merchant ngày càng bán quyền hưởng giá trị tương lai: combo đồ uống trả trước, một kỳ membership, thẻ đục lỗ, một khối phút dịch vụ. Không thứ nào hợp với một dòng đơn một-lần - khách trả một lần rồi rút giá trị dần qua nhiều lượt ghé sau, mỗi lượt phải kiểm "còn số dư không, còn hiệu lực không, có áp cho món này không?".
Thiếu một mô hình hạng nhất cho việc này, merchant chắp vá bằng ghi chú thủ công hoặc mã giảm giá - không theo dõi số dư, không hết hạn, không kiểm toán ai dùng gì lúc nào, và không bảo vệ được combo đã bán khỏi việc âm thầm thay đổi khi catalog bị sửa. Hệ quả là tranh cãi, thất thoát, và không có cách trả lời "khách này còn mấy buổi?".
Increment này ship hệ quyền lợi (entitlements) như một phần khép kín trong module Bán hàng. Nó tách mẫu merchant cấu hình (policy + target) khỏi bản đã bán khách giữ (grant), và ghi mỗi lần dùng thành một redemption bất biến để số dư luôn kiểm toán được và điều khoản đã bán luôn được tôn trọng đúng như lúc bán.
2. Mục tiêu & Không thuộc mục tiêu
Mục tiêu
- Một policy biến một variant bán được thành quyền lợi với trục hạn mức, trục hiệu lực, chế độ kích hoạt và các chiều giới hạn đã khai báo.
- Target khoanh việc grant của một policy được dùng cho món nào - phạm vi rỗng nghĩa là mở.
- Một grant được đúc khi variant quyền lợi được bán, mang mã duy nhất, số dư hạn mức, cửa sổ hiệu lực đã giải, và một bản chụp policy đóng băng để chỉnh sửa catalog không bao giờ làm thay đổi grant đã bán.
- Một sổ redemption trừ dần bộ đếm đã-dùng của grant, kiểm tra món được dùng so với phạm vi đã đóng băng, và hỗ trợ đảo trả lại hạn mức.
- Một vòng đời grant - chờ, hoạt động, cạn, hết hạn, tạm ngưng, huỷ - luôn cho biết người giữ còn gì.
Không thuộc mục tiêu
- Định giá variant quyền lợi - giá nằm ở fare (Sản phẩm); PRD này bàn cấp gì, không bàn giá bao nhiêu.
- Thu tiền và checkout đơn - thuộc Đơn hàng và Thanh toán; grant đúc từ một đơn đã hoàn tất, nó không chạy việc bán.
- Tích điểm loyalty (PNT) - một cơ chế thưởng riêng; quyền lợi là số dư đã bán, không phải điểm tích.
- Màn ví hướng khách để duyệt số dư còn lại - số dư được ghi và truy vấn được; màn cho người dùng cuối là increment sau.
3. Chỉ số Thành công
| Chỉ số | Mục tiêu / tín hiệu |
|---|---|
| Độ chính xác số dư | Số dư khả dụng của grant luôn bằng tổng hạn mức trừ tổng các redemption của nó |
| Toàn vẹn bản chụp | Một policy sửa sau khi bán không bao giờ làm thay đổi điều khoản của một grant đã bán |
| An toàn phạm vi | Một redemption vào món ngoài phạm vi đóng băng của grant bị từ chối (trừ khi phạm vi mở) |
| Đầy đủ kiểm toán | Mọi thay đổi hạn mức truy về một mục redemption chỉ-thêm - không sửa số dư âm thầm |
| Trung thực vòng đời | Grant đã dùng hết đọc là EXHAUSTED; grant quá cửa sổ đọc là EXPIRED |
4. Chân dung & Tình huống
| Chân dung | Mục tiêu trong tính năng |
|---|---|
| Chủ / Quản lý | Cấu hình thứ bán dưới dạng quyền lợi - hạn mức, hiệu lực, phạm vi - và đọc số dư còn lại |
| Thu ngân | Bán một quyền lợi và trừ số dư của khách tại điểm bán chỉ một chạm |
| Khách hàng | Mua một combo / vé một lần và rút dần qua nhiều lượt ghé, yên tâm điều khoản không đổi |
Tình huống chính: chủ cấu hình policy "10 Cà phê" trên variant tương ứng - hạn mức 10 cup, không hết hạn, kích hoạt khi mua, khoanh vào nhóm cà phê qua target. Một khách mua; hệ thống đúc grant mã ENT-…, số dư 10, trạng thái ACTIVE, và đóng băng policy + target vào grant. Mỗi lượt sau thu ngân trừ một ly: một redemption đẩy bộ đếm đã-dùng lên 1, 2, … 10; tới 10 grant lật sang EXHAUSTED. Một lần trừ nhầm được sửa bằng một đảo trả lại một ly và mở lại số dư.
5. User Story
- Là chủ, tôi khai một variant bán được thành quyền lợi kèm hạn mức và hạn dùng tuỳ chọn, để bán combo và vé.
- Là chủ, tôi khoanh quyền lợi vào các món nó áp, để vé cà phê không xài được cho đồ ăn.
- Là chủ, tôi tin sửa catalog sau này không bao giờ làm thay đổi vé khách đã mua.
- Là thu ngân, tôi trừ một lần dùng của số dư khách chỉ một chạm, và thấy còn lại bao nhiêu.
- Là thu ngân, tôi đảo một redemption mình lỡ tay, và số dư quay về.
- Là khách, tôi mua một lần và rút giá trị dần qua nhiều lượt, và vé chỉ hết hạn khi cửa sổ của nó nói vậy.
6. Yêu cầu Chức năng
| # | Yêu cầu | URD ref |
|---|---|---|
| FR-1 | Một policy gắn 1:1 với một variant bán được và khai các chiều giới hạn (đếm / cửa sổ thời gian / đo lượng) | URD-ENT-001..002 |
| FR-2 | Một policy mang hạn mức tuỳ chọn (lượng + đơn vị) và thời lượng hiệu lực tuỳ chọn; có thể vắng một trong hai trục | URD-ENT-003 |
| FR-3 | Một policy khai chế độ kích hoạt - khi mua, khi dùng lần đầu, hoặc theo lịch - chi phối khi nào hiệu lực bắt đầu | URD-ENT-004 |
| FR-4 | Một policy có thể yêu cầu gắn khách hàng, hoặc cho phép quyền lợi vô danh (bearer) | URD-ENT-005 |
| FR-5 | Target khoanh một policy vào các món cụ thể; tập target rỗng nghĩa là truy cập mở | URD-ENT-006..007 |
| FR-6 | Bán variant quyền lợi đúc một grant với mã duy nhất, số dư hạn mức, và cửa sổ hiệu lực đã giải | URD-ENT-008 |
| FR-7 | Grant đóng băng một bản chụp policy và target của nó tại thời điểm bán, cô lập khỏi sửa catalog về sau | URD-ENT-009 |
| FR-8 | Grant theo dõi tổng hạn mức so với đã-dùng (bộ đếm đã-dùng là nguồn sự thật; khả dụng = tổng − đã-dùng) | URD-ENT-010 |
| FR-9 | Grant chuyển qua chờ → hoạt động → cạn / hết hạn / tạm ngưng / huỷ | URD-ENT-011 |
| FR-10 | Một redemption trừ bộ đếm đã-dùng cho một số lượng và được ghi theo đơn / mục tiêu thụ nó | URD-ENT-012 · URD-ENT-016 |
| FR-11 | Một redemption với số lượng đơn vị khác đơn vị hạn mức của grant được quy đổi qua tỉ lệ đơn vị | URD-ENT-013 |
| FR-12 | Một redemption kiểm món được dùng so với phạm vi target đóng băng của grant (mở khi không có target) | URD-ENT-014 |
| FR-13 | Một đảo trả lại hạn mức cho grant; sổ là chỉ-thêm - sửa lỗi là mục mới | URD-ENT-015 |
| FR-14 | Mọi policy, target, grant, và redemption đều giới hạn theo merchant và soft-delete | URD-ENT-017 |
Toàn văn yêu cầu và tiêu chí nghiệm thu nằm trong URD Bán hàng - ENT. PRD này tham chiếu thay vì lặp lại.
7. Yêu cầu Phi chức năng
| Lĩnh vực | Yêu cầu |
|---|---|
| Nguồn sự thật | Bộ đếm đã-dùng của grant là thẩm quyền cho số dư; redemption là sổ kiểm toán đối soát phía sau |
| Bất biến | Sổ redemption là chỉ-thêm; sửa lỗi là một mục đảo, không bao giờ sửa hay xoá một redeem trước đó |
| Cô lập bản chụp | Điều khoản của grant lấy từ bản chụp policy đóng băng lúc bán - không đọc lại trực tiếp - nên sửa catalog không thể làm đổi grant đã bán |
| Phạm vi từ bản chụp | Redemption kiểm target từ bản chụp đã denormalize của grant, không tra cứu target trực tiếp |
| Tenancy & phân quyền | Mọi thao tác giới hạn theo merchant (x-merchant-id) và kiểm soát bởi quyền entitlement |
| Độ chính xác | Hạn mức và số lượng redemption dùng độ chính xác thập phân; redemption khác đơn vị quy đổi qua tỉ lệ đơn vị |
| i18n | Tên và mô tả policy song ngữ ({ en, vi }) |
8. UX & Luồng
Màn cấu hình cho chủ định nghĩa policy trên variant quyền lợi (hạn mức, hiệu lực, kích hoạt, phạm vi qua target). Màn điểm bán bán quyền lợi, tra grant của khách, hiện số dư còn lại, trừ một lần dùng, và đảo khi cần.
9. Dữ liệu & Miền
| Thực thể | Vai trò |
|---|---|
EntitlementPolicy | Mẫu merchant cấu hình - gắn 1:1 với một variant bán được; mang hạn mức, hiệu lực, chế độ kích hoạt, cờ yêu-cầu-khách, và các chiều giới hạn |
EntitlementTarget | Một ràng buộc phạm vi của policy vào một món cụ thể (mặc định variant), có thứ tự; phạm vi rỗng = truy cập mở |
EntitlementGrant | Bản đã bán khách giữ - mã duy nhất, số dư tổng / đã-dùng, cửa sổ hiệu lực, trạng thái vòng đời, và một bản chụp policy + target đóng băng |
EntitlementRedemption | Một mục sổ chỉ-thêm vào grant - một redeem hoặc một đảo, với số lượng, đơn vị, và đơn / mục tiêu thụ |
Chỉ ở mức khái niệm - schema và bất biến đầy đủ nằm trong mô hình miền Bán hàng. Tham chiếu chéo schema (variant, đơn, khách) là soft reference; toàn vẹn được thực thi ở tầng service.
10. Phụ thuộc & Giả định
Phụ thuộc
- Đơn bán hàng (ORD) - một grant đúc từ một lượt bán hoàn tất của variant quyền lợi; redemption tham chiếu đơn / mục tiêu thụ.
- Sản phẩm (Sản phẩm) - một policy gắn với một variant bán được, và target khoanh vào món trong catalog.
- Đơn vị tính (Kho) - hạn mức và số lượng redemption mang một đơn vị; redemption khác đơn vị quy đổi qua tỉ lệ đơn vị.
@nx/core- các model policy / target / grant / redemption và schema giới hạn theo merchant.
Giả định
- Merchant cấu hình một policy trước khi bán variant của nó; bán một variant chưa cấu hình thì không đúc grant.
- Khách được định danh khi policy yêu cầu (quyền lợi định danh); quyền lợi vô danh có thể bỏ khách.
- Bộ đếm hạn mức trên grant và sổ redemption được giữ nhất quán bởi service áp mỗi redemption.
11. Rủi ro & Câu hỏi mở
| Rủi ro / câu hỏi | Giảm thiểu / trạng thái |
|---|---|
| Sửa catalog âm thầm làm đổi vé đã bán | Đã giải - grant đóng băng bản chụp policy + target lúc bán; điều khoản đọc từ bản chụp, không bao giờ trực tiếp |
| Số dư và sổ có thể lệch | Bộ đếm đã-dùng là nguồn sự thật; redemption đối soát nó; đảo (không sửa) giữ sổ chỉ-thêm |
| Trừ vào món ngoài phạm vi | Bị từ chối - redemption kiểm món so với phạm vi target đóng băng; truy cập mở chỉ khi bản chụp không có target |
| Khách trừ ở đơn vị khác hạn mức | Số lượng được quy đổi qua tỉ lệ đơn vị trước khi trừ bộ đếm |
| Trần redemption theo ngày | Ngoài phạm vi increment này - trường trần-theo-ngày được mang trên policy cho kiểm tra runtime sau |
12. Kế hoạch Phát hành & Tiêu chí Ra mắt
| Khía cạnh | Kế hoạch |
|---|---|
| Phase | P2 - ENT trong danh mục tính năng URD |
| Triển khai | Mọi merchant; không feature flag |
| Di trú | Chỉ bảng mới (policy, target, grant, redemption); không đổi luồng đơn hiện có |
| Tiêu chí ra mắt | Bán variant đúc một grant với bản chụp đóng băng; redeem trừ số dư và cạn ở 0; đảo trả lại hạn mức; redemption ngoài phạm vi bị từ chối; mọi thứ giới hạn theo merchant |
| Giám sát | Đối soát số dư grant vs sổ, tỉ lệ từ chối redemption theo lý do (ngoài phạm vi, cạn, hết hạn), grant theo trạng thái vòng đời |
13. FAQ
Tôi bán gì được dưới dạng quyền lợi? Bất cứ thứ gì khách rút dần theo thời gian - combo đồ uống, vé lớp học, một kỳ membership, một khối phút tính theo lượng. Bạn gắn một policy vào variant và đặt hạn mức cùng hiệu lực của nó.
Sửa policy sau này có đổi vé đã bán không? Không. Mỗi grant đóng băng một bản chụp policy và phạm vi của nó lúc bán và đọc điều khoản từ bản chụp đó, nên sửa catalog không bao giờ làm đổi một grant đã bán.
Số dư còn lại được theo dõi thế nào? Grant mang một bộ đếm đã-dùng (nguồn sự thật); mỗi lần dùng thêm một redemption vào sổ kiểm toán đối soát nó. Khả dụng là tổng hạn mức trừ phần đã dùng.
Khách có xài vé cà phê cho đồ ăn được không? Chỉ khi policy được khoanh cho phép. Một redemption kiểm món so với phạm vi target đóng băng của grant; phạm vi rỗng nghĩa là truy cập mở, còn lại món ngoài phạm vi bị từ chối.
Nếu thu ngân trừ nhầm thì sao? Họ ghi một đảo - một sửa lỗi chỉ-thêm trả lại hạn mức. Redeem gốc không bao giờ bị sửa hay xoá.
Khi nào grant hết hạn hoặc cạn? Nó đọc EXHAUSTED khi bộ đếm đã-dùng chạm tổng hạn mức, và EXPIRED khi qua cửa sổ hiệu lực - cửa sổ bắt đầu khi mua, khi dùng lần đầu, hoặc một ngày theo lịch tuỳ chế độ kích hoạt của policy.
Tham chiếu
- URD: Bán hàng - ENT
- PRD liên quan: Đơn bán hàng & giỏ hàng · Tích điểm tích lũy trên đơn
- Module: Bán hàng - tổng quan + năng lực
- Developer: @nx/sale · @nx/core