Create an outbox table with columns: id (UUID PK), aggregatetype, aggregateid, type, payload (JSON), and timestamp; insert rows within the same database transaction as the domain change
Configure the outbox SMT: transforms=outbox,transforms.outbox.type=io.debezium.transforms.outbox.EventRouter
Set transforms.outbox.table.field.event.id=id, transforms.outbox.table.field.event.key=aggregateid, transforms.outbox.table.field.event.payload=payload, transforms.outbox.route.by.field=aggregatetype
Set transforms.outbox.table.expand.json.payload=true to deserialize the payload column as a structured JSON object rather than a raw string in the Kafka record value
Optionally set transforms.outbox.route.topic.replacement to a topic naming template; the aggregatetype value becomes the Kafka topic name by default
Known gotchas
Debezium captures both INSERT and DELETE events on the outbox table; if the outbox table is truncated or rows deleted after processing, DELETE events propagate downstream and must be filtered using the drop tombstones option or a downstream filter
The outbox SMT expects the Debezium envelope format; applying ExtractNewRecordState before EventRouter strips the envelope and causes the SMT to fail
If multiple aggregatetypes route to different topics with different schemas, ensure schema subjects are registered per topic and the Schema Registry subject naming strategy matches the topic routing configuration
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp