Skip to content

ADR-0005. Lưu trữ UoM - uom jsonb trên danh mục + uomId tham chiếu mềm trên dòng

TrườngGiá trị
Trạng tháiAccepted
Ngày2026-04-05
Người quyết địnhPhat Nguyen
Thay thế-

Bối cảnh

  • Material có nhiều vai trò UoM: base (đơn vị lưu kho, ví dụ gram), purchase (đơn vị trên hóa đơn vendor, ví dụ kg), sale (đơn vị hiển thị, ví dụ phần).
  • PurchaseOrderItem, VendorItem, MaterialRecipeItem, InventoryTracking mỗi loại có một ngữ cảnh UoM duy nhất trên mỗi dòng.
  • FK chặt từ các bảng dòng tới UnitOfMeasure rất mong manh: các dòng UoM là dữ liệu tham chiếu và có thể bị soft-delete hoặc đổi khóa bởi merchant.

Quyết định

Lưu trữ hai lớp:

  1. Thực thể danh mục (Material, ProductVariant) lưu các vai trò trong một cột jsonb uom có dạng:
    ts
    type TUomRoles = {
      base: { id: string; code: string; name: I18n; ratio: number };
      purchase?: { ... };
      sale?: { ... };
    };
  2. Thực thể dòng (PurchaseOrderItem, VendorItem, MaterialRecipeItem, InventoryTracking) lưu uomId: text như một tham chiếu mềm cộng với multiplier: decimal(15,4). Khai báo relations() trong model.ts cung cấp accessor uom cho truy vấn; DB không có foreign key.

Hệ quả

Ưu điểmNhược điểm
Snapshot danh mục ổn định - kể cả khi UoM của merchant bị xóa, Material.uom vẫn cònCần kiểm tra ở tầng service rằng uomId phân giải được lúc ghi
Thực thể dòng tách rời khỏi vòng đời UnitOfMeasureKhông có toàn vẹn tham chiếu ở cấp DB cho uomId
multiplier được chốt lúc ghi dòng → quy đổi đơn vị bất biến về sauPhải nhớ hai dạng lưu trữ (jsonb so với uomId)
Lập luận khi phát lại/kiểm toán hoạt động mà không cần join UnitOfMeasureBáo cáo phải cẩn thận dùng multiplier cấp dòng, không phải uom cấp danh mục

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

Phương ánƯu điểmNhược điểmLý do từ chối
FK chặt uomId → UnitOfMeasure.id ở mọi nơiToàn vẹn tham chiếuVỡ khi soft-delete UoM; mong manh khi merchant ghi đèSai primitive cho dữ liệu tham chiếu
Một jsonb trên mỗi thực thể dòngKhông lo FK mong manhLặp dữ liệu UoM trên mỗi dòng; khó truy vấn "tất cả dòng đơn vị kg"Lãng phí lưu trữ, khổ khi truy vấn
UnitOfMeasure có phiên bản theo dòng (không soft-delete)ID ổn địnhThay đổi thiết kế lớn, không giải quyết nhu cầu snapshot multiplierNgoài phạm vi

Tham chiếu

  • core/src/models/schemas/inventory/material/schema.ts (uom jsonb)
  • core/src/models/schemas/inventory/purchase-order-item/schema.ts (uomId tham chiếu mềm + quan hệ uom trong model.ts)
  • Memory: feedback_uom_storage_convention.md

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