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

Event Contract: pin.rewards.commission-money-received (CommissionMoneyReceivedKafkaEvent)

Версионируемый контракт интеграционного события «деньги по начислению получены». Consumer-документы ссылаются сюда, не переописывая payload. Дом полей — entity: CommissionAccrualEntity (включая строки распределения CommissionDistributionEntity); источник перехода — entity: PlatformReceiptEntity.

Назначение

Фиксирует прохождение гейта получения денег (ADR-0067): оператор ПИН зарегистрировал акт поступления средств, и начисление комиссии перешло Confirmed → MoneyReceived — деньги от застройщика фактически получены, все денежные следствия разблокированы. Producer — rewards (регистрация акта, platform-receipt.md); событие публичное, потому что wallet кредитует счета получателей по строкам распределения без синхронного запроса в rewards (ADR-0065), а notifications уведомляет агента и агентство о доступности выплаты. Payload несёт полное распределение тремя строками (Platform/Agency/Agent) — единственный контракт, публикующий строки распределения наружу.

Metadata

ПолеЗначение
Event typepin.rewards.commission-money-received
C# typeCommissionMoneyReceivedKafkaEvent
Topicpin.rewards.commission-money-received.v1
Partitions / key3 / key = Id начисления (объём — число завершённых сделок, ADR-0056)
ContractVersion1
Producerrewards: регистрация акта поступления средств (platform-API api/platform/register-platform-receipt.md — по конвенции; атомарный каскад INV-RC-4 platform-receipt.md) — по одному событию на каждое начисление акта
Статусdraft

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

Payload CommissionMoneyReceivedKafkaEvent

Snapshot-поля ссылаются на дом commission-accrual.md — перечисляется только то, что реально в событии. Реквизиты акта (Number, PaymentReference), InvestorUserId, цены объекта недвижимости и снапшоты правил/условий платформы в payload не входят (см. «Безопасность»).

ПолеТипОбязательностьИсточник (поле агрегата)CompatibilityОписание
IdGuidДаCommissionAccrualEntity.IdImmutableКлюч агрегата (= Kafka key); ключ идемпотентности кредитов wallet.
TenantIdGuidДаCommissionAccrualEntity.TenantIdImmutableАгентство-получатель комиссии — держатель счёта AgencyCommission (строка Agency).
DealIdGuidДаCommissionAccrualEntity.DealIdImmutableСделка crm — контекст уведомления и трассировка проводок.
DeveloperCompanyIdGuidДаCommissionAccrualEntity.DeveloperCompanyIdImmutableЗастройщик-плательщик (сторона акта).
PlatformReceiptIdGuidДаCommissionAccrualEntity.PlatformReceiptIdImmutableАкт поступления средств, подтвердивший получение денег (platform-receipt.md).
MoneyReceivedAtDateTimeOffsetДаCommissionAccrualEntity.MoneyReceivedAtImmutableМомент регистрации акта (= RegisteredAt акта).
CommissionAmountMoneyModelДаCommissionAccrualEntity.CommissionAmountAdditive onlyGross-сумма комиссии (после корректировок, если были — INV-11).
DistributionsIReadOnlyList<DistributionModel>Да (ровно 3 элемента)CommissionDistributionEntity начисленияAdditive onlyРаспределение комиссии тремя строками Platform/Agency/Agent (INV-5/9 commission-accrual.md); Σ строк = CommissionAmount. Bounded по построению.
VersionlongДаCommissionAccrualEntity.Version после переходаImmutable semanticsДоменная версия — монотонный guard потребителя.

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

Проекция CommissionDistributionEntity (commission-accrual.md).

ПолеТипОбязательностьОграниченияОписание
RecipientTypestring (enum CommissionRecipientType)ДаPlatform / Agency / Agent; по одной строке каждого типа (INV-9)Тип получателя доли — определяет кредитуемый счёт wallet (ADR-0065).
RecipientUserIdGuid?Да для Agent, null для Platform и AgencyПользователь-получатель доли: агент-исполнитель сделки (= адресат уведомления notifications).
AmountMoneyModelДаValue >= 0Сумма доли.

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

Проекция VO Money (commission-accrual.md, раздел «Value objects»); валюта всех сумм payload едина (INV-6).

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

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

УсловиеПереход состоянияСогласованность
Оператор ПИН зарегистрировал акт поступления средств (api/platform/register-platform-receipt.md — по конвенции): по одному событию на каждое начисление-позицию актаConfirmed → MoneyReceivedАкт Draft → Registered, переходы всех позиций, авто-Approve связанных реферальных начислений и публикация — в одном согласованном изменении (INV-RC-4)

Переход Confirmed → MoneyReceived достижим для начисления ровно один раз (акт Registered неизменяем, начисление — максимум в одном не-отменённом акте, INV-RC-3), поэтому на один Id публикуется ровно одно событие.

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

ПотребительЭффект (событие → действие)ИдемпотентностьЗадержка (SLA)
walletКредит счетов получателей по строкам Distributions (ADR-0065): Agent → счёт AgentCommission пользователя RecipientUserId; Agency → счёт AgencyCommission компании TenantId; Platform → счёт PlatformRevenue платформы. Consumer — ../../wallet/consumers/rewards-commission-money-received.md (по конвенции)MessageId + бизнес-ключ операции (вид операции + Id начисления) — повтор события не удваивает проводки< 5 мин
notificationsУведомления «деньги по комиссии получены, доступна выплата»: агенту (RecipientUserId строки Agent) и руководителю агентства (TenantId, роль с rewards.commission.view-all)MessageId< 5 мин

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

  • Доставка — at-least-once; wallet дедуплицирует по MessageId и бизнес-ключу операции (повторная доставка не создаёт вторую проводку), notifications — по MessageId.
  • Единственность. На одно начисление — ровно одно событие (единственная точка публикации — регистрация акта; повторная регистрация структурно невозможна).
  • Между топиками порядок не гарантирован. В одном коммите с этим событием публикуются commission-accrual-status-changed (→ MoneyReceived) и события авто-апрува реферальных начислений (referral-accrual-status-changed, → Approved) — топики разные, взаимного порядка нет; потребители независимы и идемпотентны. Кредит реферального счёта wallet выполняет по реферальному топику, не по этому.
  • Уведомление о MoneyReceived отправляется только из этого события; в commission-accrual-status-changed переход → MoneyReceived для notifications — no-op (дубль уведомления исключён по построению).
  • Неизвестные поля у потребителя игнорируются (additive-политика ниже).

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

  • Версия — один ContractVersion = 1; consumer при несовпадении версии логирует warning и продолжает (upcasting нет).
  • Additive-only для minor: новые optional-поля с безопасным default — без bump.
  • Breaking (удаление/переименование/смена типа/смысла) — ContractVersion = 2 + новый топик pin.rewards.commission-money-received.v2 + dual-publish на период миграции + deadline миграции consumers + sunset старого топика.
  • Unknown enum RecipientType у потребителя: wallet — строка в DLQ + алерт (кредит неизвестного типа получателя не выполняется, деньги не «теряются» молча); notifications — строка игнорируется с warning.
  • Deprecation — по общему sunset-правилу событийного реестра.

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

ПолеКласс данныхПравило
Id, TenantId, DealId, DeveloperCompanyId, PlatformReceiptId, MoneyReceivedAt, VersionInternalinclude
CommissionAmount, Distributions[].AmountSensitive (суммы комиссий и долей)include (внутренний топик, m2m ACL Kafka — wallet/notifications); в логи потребителей не пишутся; в уведомлении агент видит только факт получения денег, доли — только ролям агентства с rewards.payouts.manage
Distributions[].RecipientType, Distributions[].RecipientUserIdInternalinclude (адресация кредитов и уведомлений)
Реквизиты акта (Number, PaymentReference, Comment)Internalexclude — акт — платформенный документ, агентствам не показывается (platform-receipt.md)
InvestorUserId, цены объекта недвижимости, снапшоты правила и условий платформыSensitive/Internalexclude

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

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

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

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