ADR-0002. TaxInfo có thẩm quyền, nguồn từ Merchant CDC - không phải metadata.tax của commerce
| Trường | Giá trị |
|---|---|
| Status | Accepted |
| Date | 2026-04-08 |
| Deciders | Phat Nguyen |
| Supersedes | - |
Bối cảnh
- Định danh thuế merchant (MST: taxCode, fullName, address, mã hành chính) được nhập trong
@nx/commercedưới dạngMerchant.metadata.tax. - Invoice service cần một bản ghi thuế đã chuẩn hoá, truy vấn được, có relation (
tax.TaxInfo) cho payload phát hành và hiển thị FE. metadata.taxlà jsonb tự do trên một service khác - không phù hợp làm bản ghi có thẩm quyền mà domain invoice đọc từ đó.- Before-image của Debezium không đáng tin cho phát hiện thay đổi (phụ thuộc REPLICA IDENTITY của bảng).
Quyết định
Chúng ta sẽ coi metadata.tax là chỉ input và tax.TaxInfo (principalType=Merchant) là bản ghi có thẩm quyền.
InvoiceWorkerService.handleMerchantCDC tiêu thụ topic CDC của Merchant; TaxInfoService.syncTaxInfo upsert TaxInfo. Với op=u, nó so sánh thông tin thuế mới đến với TaxInfo đã lưu (không phải before-image của Debezium) và bỏ qua khi không có thay đổi. Frontend đọc relation merchant.taxInfo, không bao giờ đọc metadata.tax.
Hệ quả
| Ưu | Nhược |
|---|---|
| Một bản ghi thuế có thẩm quyền, có relation | Nhất quán cuối cùng - phụ thuộc độ trễ CDC |
| Phát hiện thay đổi đúng bất kể REPLICA IDENTITY | Thêm một lần đọc (nạp TaxInfo đã lưu) mỗi cập nhật |
| FE/phát hành tách khỏi cấu trúc jsonb của commerce | Tồn tại hai cách biểu diễn "thuế" (input + có thẩm quyền) |
| Tái gửi idempotent (không thay đổi → bỏ qua) | Yêu cầu pipeline Debezium hoạt động tốt |
Phương án đã cân nhắc
| Phương án | Ưu | Nhược | Vì sao loại |
|---|---|---|---|
Đọc metadata.tax trực tiếp lúc phát hành | Không cần CDC | Ràng buộc jsonb xuyên service; không chuẩn hoá | Mong manh; FE không relation-join được |
| Tin vào before-image của Debezium để so sánh | Không phát sinh thêm lần đọc | Không đáng tin nếu không bật FULL replica identity | Gây bỏ qua/cập nhật sai |
| Gọi HTTP đồng bộ tới commerce mỗi lần phát hành | Luôn lấy được dữ liệu mới nhất | Tăng độ trễ + ràng buộc tính sẵn sàng | Phá vỡ thiết kế event-driven |
Tham chiếu
src/services/invoice-worker.service.ts(handleMerchantCDC,_resyncMerchantTaxInfoIfChanged,_isTaxInfoUpToDate)src/services/tax-info.service.ts(syncTaxInfo)packages/core/src/models/schemas/tax/tax-info/schema.ts- Xem thêm: Integration §3.1