URD: Định giá
| Module | CORE-14 | Phiên bản | v0.1 |
|---|---|---|---|
| Trạng thái | Built | Ngày | 2026-06-05 |
Tài liệu nghiệp vụ. URD này là danh sách feature của Định giá - mỗi feature bên dưới là một Functional Area (
<AREA>). Cùng<AREA>đó làm khóa cho PRD (PRD-<AREA>-NNN) và kiểm thử (TC-<AREA>-NNN) của feature, và mỗi feature được liệt kê trong danh mục feature Bàn giao. Xem quy ước Feature Spine.
1. Mục đích
Xác định các yêu cầu hướng người dùng cho bộ máy Định giá - cách một merchant đặt giá, cách tính thuế, cách theo dõi giá vốn biến thể và cách cấu hình khuyến mãi. Kết quả là mọi dòng hàng và mọi đơn hàng đều được định giá nhất quán và có thể kiểm toán, cả khi chủ cửa hàng cấu hình lẫn khi luồng bán hàng hỏi giá lúc thanh toán.
2. Phạm vi
| Bao gồm | Loại trừ |
|---|---|
| Fare set, fare, phân cấp fare cha/con | Lưu trữ đơn hàng |
| Chọn fare theo quy tắc (số lượng, thời gian, kênh) | Phát hành hóa đơn / hóa đơn điện tử |
| Tax set, thuế, loại thuế | Thay đổi tồn kho |
| Tính thuế gộp, đã gộp/chưa gộp, theo thứ tự ưu tiên | Xử lý thanh toán |
| Thuế cấp dòng hàng và cấp đơn hàng | Định giá đa tiền tệ |
| Theo dõi giá vốn biến thể theo khoảng thời gian hiệu lực | Tính giảm giá trong thanh toán (bộ tính chưa có) |
| Mô phỏng định giá (v1 phẳng + v2 ảnh chụp) | Đặc tả API kỹ thuật |
| Khuyến mãi, phương thức khuyến mãi, quy tắc điều kiện |
3. Định nghĩa
| Thuật ngữ | Định nghĩa |
|---|---|
| Fare Set | Bộ chứa toàn bộ fare cho một biến thể sản phẩm. Mỗi biến thể có một fare set ở trạng thái kích hoạt. |
| Fare | Một bản ghi giá. Fare mặc định là giá gốc; fare cha/con tạo thành một nhóm chọn lựa. |
| Fare mặc định | Giá gốc dự phòng, dùng khi không có fare con theo quy tắc nào khớp. |
| Fare cha / con | Fare cha xác định chiến lược chọn (OVERRIDE hoặc DISCOUNT); fare con mang giá có điều kiện. |
| Quy tắc | Một điều kiện (thuộc tính, toán tử, giá trị) gắn vào fare con hoặc khuyến mãi; mọi quy tắc phải đạt (logic AND). |
| Tax Set | Bộ chứa toàn bộ thuế cho một biến thể hoặc một merchant. |
| Thuế | Một khoản theo phần trăm, cố định hoặc kết hợp, kèm mức ưu tiên, khoảng thời gian và các cờ đã gộp/chưa gộp/lũy tiến. |
| Loại thuế | Một danh mục (vd: VAT, GST) - phạm vi toàn hệ thống hoặc theo merchant. |
| Giá vốn | Giá vốn của một biến thể sản phẩm theo khoảng thời gian hiệu lực; một bản ghi là giá vốn hiện tại. |
| Ảnh chụp định giá | Kết quả v2 bất biến, có thể kiểm toán: mọi fare và thuế đã áp theo từng dòng hàng, cùng tổng đơn hàng. |
| Khuyến mãi | Một chiến dịch giảm giá do merchant cấu hình, có một phương thức và các quy tắc điều kiện. |
| Phương thức khuyến mãi | Cơ chế của khuyến mãi (cách áp giảm giá). |
4. Mô hình Khái niệm
Chỉ mang tính khái niệm - schema đầy đủ nằm trong mô hình miền của tài liệu kỹ thuật.
5. Danh mục Feature
Danh sách feature của module này. Mỗi dòng là một feature (một Functional Area). Chi tiết ở §6. Được phản chiếu trong danh mục feature Bàn giao.
| Feature ID | Tính năng | Phase | Trạng thái | Ưu tiên |
|---|---|---|---|---|
FARE | Fare & Fare Set | P1 | Built | High |
TAX | Tính thuế | P1 | Built | High |
COST | Theo dõi giá vốn | P2 | Built | High |
SIM | Mô phỏng & Xem trước định giá | P2 | Built | High |
PROMO | Khuyến mãi & Quy tắc | P3 | In-progress | Medium |
Trạng thái: live từ Plane nếu có map, còn lại do registry khai báo. Vocabulary đồng nhất với Plane (state-group / phase).
6. Các Feature
Mỗi mục con cho một feature, theo thứ tự danh mục. Mỗi feature giữ chung mô tả, yêu cầu và tiêu chí chấp nhận. Mức ưu tiên = MoSCoW (Must / Should / Could / Won't).
FARE - Fare & Fare Set Built
Feature ID: pricing/FARE · Phase: P1 · PRDs: Bộ máy định giá Fare & Thuế · Dev: @nx/pricing · Fare System
Người dùng được gì: chủ cửa hàng đặt giá gốc cho từng biến thể và, tùy chọn, các giá con có điều kiện theo quy tắc (số lượng, khung giờ, kênh). Bộ máy tự chọn fare thắng - fare con hợp lệ đầu tiên cho nhóm OVERRIDE, hoặc fare con hợp lệ rẻ nhất cho nhóm DISCOUNT, quay về fare mặc định khi cần.
Yêu cầu
| ID | P | Yêu cầu |
|---|---|---|
| URD-FARE-001 | M | Mỗi biến thể sản phẩm có đúng một fare set ở trạng thái kích hoạt. |
| URD-FARE-002 | M | Một fare set + fare mặc định được tạo tự động khi tạo một biến thể sản phẩm (CDC). |
| URD-FARE-003 | M | Chủ cửa hàng có thể đặt một fare mặc định (giá gốc) cho từng biến thể. |
| URD-FARE-004 | M | Chủ cửa hàng có thể tạo một fare cha với một trong hai chiến lược: OVERRIDE hoặc DISCOUNT. |
| URD-FARE-005 | M | Chủ cửa hàng có thể thêm các fare con dưới một fare cha, mỗi fare có giá riêng. |
| URD-FARE-006 | M | Fare con có thể mang quy tắc (thuộc tính, toán tử, giá trị) được đánh giá theo logic AND. |
| URD-FARE-007 | M | OVERRIDE: fare con hợp lệ đầu tiên được chọn ngay lập tức. |
| URD-FARE-008 | M | DISCOUNT: fare con hợp lệ có giá thấp nhất được chọn. |
| URD-FARE-009 | M | Khi không có fare con nào hợp lệ, fare mặc định được chọn. |
| URD-FARE-010 | S | Fare hỗ trợ khoảng thời gian hiệu lực (từ / đến) và giới hạn số lượng. |
| URD-FARE-011 | M | Fare và fare set được cô lập theo merchant và dùng xóa mềm. |
Chấp nhận
AC-FARE-01: Chọn theo quy tắc
| Cho | Khi | Thì |
|---|---|---|
| Biến thể có mặc định 100 và một fare con DISCOUNT 80 (quy tắc: số lượng ≥ 10) | Định giá 12 đơn vị | Fare con 80 thắng (hợp lệ và thấp nhất) |
| Cùng biến thể | Định giá 5 đơn vị | Fare mặc định 100 thắng (không quy tắc nào khớp) |
AC-FARE-02: Tự khởi tạo khi có biến thể
| Cho | Khi | Thì |
|---|---|---|
| Một biến thể sản phẩm mới | Sự kiện CDC của biến thể tới | Một fare set + fare mặc định được tạo tự động |
TAX - Tính thuế Built
Feature ID: pricing/TAX · Phase: P1 · PRDs: Bộ máy định giá Fare & Thuế · Dev: @nx/pricing · Tax System
Người dùng được gì: chủ cửa hàng gắn thuế vào một biến thể (cấp dòng hàng) hoặc một merchant (cấp đơn hàng), chọn mức phần trăm/cố định, cách xử lý đã gộp hay chưa gộp, và thuế lũy tiến chồng thuế. Bộ máy áp chúng theo thứ tự ưu tiên và trả về bản phân rã rõ ràng.
Yêu cầu
| ID | P | Yêu cầu |
|---|---|---|
| URD-TAX-001 | M | Chủ cửa hàng có thể tạo loại thuế (vd: VAT), phạm vi toàn hệ thống hoặc theo merchant. |
| URD-TAX-002 | M | Chủ cửa hàng có thể tạo một tax set và thêm thuế vào đó (cập nhật aggregate). |
| URD-TAX-003 | M | Một thuế có thể theo phần trăm, cố định hoặc kết hợp (phần trăm + cố định). |
| URD-TAX-004 | M | Thuế áp theo thứ tự ưu tiên (số nhỏ hơn = ưu tiên cao hơn). |
| URD-TAX-005 | M | Một thuế có thể chưa gộp (cộng thêm bên trên) hoặc đã gộp (tính ngược từ giá). |
| URD-TAX-006 | M | Một thuế có thể lũy tiến (tính trên tổng đang chạy đã gồm các thuế trước đó). |
| URD-TAX-007 | S | Một thuế có thể mang khoảng thời gian hiệu lực và điều kiện số lượng tối thiểu/tối đa. |
| URD-TAX-008 | M | Thuế cấp dòng hàng áp theo từng dòng; thuế cấp đơn hàng áp cho các tax set theo phạm vi merchant. |
| URD-TAX-009 | M | Một mức thuế mặc định được áp khi không có tax set nào được cấu hình. |
| URD-TAX-010 | M | Tax set và thuế được cô lập theo merchant và dùng xóa mềm. |
Chấp nhận
AC-TAX-01: Đã gộp và chưa gộp
| Cho | Khi | Thì |
|---|---|---|
| Giá 110, một thuế 10% chưa gộp | Tính | Thuế 11; tổng 121 |
| Giá 110, một thuế 10% đã gộp | Tính | Thuế ≈ 10; tổng giữ ở 110 (tính ngược) |
AC-TAX-02: Lũy tiến theo thứ tự
| Cho | Khi | Thì |
|---|---|---|
| Hai thuế (10% rồi 5% lũy tiến) trên cơ sở 100 | Tính | 10 đầu → cơ sở 110 → 5,5; tổng thuế 15,5 |
COST - Theo dõi giá vốn Built
Feature ID: pricing/COST · Phase: P2 · PRDs: - · Dev: @nx/pricing · Cost Tracking
Người dùng được gì: chủ cửa hàng ghi nhận giá vốn của từng biến thể theo thời gian. Cập nhật giá vốn hiện tại sẽ kết thúc bản ghi giá vốn trước và mở một bản ghi mới, nên lịch sử giá vốn đầy đủ được giữ lại cho biên lợi nhuận và báo cáo.
Yêu cầu
| ID | P | Yêu cầu |
|---|---|---|
| URD-COST-001 | M | Chủ cửa hàng có thể ghi nhận giá vốn cho một biến thể sản phẩm với khoảng thời gian hiệu lực. |
| URD-COST-002 | M | Chủ cửa hàng có thể đọc giá vốn hiện tại của một biến thể. |
| URD-COST-003 | M | Cập nhật giá vốn hiện tại sẽ kết thúc bản ghi trước và tạo một bản ghi mới. |
| URD-COST-004 | M | Tại mọi thời điểm, mỗi biến thể có nhiều nhất một giá vốn hiện tại (chưa kết thúc). |
| URD-COST-005 | S | Lịch sử giá vốn được giữ lại và truy xuất được. |
| URD-COST-006 | M | Giá vốn được cô lập theo merchant và dùng xóa mềm. |
Chấp nhận
AC-COST-01: Cập nhật giá vốn hiện tại
| Cho | Khi | Thì |
|---|---|---|
| Biến thể có giá vốn hiện tại 50 | Chủ cửa hàng đặt giá vốn hiện tại thành 60 | Bản ghi 50 trước đó được kết thúc; 60 trở thành giá vốn hiện tại |
| Cùng biến thể | Đọc giá vốn hiện tại | Trả về 60 |
SIM - Mô phỏng & Xem trước định giá Built
Feature ID: pricing/SIM · Phase: P2 · PRDs: Mô phỏng định giá & xem trước giá đơn hàng · Dev: @nx/pricing · Simulation
Người dùng được gì: luồng bán hàng định giá cả một giỏ hàng mà không cam kết một đơn. Hai endpoint không trạng thái phục vụ việc đó - một bản phân rã phẳng v1 (fare, thuế, tổng theo dòng + tổng đơn) để hiển thị trực tiếp, và một ảnh chụp bất biến, kiểm toán được v2 (một ảnh chụp đơn cộng một ảnh chụp theo từng dòng, kèm sổ cái theo bên) nhằm được lưu trên đơn. Một xem trước chỉ-đọc cho khách thấy giá trước khi thanh toán; lúc thanh toán v1 (chuẩn) và v2 (bổ sung, best-effort) chạy cùng nhau để đơn được định giá và ảnh chụp được nắm bắt.
Yêu cầu
| ID | P | Yêu cầu |
|---|---|---|
| URD-SIM-001 | M | Một mô phỏng không trạng thái định giá một giỏ 1-100 dòng và trả về tổng theo dòng và theo đơn mà không lưu đơn hay thay đổi tồn kho. |
| URD-SIM-002 | M | Mô phỏng v1 (/simulation) trả về một bản phân rã phẳng - theo dòng: giá gốc, giá đơn vị, fare đã chọn + quy tắc fare đã áp, thuế đã áp, số lượng, subtotal, discount, tax, total; cùng subtotal/discount/tax/total của đơn và một mốc thời gian tính. |
| URD-SIM-003 | M | Một id dòng do bên gọi cấp được trả lại và dùng làm khóa kết quả, để mỗi dòng đã định giá ánh xạ rõ ràng về dòng yêu cầu của nó. |
| URD-SIM-004 | M | Thuế đã gộp được nhúng vào giá và không bao giờ làm tăng tổng; thuế chưa gộp được cộng thêm bên trên - nhất quán với bộ máy thuế. |
| URD-SIM-005 | M | Mô phỏng v2 (/simulation-v2) trả về một ảnh chụp bất biến, kiểm toán được - một ảnh chụp đơn cộng một ảnh chụp theo từng dòng - mang mọi quyết định đã áp (giá, thuế, giảm giá, phí). |
| URD-SIM-006 | M | Mỗi quyết định đã áp của v2 sao chép nhãn, cơ sở, giá trị và khoản của nó tại thời điểm tính, để hiển thị lịch sử vẫn đúng kể cả khi quy tắc nguồn về sau bị đổi tên hay ngừng kích hoạt. |
| URD-SIM-007 | M | Một ảnh chụp dòng v2 phơi ra tổng sẵn-để-đọc - buyer-payable cộng một sổ cái theo bên (mua/bán/nền tảng/nhà cung cấp/nhà nước) - và ảnh chụp đơn cuộn chúng vào subtotal, buyer-payable, sổ cái theo bên, và seller liability. |
| URD-SIM-008 | M | Một mô phỏng v2 khai báo một hướng giao dịch - SALE hoặc PURCHASE - và một tiền tệ đơn (ISO 4217, mặc định VND). |
| URD-SIM-009 | M | Xem trước giá đơn hàng (POST /sale-orders/{id}/pricing/preview) định giá lại một đơn đang có theo kiểu chỉ-đọc - không lưu, không đổi trạng thái - và trả về bản phân rã v1. |
| URD-SIM-010 | M | Định giá một giỏ rỗng bị từ chối. |
| URD-SIM-011 | S | Lúc thanh toán đơn được định giá với v1 (chuẩn) cộng v2 (bổ sung, best-effort); một lỗi v2 được log và bỏ qua và không bao giờ chặn thanh toán. |
| URD-SIM-012 | S | Thuế đã áp được lưu theo dòng trộn các mục VAT của v1 với các mục PIT của v2. |
| URD-SIM-013 | M | Ngữ cảnh định giá mỗi dòng mang số lượng, thời điểm tính, thứ/giờ/ngày, các id biến thể của giỏ (cho quy tắc đồng xuất hiện), và một khung dịch vụ suy ra (giờ dịch vụ, ngày, thứ, thời lượng), để quy tắc fare đánh giá. |
| URD-SIM-014 | M | Khi dịch vụ định giá thượng nguồn từ chối một dòng (vd: không có fare set kích hoạt), luồng bán hàng phơi ra trạng thái và lý do thật thay vì một lỗi chung chung. |
| URD-SIM-015 | M | Cả hai endpoint mô phỏng yêu cầu xác thực và một phạm vi merchant, và mọi phép tính định giá dùng độ chính xác thập phân. |
| URD-SIM-016 | M | v1 và v2 chia sẻ cùng logic fare và thuế lõi, nên một bản sửa đáp ở cả hai. |
Chấp nhận
AC-SIM-01: Bản phân rã & tổng v1
| Cho | Khi | Thì |
|---|---|---|
| Một giỏ 2 dòng định giá được | POST /simulation/calculate | Mỗi dòng trả về giá gốc/đơn vị, fare đã chọn, thuế đã áp, và tổng dòng; đơn trả về subtotal/discount/tax/total và một mốc thời gian tính |
| Một dòng mang thuế 10% đã gộp | Cùng lệnh | Thuế đó được nhúng vào giá và không làm tăng tổng đơn |
AC-SIM-02: Trả lại & khóa theo id dòng
| Cho | Khi | Thì |
|---|---|---|
| Các món mỗi món mang một id dòng do bên gọi cấp | Định giá qua v1 | Bản đồ kết quả được khóa theo id đó và trả lại nó trên mỗi dòng |
AC-SIM-03: Ảnh chụp bất biến v2
| Cho | Khi | Thì |
|---|---|---|
| Một giỏ N dòng | POST /simulation-v2/calculate | Trả về một ảnh chụp đơn cộng N ảnh chụp dòng; mỗi dòng mang một PRICE cộng các mục thuế của nó, buyer-payable, và một sổ cái theo bên |
| Ảnh chụp đơn | Cùng lệnh | Cuộn lên subtotal, buyer-payable, sổ cái theo bên, và seller liability |
AC-SIM-04: Xem trước là chỉ-đọc
| Cho | Khi | Thì |
|---|---|---|
| Một đơn đang có với các món | POST /sale-orders/{id}/pricing/preview | Bản phân rã v1 trả về và trạng thái cùng dữ liệu đã lưu của đơn không đổi |
AC-SIM-05: Giỏ rỗng bị từ chối
| Cho | Khi | Thì |
|---|---|---|
| Một đơn không có món | Định giá (xem trước) | Từ chối - một giỏ rỗng không thể định giá |
AC-SIM-06: v2 best-effort lúc thanh toán
| Cho | Khi | Thì |
|---|---|---|
| Định giá lúc thanh toán nơi phép tính v2 lỗi | Đơn được định giá | Kết quả v1 vẫn trả về và thanh toán tiếp tục; lỗi v2 được log và bỏ qua |
AC-SIM-07: Từ chối thượng nguồn được phơi ra
| Cho | Khi | Thì |
|---|---|---|
| Một dòng có biến thể không có fare set kích hoạt | Định giá | Trạng thái và lý do thật từ thượng nguồn được phơi ra (không phải một lỗi 500 chung chung) |
PROMO - Khuyến mãi & Quy tắc In-progress
Feature ID: pricing/PROMO · Phase: P3 · PRDs: Khuyến mãi, phương thức & quy tắc phân khúc · Dev: @nx/pricing · Promotion System
Người dùng được gì: chủ cửa hàng định nghĩa các chiến dịch khuyến mãi - một khuyến mãi mang đúng một phương thức (cố định hoặc phần trăm; nhắm vào dòng hàng, đơn hàng, hoặc vận chuyển; kèm chiến lược phân bổ), một cơ chế tiêu chuẩn hoặc mua-tặng, và ba tập quy tắc phân khúc ai đủ điều kiện (điều kiện), cái gì phải mua (nguồn), và cái gì được giảm (đích). CRUD và aggregate (khuyến mãi + phương thức + mọi tập quy tắc) đã có hôm nay; bộ tính giảm giá áp khuyến mãi khi thanh toán chưa được đấu nối vào luồng định giá.
Yêu cầu
| ID | P | Yêu cầu |
|---|---|---|
| URD-PROMO-001 | M | Chủ cửa hàng có thể tạo một khuyến mãi với một phương thức và các quy tắc trong một thao tác aggregate. |
| URD-PROMO-002 | M | Chủ cửa hàng có thể cập nhật một aggregate khuyến mãi (phương thức + quy tắc: thêm/sửa/xóa). |
| URD-PROMO-003 | M | Một khuyến mãi có nhiều nhất một phương thức khuyến mãi. |
| URD-PROMO-004 | S | Quy tắc điều kiện dùng cùng mô hình quy tắc như fare (thuộc tính, toán tử, giá trị, logic AND). |
| URD-PROMO-005 | M | Khuyến mãi, phương thức và quy tắc được cô lập theo merchant và dùng xóa mềm. |
| URD-PROMO-006 | W | Giảm giá khuyến mãi được áp tự động trong quá trình định giá lúc thanh toán (bộ tính chưa có - chưa đấu nối). |
| URD-PROMO-007 | M | Một khuyến mãi khai báo một cơ chế - STANDARD (giảm giá thẳng) hoặc BUY_GET (mua-X-tặng-Y) - mặc định là STANDARD. |
| URD-PROMO-008 | M | Phương thức duy nhất khai báo cách tính giảm giá: FIXED (số tiền giảm) hoặc PERCENTAGE (phần trăm giảm), mang giá trị giảm. |
| URD-PROMO-009 | M | Phương thức khai báo nơi giảm giá rơi vào qua kiểu đích: ITEMS, ORDER, hoặc SHIPPING. |
| URD-PROMO-010 | S | Phương thức khai báo chiến lược phân bổ - EACH (theo từng món), ACROSS (trải đều các món), hoặc ONCE (một món). |
| URD-PROMO-011 | S | Phương thức có thể giới hạn số đơn vị được giảm qua giới hạn số lượng tối đa. |
| URD-PROMO-012 | M | Phương thức BUY_GET khai báo số lượng nguồn tối thiểu (phải mua) và số lượng đích (được giảm). |
| URD-PROMO-013 | M | Quy tắc cấp phương thức chia thành quy tắc nguồn (phải mua gì) và quy tắc đích (cái gì được giảm), gắn theo ngữ cảnh, bên cạnh quy tắc điều kiện của khuyến mãi. |
| URD-PROMO-014 | M | Số đếm quy tắc điều kiện, nguồn và đích được denormalized trên khuyến mãi và phương thức và luôn chính xác khi quy tắc được thêm hoặc bỏ. |
| URD-PROMO-015 | S | Một khuyến mãi mang một mã tùy chọn; khuyến mãi không mã chỉ là tự động (auto-apply), và mã là duy nhất theo merchant trong số các khuyến mãi còn sống. |
| URD-PROMO-016 | S | Một khuyến mãi mang một cờ stacking kiểm soát việc nó có thể kết hợp với khuyến mãi khác, và một cờ đã-gồm-thuế. |
| URD-PROMO-017 | S | Một khuyến mãi mang khoảng hiệu lực từ / đến, một giới hạn lượt dùng, và một số lượt dùng đang chạy. |
| URD-PROMO-018 | M | Một khuyến mãi đi qua trạng thái vòng đời - DRAFT, ACTIVATED, DEACTIVATED, EXPIRED, hoặc ARCHIVED - mặc định là DRAFT. |
| URD-PROMO-019 | M | Trong một cập nhật aggregate mỗi mục quy tắc được diễn giải theo hình dạng: không id tạo, id-kèm-trường sửa, chỉ-id xóa; một quy tắc được tạo phải mang thuộc tính, toán tử và kiểu dữ liệu. |
| URD-PROMO-020 | M | Xóa một khuyến mãi lan truyền tới phương thức và mọi quy tắc đính kèm (điều kiện, nguồn, đích) trong một transaction. |
Chấp nhận
AC-PROMO-01: Aggregate khuyến mãi
| Cho | Khi | Thì |
|---|---|---|
| Chủ cửa hàng gửi một khuyến mãi + phương thức + 2 quy tắc | Tạo | Khuyến mãi, phương thức và cả hai quy tắc được lưu cùng nhau |
| Chủ cửa hàng bỏ một quy tắc qua cập nhật aggregate | Lưu | Quy tắc đó bị xóa mềm; phần còn lại được giữ |
AC-PROMO-02: Mua-tặng với quy tắc nguồn/đích
| Cho | Khi | Thì |
|---|---|---|
| Một khuyến mãi BUY_GET: một phương thức PERCENTAGE (giá trị 100, nguồn-tối-thiểu 2, đích 1) + 1 quy tắc nguồn + 1 quy tắc đích | Tạo qua aggregate | Khuyến mãi, phương thức, quy tắc nguồn và quy tắc đích được lưu cùng nhau; số đếm quy tắc nguồn và đích mỗi cái đọc ra 1 |
AC-PROMO-03: Trộn quy tắc aggregate theo hình dạng
| Cho | Khi | Thì |
|---|---|---|
| Một khuyến mãi đang có với hai quy tắc điều kiện | Cập nhật aggregate gửi một quy tắc có id+trường, một chỉ có id, một không id | Cái đầu được sửa, cái thứ hai bị xóa, cái thứ ba được tạo - trong một transaction; số đếm quy tắc vẫn chính xác |
| Một quy tắc được tạo thiếu thuộc tính / toán tử / kiểu dữ liệu | Cập nhật aggregate được lưu | Cả aggregate bị từ chối và rollback |
AC-PROMO-04: Tính duy nhất của mã & tự động
| Cho | Khi | Thì |
|---|---|---|
| Một khuyến mãi còn sống với mã SUMMER | Tạo một khuyến mãi còn sống khác với mã SUMMER | Từ chối - mã là duy nhất theo merchant trong số các khuyến mãi chưa xóa |
| Một khuyến mãi không có mã | Lưu | Nó chỉ là tự động (auto-apply) |
7. Ràng buộc & Phi mục tiêu
Các yêu cầu xuyên suốt (
CON) áp dụng cho mọi feature ở trên và được kiểm thử dưới dạngTC-CON-*.
Yêu cầu xuyên suốt (CON)
| ID | P | Yêu cầu |
|---|---|---|
| URD-CON-001 | M | Mọi endpoint định giá yêu cầu xác thực (JWT hoặc basic auth). |
| URD-CON-002 | M | Mọi bản ghi được giới hạn theo merchant qua header merchant và dùng xóa mềm. |
| URD-CON-003 | M | Giá trị tiền tệ dùng độ chính xác thập phân (4 chữ số) trong toàn bộ phép tính. |
| URD-CON-004 | M | Ảnh chụp định giá (v2) bất biến sau khi đã tính. |
Ràng buộc
| ID | Ràng buộc |
|---|---|
| C-01 | Đúng một fare set ở trạng thái kích hoạt cho mỗi biến thể sản phẩm. |
| C-02 | Nhiều nhất một giá vốn hiện tại (chưa kết thúc) cho mỗi biến thể tại một thời điểm. |
| C-03 | Thuế áp theo thứ tự ưu tiên tăng dần; thuế đã gộp không bao giờ làm tăng tổng. |
| C-04 | Phép tính tiền dùng độ chính xác float(value, 4). |
| C-05 | Mọi bản ghi được cô lập theo merchant và xóa mềm. |
| C-06 | v1 (/simulation) và v2 (/simulation-v2) chia sẻ logic fare/thuế lõi; bản sửa phải đáp ở cả hai. |
Phi mục tiêu
- Định giá đa tiền tệ
- Một bộ tính giảm giá đấu nối vào thanh toán (thực thể đã có; chưa áp)
- Lưu trữ đơn hàng, phát hành hóa đơn, tác động lên tồn kho hoặc thanh toán
8. Lịch sử Phiên bản
| Ngày | Tác giả | Mô tả | Phiên bản |
|---|---|---|---|
| 2026-06-05 | Claude (AI pair) | URD ban đầu từ phân tích code @nx/pricing; feature spine FARE / TAX / COST / PROMO | v0.1 |
| 2026-06-15 | Nhóm Định giá | Thêm feature SIM - mô phỏng định giá (v1 phẳng + v2 ảnh chụp) & xem trước giá đơn hàng | v0.2 |