ADR-0001. Phát hành subpath ./contracts gần như chỉ chứa kiểu, thay vì gắn pricing như một component
| Trường | Giá trị |
|---|---|
| Trạng thái | Accepted |
| Ngày | 2026-03 |
| Người quyết định | Phat Nguyen |
| Thay thế | - |
Bối cảnh
- Sale phải tính giá giỏ hàng lúc checkout, nhưng pricing là một service chạy độc lập với DB schema, Kafka consumer và calculator riêng.
- Gắn pricing như một component IGNIS nhúng bên trong sale sẽ kéo theo repository, Kafka component và sự ràng buộc DB của pricing vào tiến trình của sale.
- Sale vẫn cần các kiểu request/response chặt chẽ, cùng một vài hằng số runtime (ví dụ
TransactionDirections.SALE, các key củaPartyRoles) để dựng request và đọc ledgerbyBearertrong snapshot.
Quyết định
Pricing cung cấp một export subpath chuyên dụng @nx/pricing/contracts (src/contracts/index.ts), phần lớn là các khai báo export type, kèm một tập nhỏ các const container runtime đã đóng băng (AppliedRuleSourceTypes, FareSourceTypes, FeeScopes, PartyRoles, RuleBasises, Snapshot{Discount,Fee,Tax}Types, TransactionDirections). Sale gọi pricing qua HTTP (PricingNetworkService, xác thực BASIC) và chỉ import từ subpath này. Sale không bao giờ gắn pricing như một component.
Hệ quả
| Ưu điểm | Nhược điểm |
|---|---|
| Sale chỉ kèm các kiểu có thể xoá khi biên dịch + vài bảng const nhỏ - không có runtime của pricing trong bundle | Hai service phải luôn kết nối được lúc checkout (thêm một lượt gọi mạng) |
| Ranh giới service rõ ràng; pricing có thể phát triển phần lõi tự do | Const container vẫn là một phụ thuộc runtime thật (dù nhỏ) cần quản lý version |
| An toàn kiểu xuyên qua ranh giới HTTP mà không cần một package schema dùng chung | Lệch contract chỉ phát hiện được lúc type-check, không phải khi truyền trên đường truyền |
Các phương án đã cân nhắc
| Phương án | Ưu điểm | Nhược điểm | Vì sao loại |
|---|---|---|---|
| Gắn pricing như một component nhúng trong sale | Không phải gọi mạng | Kéo ràng buộc DB/Kafka/repo vào sale; phá vỡ sự cô lập của service | Phá vỡ thiết kế service độc lập |
Chia sẻ mọi kiểu chỉ qua @nx/core | Một nơi duy nhất cho các kiểu | Các cấu trúc snapshot nội bộ của pricing không thuộc về core | Làm nhiễu core với các contract riêng của engine |
| Contract thuần kiểu (không có const runtime) | Không phụ thuộc runtime nào | Sale sẽ phải tự khai báo lại các giá trị TransactionDirections / PartyRoles, dễ gây sai lệch | Trùng lặp còn tệ hơn một export const đã đóng băng |
Tham chiếu
pricing/src/contracts/index.tssale/src/services/pricing-network.service.tssale/src/services/checkout.service.ts