Перейти к основному содержимому

Webhook Compatibility Checklist For External Async Notifications — Границы внешних async уведомлений и их совместимости

Версия: 1.0
Дата: 24.04.2026
Статус: Готов к обсуждению

Назначение документа

Этот документ фиксирует первый внешний async boundary checklist для платформы.

Его задача — определить:

  • какие внутренние async-события вообще допустимо проецировать наружу;
  • как webhook-поверхность должна отличаться от внутренних event families;
  • какие compatibility promises допустимы для внешних уведомлений;
  • как выглядят retry, redelivery, degradation и failure semantics для внешнего async уведомления;
  • какие поля и смыслы можно обещать партнёру, а какие должны остаться внутренней реальностью платформы.

Документ не делает webhook-уведомления “главной event model” платформы. Он описывает только внешний projection boundary над уже существующим внутренним async-каркасом.

Опорные документы

Почему Этот Документ Нужен Отдельно

После появления:

  • bounded internal async contracts;
  • payload examples and schema drafts;
  • compatibility и replay policy;

недостаточно просто “решить, что часть событий можно отдать партнёру”.

Нужен отдельный boundary-документ, потому что внешний webhook:

  • не равен raw internal event;
  • не должен утекать наружу вместе с внутренней служебной семантикой;
  • должен быть contract-stable и партнёрно-понятным;
  • должен учитывать безопасность, redelivery и support reality;
  • должен не разрушать tenant, usage и publication discipline.

Без этого внешний async слой начнёт копировать внутреннюю event-модель слишком буквально.

Главный Принцип

External webhook is a bounded projection, not a raw internal event.

Это означает:

  • внутренняя event family может породить webhook, но не обязана экспортироваться напрямую;
  • внешний contract должен быть surface-safe и business-comprehensible;
  • для webhook важна не полнота внутреннего события, а корректность внешнего обещания;
  • внешний consumer не должен зависеть от внутренних governance, replay и recovery деталей;
  • совместимость webhook-контракта должна удерживаться жёстче, чем внутреннего domain event.

Правило Внешней Проекции

Внешнее async уведомление допустимо только если одновременно верно следующее:

  1. у него есть ясный внешний consumer use case;
  2. оно не раскрывает внутреннюю управляющую или операционную кухню;
  3. оно не заставляет партнёра понимать внутренние bounded codes платформы глубже, чем требуется для surface behavior;
  4. его redelivery semantics могут быть объяснены и выдержаны;
  5. его failure semantics не создают ложного ощущения подтверждённой бизнес-истины;
  6. оно укладывается в tenant-aware и usage-aware policy платформы.

Если хотя бы одно из этих условий не выполняется, событие должно оставаться внутренним.

Общий Webhook Compatibility Checklist

Перед выводом async-сигнала на внешний webhook surface нужно подтвердить:

  1. External use case is explicit and justified.
  2. Notification semantics are bounded and partner-comprehensible.
  3. Event is projection-safe and does not leak internal-only operational meaning.
  4. Delivery contract defines idempotent reprocessing expectations.
  5. Retry and redelivery policy are documented for external consumers.
  6. Signature/authentication model is defined.
  7. Versioning and additive evolution rules are documented.
  8. Failure to deliver does not silently change platform truth.
  9. Support and operator teams can diagnose delivery failures.
  10. Tenant, partner and quota policy are reflected in the contract.

Event Families And External Suitability

Quote Notifications

Потенциально допустимы наружу только bounded quote-lifecycle projections, например:

  • quote created for partner-visible workflow;
  • quote invalidated;
  • quote expiry approaching;
  • quote expired.

Ограничения:

  • webhook не должен раскрывать внутренние repricing pipelines целиком;
  • нельзя обещать партнёру, что quote webhook равен booking confirmation;
  • внутренние publication/gating причины должны быть сведены к bounded external semantics;
  • quote webhook должен оставаться производным от contract-safe quote truth.

Booking Notifications

Это наиболее естественный внешний webhook family.

Допустимы наружу:

  • booking accepted/received;
  • booking confirmed;
  • booking pending external confirmation;
  • booking requires action;
  • booking cancelled;
  • booking state uncertain / requires operator attention.

Ограничения:

  • нельзя экспортировать сырые внутренние recovery events;
  • нельзя маскировать unknown.external.state под подтверждённое бронирование;
  • внешняя схема должна быть support-safe и не заставлять партнёра угадывать внутреннее состояние;
  • должен существовать idempotent model для повторной доставки статуса.

Post-Booking Notifications

Допустимы только если у партнёра реально есть post-sale workflow.

Потенциальные семьи:

  • change requested;
  • change accepted/rejected;
  • cancellation accepted/rejected;
  • supplier disruption affecting booking;
  • case requires manual follow-up.

Ограничения:

  • нельзя вытаскивать наружу внутренний service-case lifecycle целиком;
  • support ownership и internal SLA не должны утекать как raw internal fields;
  • внешний webhook должен описывать именно partner-relevant effect.

Usage Governance Notifications

Эти уведомления особенно важны для API-платформы.

Допустимы наружу:

  • usage threshold reached;
  • quota nearing exhaustion;
  • quota exhausted;
  • temporary restriction applied;
  • usage restored after remediation.

Ограничения:

  • contract не должен раскрывать внутреннюю enforcement matrix полностью;
  • governance signal не должен становиться backdoor к внутренним rate-control деталям;
  • bounded reason classes должны быть устойчивы и не слишком granular.

Что Не Должно Экспортироваться Напрямую

Следующие классы событий не должны уходить наружу как прямые webhook contracts:

  • raw canonical entity changes;
  • raw normalization/matching events;
  • internal governance/review task events;
  • internal publication gating internals;
  • operator recovery events;
  • settlement/reconciliation internals “как есть”;
  • internal-only incident or observability signals.

Если внешнему consumer действительно нужен эффект от этих контуров, должен публиковаться отдельный bounded projection contract.

Security Checklist

Для любого внешнего webhook family должно быть определено:

  1. How endpoint ownership is verified.
  2. How webhook signatures are generated and validated.
  3. How replay attack window is bounded.
  4. How secret rotation works.
  5. How delivery attempts are logged and audited.
  6. Which data classes are forbidden in external payloads.

Retry And Redelivery Checklist

Для любого внешнего webhook family должно быть определено:

  1. Retry class and backoff stance.
  2. Maximum retry window.
  3. Redelivery idempotency contract.
  4. Terminal undelivered state handling.
  5. Whether operator escalation is required after exhaustion.
  6. Whether partner-visible reconciliation endpoint exists for missed notifications.

Degradation And Failure Semantics

Внешний webhook всегда должен сопровождаться правилом:

delivery failure is not equal to business rollback.

Это означает:

  • недоставка webhook не отменяет booking truth;
  • недоставка quote invalidation не делает quote снова valid;
  • платформа должна иметь способ повторной синхронизации external state;
  • consumer должен знать, какие состояния можно подтянуть pull-механизмом.

Version Compatibility Checklist

Для любого внешнего webhook family должно быть определено:

  1. What constitutes additive change.
  2. What constitutes breaking change.
  3. How long old versions stay supported.
  4. How partner migration window is communicated.
  5. Whether unknown optional fields are guaranteed safe to ignore.
  6. Whether unknown bounded codes are allowed and how they degrade.

Mapping To Existing Internal Families

Внешний webhook слой должен строиться как projection над уже существующими внутренними families:

  • internal quote-lifecycle may project outward as partner-safe quote-status notifications;
  • internal booking-transitions may project outward as booking-status notifications;
  • internal post-booking-case may project outward as service-impact notifications;
  • internal usage-governance may project outward as quota-and-access notifications.

Проекция не обязана сохранять полную внутреннюю shape fidelity.

Что Должно Появиться Следом

Следующий практический слой после этого документа:

Этот документ замыкает важную границу между внутренней async-архитектурой платформы и её внешним партнёрским async surface.

Уточнение под Фазы 4–6 (28.04.2026)

Webhook compatibility checklist для external async notifications интегрирован с reference/notification-and-communication.md (Фаза 4) — каноничный документ webhook delivery semantics.

Дополнительные требования:

  • HMAC signing (см. security-architecture.md);
  • Tier-зависимые webhook quotas (см. api-as-product.md);
  • Booking state webhook contracts — все 14 каноничных состояний (см. booking-state-machine.md); особое внимание unknown_external_state — partner обязан корректно его обрабатывать;
  • Payment webhook contractspayment.intent.*, payment.refund.*, payment.chargeback.* (см. payment-domain.md);
  • Tour Builder partner-grade webhooks — saga events для partner-initiated tour bookings (см. tour-builder-operational-model.md);
  • Tenant isolation в webhooks — payload каждого webhook scoped to single tenant (см. multi-tenant-isolation-strength.md);
  • GDPR / consent в webhooks — для marketing-channel webhooks обязательная consent verification (см. compliance-and-legal.md).

Каноничные имена webhook events — initial-event-taxonomy.md.

Уточнение выполнено через no-destruction.