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

Event Contract: pin.rewards.referral-accrual-created (ReferralAccrualCreatedKafkaEvent)

Версионируемый контракт интеграционного события «реферальное вознаграждение начислено». Consumer-документы ссылаются сюда, не переописывая payload. Дом полей — entity: ReferralAccrualEntity.

Назначение

Фиксирует создание реферального начисления (referral-accrual.md, [*] → Pending) по завершённой сделке приведённого инвестора: партнёр узнаёт, что вознаграждение начислено и ожидает получения денег от застройщика (гейт ADR-0067). Producer — rewards (реферальная ветка consumer-а завершения сделки); событие публичное, потому что notifications уведомляет партнёра без синхронного запроса в rewards. Переходы статуса — соседним контрактом referral-accrual-status-changed.md того же топика.

Metadata

ПолеЗначение
Event typepin.rewards.referral-accrual-created
C# typeReferralAccrualCreatedKafkaEvent
Topicpin.rewards.referral-accruals.v1 (общий с ReferralAccrualStatusChangedKafkaEvent — общий key = строгий порядок событий per-начисление; прецедент двух контрактов в топике — pin.referral.bonds.v1, ../../referral/events/bond-created.md)
Partitions / key3 / key = Id начисления (объём — доли завершённых сделок, ADR-0056)
ContractVersion1
Producerrewards: реферальная ветка consumer-а crm-deal-completed.md (активная связь + резолвленная ставка, referral-rate-rule.md)
Статусdraft

Метаданные события: идентификатор сообщения (MessageId, ключ дедупликации), время (CreatedAt), Version (= ContractVersion), AggregateId = Id, AggregateType = "ReferralAccrual". Событие публикуется атомарно с созданием начисления.

Payload ReferralAccrualCreatedKafkaEvent

Snapshot-поля ссылаются на дом referral-accrual.md — перечисляется только то, что реально в событии. InvestorUserId, CommissionAccrualId, BaseAmount и AppliedRateSnapshot в payload не входят (см. «Безопасность»).

ПолеТипОбязательностьИсточник (поле агрегата)CompatibilityОписание
IdGuidДаReferralAccrualEntity.IdImmutableКлюч агрегата (= Kafka key).
DealIdGuidДаReferralAccrualEntity.DealIdImmutableСделка crm — основание начисления (одно начисление на сделку, INV-RA-1).
BondIdGuidДаReferralAccrualEntity.BondIdImmutableРеферальная связь — основание начисления (../../referral/domain/referral-bond.md).
PartnerUserIdGuidДаReferralAccrualEntity.PartnerUserIdImmutableПартнёр — получатель вознаграждения; адресат уведомления.
DeveloperCompanyIdGuidДаReferralAccrualEntity.DeveloperCompanyIdImmutableЗастройщик сделки (измерение резолюции ставки).
AmountMoneyModelДаReferralAccrualEntity.AmountAdditive onlyСумма вознаграждения (FinalPrice × Percent / 100, INV-RA-2).
Statusstring (enum ReferralAccrualStatus)ДаReferralAccrualEntity.StatusAdditive only (новые значения)Всегда Pending в v1 (создание — единственная точка публикации); переходы — соседним контрактом referral-accrual-status-changed.md.
DealCompletedAtDateTimeOffsetДаReferralAccrualEntity.DealCompletedAtImmutableМомент завершения сделки (= asOf резолюции ставки).
VersionlongДаReferralAccrualEntity.VersionImmutable semanticsДоменная версия — монотонный guard потребителя (события created и status-changed одного топика упорядочены key-ом).

Вложенная модель MoneyModel

Проекция VO Money (commission-accrual.md, раздел «Value objects»).

ПолеТипОбязательностьОграниченияОписание
ValuedecimalДа> 0, scale 2Сумма.
CurrencyIdshortДассылка на валюту справочника; RUB-only (ADR-0048)Типизированная ссылка на валюту.
CurrencySnapshotCurrencySnapshotДа../../handbook/domain/snapshots.mdDisplay-снапшот валюты на момент публикации.

Когда публикуется

УсловиеПереход состоянияСогласованность
Реферальная ветка consumer-а завершения сделки создала начисление (crm-deal-completed.md): у инвестора активная связь, guard самореферала пройден (INV-RA-4), ставка резолвлена на CompletedAt[*] → Pendingначисление, отметка идемпотентности и событие — в одном согласованном изменении

Skip-ветки consumer-а (нет активной связи, самореферал, ставка не найдена, дубль DealId) события не публикуют.

Потребители (consumers)

ПотребительЭффект (событие → действие)ИдемпотентностьЗадержка (SLA)
notificationsУведомление партнёру (PartnerUserId): «начислено реферальное вознаграждение по сделке приведённого клиента, ожидает поступления денег»MessageId< 5 мин

wallet этот контракт не потребляет: кредит счёта ReferralCommission выполняется только по переходу Approved соседнего контракта (referral-accrual-status-changed.md, ADR-0065) — до прохождения гейта денег начисление балансов не меняет.

Гарантии доставки и порядка

  • Доставка — at-least-once; потребитель дедуплицирует по MessageId.
  • Порядок внутри топика — строгий per-начисление (общий key = Id с referral-accrual-status-changed.md): created приходит строго раньше любых переходов того же начисления; дополнительный monotonic-guard — по Version.
  • Единственность. На один Id — ровно одно created (единственная точка публикации — создание; повтор события-источника упирается в идемпотентность по DealId, INV-RA-1).
  • Неизвестные поля у потребителя игнорируются (additive-политика ниже).

Версионирование и совместимость

  • Версия — один ContractVersion = 1; consumer при несовпадении версии логирует warning и продолжает (upcasting нет).
  • Additive-only для minor: новые optional-поля с безопасным default — без bump.
  • Breaking (удаление/переименование/смена типа/смысла) — ContractVersion = 2 + новый топик pin.rewards.referral-accruals.v2 (мигрируют оба контракта топика) + dual-publish на период миграции + deadline миграции consumers + sunset старого топика.
  • Unknown enum Status у потребителя — fallback: трактовать как Pending + warning.
  • Deprecation — по общему sunset-правилу событийного реестра.

Безопасность

ПолеКласс данныхПравило
Id, DealId, BondId, PartnerUserId, DeveloperCompanyId, Status, DealCompletedAt, VersionInternalinclude
AmountSensitive (суммы вознаграждений)include (внутренний топик, m2m ACL Kafka); в логи потребителей не пишется; в уведомлении сумма видна только партнёру
InvestorUserIdPII (приведённый инвестор, referral-accrual.md)exclude — в payload не входит
BaseAmount (цена сделки), AppliedRateSnapshot, CommissionAccrualIdSensitive/Internalexclude — условия ставок и связка с комиссионным начислением не раскрываются потребителям

Событие НЕ содержит secrets, tokens, PII (ФИО/телефоны), платёжные реквизиты, unbounded-вложения.

Обратные ссылки

Автоссылки: где используется этот документ.

Связанные документы