API Events
The only async surface is one CDC consumer. There are no Kafka producers, BullMQ queues, or WebSocket emissions.
1. Inbound — Kafka
| Topic | Producer | Handler | Idempotency Key | Failure Mode |
|---|---|---|---|---|
public.Product (CDCKafkaTopics.PRODUCT) | Debezium (commerce) | TaxationWorkerService.handleProductCDC | (productId, taxGroupId, op) — provision is idempotent | log + skip (autocommit; no DLQ) |
Consumer config (ApplicationKafkaComponent):
| Setting | Value |
|---|---|
| Client ID | APP_ENV_KAFKA_CLIENT_ID (default SVC-00130-TAXATION_CONSUMER) |
| Group ID | APP_ENV_KAFKA_GROUP_ID (default SVC-00130-TAXATION_CONSUMER_GROUP) |
| Key deserializer | stringDeserializer |
| Value deserializer | jsonDeserializer |
fallbackMode | latest (no historical backfill) |
autocommit | true |
requestTimeout / connectTimeout / maxWaitTime | 60000 / 30000 / 5000 ms |
Op routing:
Debezium op | Action |
|---|---|
c, u, r | _reconcileTaxProvisions(after) |
d | deprovisionForProduct(before.id ?? after.id) |
| other | ignored |
Reconcile branch (c/u/r):
| Product state | Action |
|---|---|
deletedAt set | deprovision |
no taxGroupId | deprovision |
taxGroupId present | provision (idempotent) |
2. Outbound — Kafka
None. Taxation does not produce events. Provisioned
TaxSet/Taxrows are read by pricing directly from the shared DB.
3. Inbound — BullMQ
None.
4. Outbound — BullMQ
None.
5. WebSocket Emissions
None.
6. Payload Schemas
Inbound payload is a Debezium envelope around a
Productrow. Types are from@nx/core(TDebeziumMessage,TDebeziumPayload,TProductPgRow). Snake_case row keys are converted viatoCamelCaseKeysbefore use.
ts
// CDCKafkaTopics.PRODUCT — message.value
interface TDebeziumMessage<TProductPgRow> {
payload: TDebeziumPayload<TProductPgRow>;
}
interface TDebeziumPayload<T> {
op: 'c' | 'u' | 'r' | 'd';
before: T | null; // snake_case
after: T | null; // snake_case
}
// Fields read by the worker (post toCamelCaseKeys):
// id: string
// taxGroupId: string | null
// deletedAt: string | null7. Idempotency & Ordering
| Topic | Delivery | Ordering | Recovery |
|---|---|---|---|
public.Product | at-least-once (autocommit) | per-partition (per product key) | re-deliver replays reconcile; provision skips when already provisioned with the same TaxGroup |
No DLQ:
onMessageErrorlogs only.fallbackMode: latestmeans rows changed while the consumer was down before the offset window are not reprocessed — there is no backfill job (ADR-0001).