Контракт, отказ и replay события¶
Ненормативный пример. Иллюстрирует
INT-EVT-001,INT-EVT-002,INT-EVT-003,INT-EVT-004,INT-EVT-005,INT-EVT-009иINT-EVT-013. Запрещено использовать показанный payload как контракт прикладного проекта.
Ограничения применимости: показано синтетическое событие изменения одного агрегата при at-least-once доставке. Пример не определяет broker, topology, retention, транзакционную технологию, формат project schema или процедуру операционного доступа к dead-letter storage. Показанная изоляция является рекомендуемым вариантом, а не обязательным компонентом каждого consumer.
Общий конверт и project payload¶
{
"timestamp": "2026-07-24T12:34:56.123Z",
"event.id": "evt-example-1",
"event.name": "order.approved",
"event.schema_version": 2,
"producer.id": "orders-api",
"trace_id": "0123456789abcdef0123456789abcdef",
"span_id": "0123456789abcdef",
"correlation_id": "corr-example-1",
"aggregate.version": 7,
"payload": {
"order_id": "ord-example",
"approved_at": "2026-07-24T12:34:56.123Z",
"approval_channel": "operator"
}
}
Общая часть проверяется
schemas/event-envelope.schema.json. Project schema версии 2 дополнительно
определяет aggregate.version и payload. Поле approval_channel является
необязательным добавлением относительно версии 1; consumer версии 1 его
игнорирует. Изменение смысла или типа существующего поля потребовало бы новой
несовместимой версии и миграции.
Producer одной локальной транзакцией сохраняет изменение заказа и outbox-запись
с сериализованным событием. Отдельный publisher отмечает запись отправленной
только после положительного durable-подтверждения broker. При timeout или
потере соединения publisher повторяет исходные bytes с тем же event.id,
поэтому consumer ожидает redelivery.
Изоляция после исчерпания повторов¶
{
"original_event_id": "evt-example-1",
"contract_name": "order.approved",
"contract_version": 2,
"attempts": 5,
"reason": "consumer_dependency_unavailable",
"original_bytes_base64": "ZXhhbXBsZQ=="
}
Это запись изолированного хранилища, а не новое бизнес-событие. Значение
original_bytes_base64 синтетическое.
Replay¶
Управляемый replay:
- читает неизменённые исходные bytes;
- повторно проверяет project schema версии 2;
- сохраняет
event.idиaggregate.version; - отправляет событие через обычный consumer path;
- применяет deduplication и сравнение версии атомарно с изменением проекции.
Повторный replay того же события не создаёт второй эффект. Если проекция уже применила версию 8, событие версии 7 не откатывает её состояние.