Skip to content

ADR-0005. Capture snapshot pricing (v1 + v2) khi checkout vào order item

TrườngGiá trị
Trạng tháiAccepted
Ngày2026-03-20
Người quyết địnhsale-team, pricing-team
Thay thế

Bối cảnh

  • Quy tắc pricing trong @nx/pricing thay đổi thường xuyên — khuyến mãi, hiệu chỉnh giá, override fare.
  • Hóa đơn POS phát hành phải phản ánh giá tại thời điểm checkout — không phải giá live 3 tuần sau khi accounting đối chiếu.
  • Pricing v1 trả về điểm giá đơn giản. v2 trả về object snapshot phong phú với rule trace, mức discount đã áp dụng, chi tiết quy đổi tiền tệ.

Quyết định

Tại checkout (CheckoutService.checkout), sale gọi PricingNetworkService.calculate() (v1) VÀ calculateV2() (v2) cho item của order. Cả hai kết quả được lưu trên mỗi SaleOrderItem:

  • unitPrice ← kết quả v1 (giá bán hiển thị)
  • priceMetadata (jsonb) ← snapshot v2 với pricing trace đầy đủ
  • fareId, fareProvider ← tham chiếu tới rule đã định giá dòng

Snapshot v2 là source-of-truth cho refund, audit, và khai thuế. v1 là cái khách thấy.

Hệ quả

ƯuNhược
Hóa đơn bất biến sau checkoutĐộ trễ pricing call nhân đôi
Audit trail đầy đủ per dòngpriceMetadata jsonb phình to
Thay đổi rule không bao giờ ảnh hưởng order quá khứPricing service phải đến được khi checkout
Refund biết chính xác discount nào đã áp dụngLogic refund phải đọc snapshot v2, không re-call pricing

Phương án thay thế đã cân nhắc

Phương ánƯuNhượcLý do từ chối
Chỉ lưu unitPrice (không snapshot)Storage nhỏ hơnKhông audit được rule nào áp dụngKhông đủ cho refund và thuế
Re-call pricing mỗi lần đọcLuôn "fresh"Refund phản ánh giá hiện tại, không phải giá đã trảSai từ thiết kế
Snapshot chỉ khi order hoàn tấtStorage trước thanh toán nhỏ hơnMất pricing nếu order bị hủy trước khi hoàn tấtKhoảng trống audit

Tham chiếu

  • sale/src/services/checkout.service.ts
  • sale/src/services/pricing-network.service.ts
  • core/src/models/schemas/sale/sale-item/schema.ts (priceMetadata, fareId, fareProvider)

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.