Skip to content

ADR-0001. Cấp phát thuế dựa trên CDC với đối soát idempotent

FieldValue
StatusAccepted
Date2026-04-01
DecidersPhat Nguyen
Supersedes-

Bối cảnh

  • Commerce sở hữu Product (gồm cả taxGroupId); taxation không được gọi commerce đồng bộ mỗi lần ghi sản phẩm.
  • Thuế phải luôn nhất quán khi sản phẩm được tạo, đổi tax group, mất tax group, hoặc bị xoá.
  • Debezium đã phát luồng thay đổi public.Product; tái dùng luồng này giúp tránh phải định nghĩa một API contract mới.
  • Giao nhận at-least-once cộng với việc consumer khởi động lại nghĩa là cùng một thay đổi có thể bị xử lý nhiều lần.

Quyết định

Chúng tôi tiêu thụ topic Debezium public.Product trong một ApplicationKafkaComponent duy nhất và định tuyến mọi thay đổi tới TaxationWorkerService.handleProductCDC. Hàm này đối soát thay vì áp dụng delta: c/u/r → cấp phát khi taxGroupId có giá trị (ngược lại thì thu hồi), d → thu hồi. Việc cấp phát là idempotent - TaxProvisioningService bỏ qua khi đã tồn tại một TaxSet ACTIVATED với sourceType = TaxGroupsourceId khớp.

Hệ quả

ƯuNhược
Không phụ thuộc đồng bộ vào commerceKhông nạp lại dữ liệu cũ: fallbackMode: latest bỏ qua các thay đổi trước offset
Đối soát tự khôi phục khi bị giao lạiCác TaxSet DEACTIVATED tích lũy dần (không bao giờ bị xoá cứng)
Một topic, một consumer - bề mặt tối thiểuKhông có DLQ; onMessageError chỉ ghi log
Idempotency key (sourceType, sourceId) tránh TaxSet trùngMột Snowflake worker id cố định cứng chặn việc mở rộng theo chiều ngang

Các phương án đã cân nhắc

Phương ánƯuNhượcLý do loại bỏ
Commerce gọi taxation qua REST khi ghi sản phẩmTức thì, không cần KafkaPhụ thuộc đồng bộ; commerce phải biết taxation; logic retry phức tạpRàng buộc vào đường ghi; CDC đã có sẵn
Xử lý theo delta (chỉ áp dụng phần khác biệt)Ít việc hơn mỗi messageDễ vỡ khi bị giao lại hoặc sai thứ tựĐối soát đơn giản hơn và tự khôi phục
fallbackMode: earliest + nạp lại dữ liệu cũBắt được các dòng lịch sửPhát lại toàn bộ lịch sử mỗi lần reset groupNặng về vận hành; các endpoint cấp phát thủ công là đủ

Tham chiếu

  • packages/taxation/src/components/kafka/component.ts
  • packages/taxation/src/services/taxation-worker.service.ts
  • packages/taxation/src/services/tax-provisioning.service.ts:provisionForProduct
  • packages/core/src/common/kafka/topics.ts:CDCKafkaTopics.PRODUCT

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