Skip to content

ADR-0001. CDC-driven tax provisioning with idempotent reconcile

FieldValue
StatusAccepted
Date2026-04-01
Deciderstaxation-team
Supersedes

Context

  • Commerce owns Product (including its taxGroupId); taxation must not call commerce synchronously on every product write.
  • Tax must stay consistent as products are created, change tax group, lose their tax group, or get deleted.
  • Debezium already streams public.Product changes; reusing that stream avoids a new API contract.
  • At-least-once delivery + consumer restarts mean the same change may be processed more than once.

Decision

We consume the Debezium public.Product topic in a single ApplicationKafkaComponent and route every change to TaxationWorkerService.handleProductCDC, which reconciles rather than applies deltas: c/u/r → provision when taxGroupId is set (else deprovision), d → deprovision. Provisioning is idempotent — TaxProvisioningService skips when an ACTIVATED TaxSet already exists with sourceType = TaxGroup and a matching sourceId.

Consequences

ProsCons
No synchronous coupling to commerceNo backfill: fallbackMode: latest skips pre-offset changes
Reconcile is self-healing on redeliveryDEACTIVATED TaxSets accumulate (never hard-deleted)
Single topic, single consumer — minimal surfaceNo DLQ; onMessageError only logs
Idempotency key (sourceType, sourceId) avoids duplicate TaxSetsSingle hardcoded Snowflake worker id blocks horizontal scale

Alternatives Considered

OptionProsConsWhy rejected
Commerce calls taxation REST on product writeImmediate, no KafkaSync coupling; commerce must know taxation; ret//retry complexityCouples write path; CDC already available
Delta-based handling (apply only the diff)Less work per messageFragile under redelivery / out-of-orderReconcile is simpler and self-healing
fallbackMode: earliest + backfillCatches historical rowsReplays entire history on every group resetOperationally heavy; manual provision endpoints suffice

References

  • 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.