Events & Data Model

The OutboxEvent record model, the OutboxKafkaEvent Avro schema, and how services publish through the outbox.

OutboxEvent (persisted model)

The abstract OutboxEvent model comes from arya-banking-common and is persisted in a Mongo collection per concrete entity (e.g., user_outbox in user-service):

FieldDescription
idRecord identifier
aggregateIdBusiness aggregate the event belongs to — also the Kafka message key
eventTypeLogical event type (e.g., USER_INSERT)
payloadEvent payload
topicTarget Kafka topic, stored per event on the record
outboxStatusOutboxStatus enum: PENDING, COMPLETED, FAILED, RETRY_PENDING
retryCountNumber of publish attempts so far

OutboxKafkaEvent (Avro schema)

The Avro message published to Kafka, defined in org.arya.banking.common.avro:

FieldType
aggregateIdstring
eventTypestring
payloadstring

Publishing Flow

The outbox record is written inside the same @Transactional method as the business write, so both commit or roll back together:

> Java code-highlight
@Transactional
public void createUser(User user) {
    mongoTemplate.save(user);

    UserOutboxEvent outboxEvent = UserOutboxEvent.builder()
        .aggregateId(user.getId())
        .eventType("USER_INSERT")
        .topic("arya-user-svc-usr-update")
        .payload(serialize(user))
        .outboxStatus(OutboxStatus.PENDING)
        .retryCount(0)
        .build();

    userOutboxRepository.save(outboxEvent);
}

Concrete Repository

Services provide a concrete repository interface that narrows the generic contract to their entity:

> Java code-highlight
public interface UserOutboxRepository extends OutboxEventRepository<UserOutboxEvent> {
}

The topic is stored per-event on the outbox record (event.getTopic()) — it is not a fixed constant. Current usage: user-service publishes eventType USER_INSERT to topic arya-user-svc-usr-update.