Rewards API — реестр операций и общие контрактные модели
Индекс всех HTTP-операций контекста rewards и единственный дом общих контрактных моделей API
(деньги, условия правил, проекции начислений/поручений, сводки, paging). Файлы операций описывают
только свою дельту и ссылаются сюда. Дом полей сущностей — ../domain/*.md.
| Поле | Значение |
|---|
| Сервис/контекст | rewards (greenfield) |
| Статус | draft |
| Owning team | PIN Platform (backend) |
| Область действия | API areas: developer-admin (правила, подтверждение начислений), agency (политика, поручения, сводки, per-deal корректировки, Excel-выгрузки), agent (мои комиссии + личная user-centric статистика, ADR-0061 п.5), partner (мои реферальные начисления, Excel-выгрузки реферальных вознаграждений — свои/все по permission), platform (условия платформы, реферальные ставки, акты поступления, корректировки, реферальные поручения — Менеджер/оператор ПИН), internal (расчёт комиссии для catalog) |
| Assumptions | Конверт ответа/ошибок — общий для платформы, дом — identity/api/README.md «Общий конверт ответа»; permissions — каталог ../../identity/domain/permission.md |
| Зависимости | ../README.md, ../domain/reward-rule.md, ../domain/commission-accrual.md, ../domain/agency-commission-policy.md, ../domain/payout-order.md, ../domain/platform-commission-terms.md, ../domain/referral-rate-rule.md, ../domain/referral-accrual.md, ../domain/platform-receipt.md |
Реестр операций (64)
Developer-admin — правила вознаграждений (rules)
Developer-admin — начисления (developer-accruals)
Agency — комиссионная политика (agency-policy)
| # | Операция | HTTP | Route | Permission | Документ |
|---|
| 13 | listAgencyPolicies | GET | /api/v1/agency/commission-policies | rewards.commission-policy.view | list-agency-policies.md |
| 14 | createAgencyPolicy | POST | /api/v1/agency/commission-policies | rewards.commission-policy.manage | create-agency-policy.md |
| 15 | updateAgencyPolicy | PUT | /api/v1/agency/commission-policies/{policyId} | rewards.commission-policy.manage | update-agency-policy.md |
| 16 | activateAgencyPolicy | POST | /api/v1/agency/commission-policies/{policyId}/activate | rewards.commission-policy.manage | activate-agency-policy.md |
| 17 | archiveAgencyPolicy | POST | /api/v1/agency/commission-policies/{policyId}/archive | rewards.commission-policy.manage | archive-agency-policy.md |
Agency — boost-кампании агентов (agent-boost)
Agency — начисления и сводки (agency-commission)
Agency — Excel-выгрузки (rewards-exports)
| # | Операция | HTTP | Route | Permission | Документ |
|---|
| 34 | createRewardsExport | POST | /api/v1/agency/rewards-exports | rewards.commission.view-all | create-rewards-export.md |
| 35 | getRewardsExportJob | GET | /api/v1/agency/rewards-exports/{jobId} | rewards.commission.view-all | get-rewards-export-job.md |
Agency — платёжные поручения и история выплат (payouts)
Agent — мои комиссии (my-commission)
Partner — мои реферальные начисления (my-referral)
| # | Операция | HTTP | Route | Permission | Документ |
|---|
| 36 | listMyReferralAccruals | GET | /api/v1/my/referral-accruals | rewards.referral.view-own | list-my-referral-accruals.md |
Partner — реферальные выгрузки (referral-rewards-exports)
Область выборки (own/all) разрешается по permission актора: партнёр (rewards.referral.view-own) —
только свои начисления; Менеджер ПИН (rewards.commission.view-all) — все.
| # | Операция | HTTP | Route | Permission | Документ |
|---|
| 61 | createReferralRewardsExport | POST | /api/v1/referral-rewards-exports | rewards.referral.view-own / rewards.commission.view-all | create-referral-rewards-export.md |
| 62 | getReferralRewardsExportJob | GET | /api/v1/referral-rewards-exports/{jobId} | rewards.referral.view-own / rewards.commission.view-all | get-referral-rewards-export-job.md |
Internal — s2s для catalog (internal-commission)
Общие контрактные модели
| Поле | Тип | Обязательность | Ограничения | Описание |
|---|
Value | decimal | Да | >= 0, scale 2 (numeric(18,2)) | Сумма. |
CurrencyId | short | Да | ссылка на валюту справочника; допустимость валют — RUB-only (ADR-0048) | Типизированная ссылка на валюту. Display-код/знак клиент берёт из справочника (../../handbook/api/public/lookup-references.md); в payload событий деньги идут как Value + CurrencyId + CurrencySnapshot (../../handbook/domain/snapshots.md). |
RewardRuleConditionsModel (проекция RewardRuleConditionsDocument — дом: ../domain/reward-rule.md)
Семантика «null/пусто = любое значение», логическое И между измерениями — как в доме. ContractVersion
jsonb-документа наружу не отдаётся (внутренняя версия хранения).
Ось каталога (специфичность по убыванию): ProjectIds (ЖК, наименее специфично) → LayoutGroupIds
(группа планировок) → LayoutIds (планировка, наиболее специфично). Предикаты PropertyTypes/
RoomsRange/AreaRangeM2 — дополнительные фильтры совпадения (на уровень специфичности не влияют).
| Поле | Тип | Обязательность | Ограничения |
|---|
PropertyTypes | IReadOnlyList<PropertyType> | Нет (пусто = any) | значения Apartment/Parking/Commercial, уникальны, ≤ 3 |
ProjectIds | IReadOnlyList<Guid> | Нет (пусто = any) | уникальны, ≤ 200; ось каталога — ЖК (наименее специфичное измерение) |
LayoutGroupIds | IReadOnlyList<Guid> | Нет (пусто = any) | уникальны, ≤ 200; ось каталога — группа планировок (средняя специфичность) |
LayoutIds | IReadOnlyList<Guid> | Нет (пусто = any) | уникальны, ≤ 500; ось каталога — планировка (наиболее специфичное измерение) |
RoomsRange | NullableRange<int> | Нет | границы Min/Max в 0..20, Min <= Max |
AreaRangeM2 | NullableRange<decimal> | Нет | границы Min/Max в (0; 10000], scale 2, Min <= Max |
RewardRuleModel (полная проекция RewardRuleEntity)
| Поле | Тип | Обязательность | Источник |
|---|
Id | Guid | Да | RewardRuleEntity.Id |
Name | string | Да | Name |
Description | string? | Нет | Description |
Status | string (enum RewardRuleStatus) | Да | Status: Draft/Active/Archived |
CalculationBase | string (enum CommissionCalculationBase) | Да | CalculationBase: BasePrice/FinalPrice |
CommissionPercent | decimal | Да | CommissionPercent (0 < x <= 100, scale 2) |
Priority | int | Да | Priority (0..100000) |
EffectiveFrom | DateTimeOffset? | Нет | EffectiveFrom |
EffectiveTo | DateTimeOffset? | Нет | EffectiveTo |
Conditions | RewardRuleConditionsModel | Да | Conditions (jsonb) |
CreatedAt | DateTimeOffset | Да | CreatedAt |
UpdatedAt | DateTimeOffset | Да | UpdatedAt |
Version | long | Да | Version — используется как ExpectedVersion в мутациях (optimistic concurrency) |
CommissionDistributionModel (проекция CommissionDistributionEntity; отдаётся только agency-area)
| Поле | Тип | Обязательность | Источник |
|---|
Id | Guid | Да | CommissionDistributionEntity.Id |
RecipientType | string (enum CommissionRecipientType) | Да | RecipientType: Platform/Agent/Agency (три строки — INV-9, ADR-0066) |
RecipientUserId | Guid? | Да для Agent, null для Platform/Agency | RecipientUserId |
Amount | MoneyModel | Да | Amount |
AppliedRetentionKind | string? (enum AgencyRetentionKind) | Только у строки Agency | AppliedRetentionKind: Percent/FixedAmount/AgentPercentOfPool/AgentPercentOfPrice (форма применённого правила распределения пула) |
AppliedBoostCampaignId | Guid? | Только у строки Agency, если применён активный boost | AppliedBoostCampaignId (снапшот применённой boost-кампании; null — применялось базовое правило политики) |
PayoutOrderItemId | Guid? | Нет (только строки Agent) | PayoutOrderItemId (null = не включена в поручение) |
PaidAt | DateTimeOffset? | Нет | PaidAt |
CommissionAccrualModel (полная проекция CommissionAccrualEntity; masking по area — см. Masking-правила)
| Поле | Тип | Обязательность | Источник |
|---|
Id | Guid | Да | CommissionAccrualEntity.Id |
DealId | Guid | Да | DealId |
DeveloperCompanyId | Guid | Да | DeveloperCompanyId |
AgencyCompanyId | Guid | Да | TenantId |
AgentUserId | Guid | Да | AgentUserId |
PropertyObjectId | Guid | Да | PropertyObjectId |
DealCompletedAt | DateTimeOffset | Да | DealCompletedAt |
CalculationBase | string (enum CommissionCalculationBase) | Да | CalculationBase |
CommissionPercent | decimal | Да | CommissionPercent |
BasePriceAmount | MoneyModel | Да | BasePriceAmount |
FinalPriceAmount | MoneyModel | Да | FinalPriceAmount |
CommissionAmount | MoneyModel | Да | CommissionAmount (итоговая сумма — после корректировок gross, INV-11) |
OriginalCommissionAmount | MoneyModel? | Нет (null — сумма не корректировалась) | OriginalCommissionAmount |
PlatformRetentionPercentagePoints | decimal | Да | PlatformRetentionPercentagePoints (снапшот условий платформы; 0 — fallback, ADR-0066) |
PlatformFeeAmount | MoneyModel | Да | PlatformFeeAmount (удержание ПИН; пул агентства = CommissionAmount − PlatformFeeAmount) |
AppliedRule | AppliedRuleRefModel | Да | вложенная ref-модель применённого правила (id + имя); дом — ниже |
AppliedPolicyId | Guid? | Нет | AppliedPolicyId |
Status | string (enum CommissionAccrualStatus) | Да | Status: PendingConfirmation/Confirmed/MoneyReceived/Paid/Cancelled |
ConfirmedAt | DateTimeOffset? | Нет | ConfirmedAt |
MoneyReceivedAt | DateTimeOffset? | Нет | MoneyReceivedAt (регистрация акта поступления — гейт ADR-0067) |
PlatformReceiptId | Guid? | Нет | PlatformReceiptId (акт, подтвердивший получение денег; агентству виден эффект гейта — ../domain/platform-receipt.md) |
PaidAt | DateTimeOffset? | Нет | PaidAt |
CancelledAt | DateTimeOffset? | Нет | CancelledAt |
CancelReason | string? (enum CommissionCancelReason) | Нет | CancelReason |
Distributions | IReadOnlyList<CommissionDistributionModel> | Да (пусто до Confirmed; с Confirmed — три строки Platform/Agency/Agent) | child-коллекция; только agency-area |
Adjustments | IReadOnlyList<AdjustmentModel> | Да (может быть пустым) | child-коллекция аудита корректировок; только agency-area |
CreatedAt | DateTimeOffset | Да | CreatedAt |
Version | long | Да | Version |
AppliedRuleRefModel (ref-модель применённого правила; вложена в CommissionAccrualModel)
| Поле | Тип | Обязательность | Источник |
|---|
RuleId | Guid? | Нет (null — ручное начисление) | AppliedRuleId |
RuleName | string | Да | AppliedRuleSnapshot.RuleName ("manual" для ручных) |
PayoutOrderItemModel (проекция PayoutOrderItemEntity)
| Поле | Тип | Обязательность | Источник |
|---|
Id | Guid | Да | PayoutOrderItemEntity.Id |
RecipientUserId | Guid | Да | RecipientUserId — агент (AgencyCommission) / реферальный партнёр (ReferralReward) |
Amount | MoneyModel | Да | Amount |
DistributionsCount | int | Да | DistributionsCount |
PaidAt | DateTimeOffset? | Нет | PaidAt |
PayoutOrderModel (полная проекция PayoutOrderEntity)
| Поле | Тип | Обязательность | Источник |
|---|
Id | Guid | Да | PayoutOrderEntity.Id |
Kind | string (enum PayoutOrderKind) | Да | Kind: AgencyCommission/ReferralReward (../domain/payout-order.md) |
Number | string | Да | Number (PO-{yyyy}-{seq}) |
Title | string? | Нет | Title |
PeriodFrom | DateTimeOffset | Да | PeriodFrom |
PeriodTo | DateTimeOffset | Да | PeriodTo |
Status | string (enum PayoutOrderStatus) | Да | Status: Draft/PendingPayment/Paid/Rejected/Cancelled |
TotalAmount | MoneyModel | Да | TotalAmount |
ItemsCount | int | Да | ItemsCount |
ApprovedAt | DateTimeOffset? | Нет | ApprovedAt |
PaidAt | DateTimeOffset? | Нет | PaidAt |
RejectedAt | DateTimeOffset? | Нет | RejectedAt |
RejectReason | string? | Нет | RejectReason |
CancelledAt | DateTimeOffset? | Нет | CancelledAt |
CreatedAt | DateTimeOffset | Да | CreatedAt |
Version | long | Да | Version |
Items | IReadOnlyList<PayoutOrderItemModel> | Да | child-коллекция (в списках может отдаваться пустой — см. документ операции) |
AdjustmentModel (проекция CommissionAccrualAdjustmentEntity — дом: ../domain/commission-accrual.md)
| Поле | Тип | Обязательность | Источник |
|---|
Id | Guid | Да | CommissionAccrualAdjustmentEntity.Id |
Kind | string (enum CommissionAdjustmentKind) | Да | Kind: GrossAmount/Distribution |
OldAmount | MoneyModel | Да | OldAmount (для GrossAmount — комиссия, для Distribution — доля агента до правки) |
NewAmount | MoneyModel | Да | NewAmount (та же семантика) |
Reason | string | Да | Reason (обязательная причина, INV-11) |
ActorUserId | Guid | Да | ActorUserId |
CreatedAt | DateTimeOffset | Да | CreatedAt |
CommissionAdjustmentRequestModel (проекция CommissionAdjustmentRequestEntity — дом: ../domain/commission-accrual.md)
Заявка агента на корректировку своей доли (схема «агент запрашивает → руководитель одобряет», INV-12).
Отдаётся агенту-заявителю (только свои заявки, record-level RequestedByAgentUserId) и agency-area
(руководителю — все заявки tenant-а).
| Поле | Тип | Обязательность | Источник |
|---|
Id | Guid | Да | CommissionAdjustmentRequestEntity.Id |
AccrualId | Guid | Да | AccrualId |
RequestedByAgentUserId | Guid | Да | RequestedByAgentUserId |
ProposedAgentAmount | MoneyModel | Да | ProposedAgentAmount (предлагаемая доля Agent-строки) |
Reason | string | Да | Reason (обязательное обоснование заявителя) |
Status | string (enum CommissionAdjustmentRequestStatus) | Да | Status: Pending/Approved/Rejected |
ResolvedByUserId | Guid? | Нет (заполняется при разрешении) | ResolvedByUserId (руководитель) |
ResolvedAt | DateTimeOffset? | Нет | ResolvedAt |
ResolutionComment | string? | Нет (обязателен при Rejected) | ResolutionComment |
AppliedAdjustmentId | Guid? | Нет (заполняется при Approved) | AppliedAdjustmentId (id аудит-строки Distribution) |
CreatedAt | DateTimeOffset | Да | CreatedAt |
PlatformTermsModel (полная проекция PlatformCommissionTermsEntity — дом: ../domain/platform-commission-terms.md; только platform-area)
| Поле | Тип | Обязательность | Источник |
|---|
Id | Guid | Да | PlatformCommissionTermsEntity.Id |
AgencyCompanyId | Guid? | Нет (null = глобальный дефолт) | AgencyCompanyId |
RetentionPercentagePoints | decimal | Да | RetentionPercentagePoints (0.25..1.50, scale 2, INV-PT-1) |
Comment | string? | Нет | Comment |
Status | string (enum PlatformCommissionTermsStatus) | Да | Status: Draft/Active/Archived |
ActivatedAt | DateTimeOffset? | Нет | ActivatedAt (начало интервала asOf-резолюции) |
ArchivedAt | DateTimeOffset? | Нет | ArchivedAt (конец интервала, исключительно) |
CreatedAt / UpdatedAt | DateTimeOffset | Да | audit-поля |
Version | long | Да | Version — ExpectedVersion мутаций |
ReferralRateRuleModel (полная проекция ReferralRateRuleEntity — дом: ../domain/referral-rate-rule.md; только platform-area)
| Поле | Тип | Обязательность | Источник |
|---|
Id | Guid | Да | ReferralRateRuleEntity.Id |
PartnerUserId | Guid? | Нет (null = любой партнёр) | PartnerUserId |
DeveloperCompanyId | Guid? | Нет (null = любой застройщик) | DeveloperCompanyId |
Scope | string (enum ReferralRateScope) | Да | computed из заполненности измерений: PartnerDeveloper/Partner/Developer/Global |
Percent | decimal | Да | Percent (0 < x <= 100, scale 2, INV-RR-1) |
EffectiveFrom | DateTimeOffset | Да | EffectiveFrom |
EffectiveTo | DateTimeOffset? | Нет (null = бессрочно) | EffectiveTo |
Comment | string? | Нет | Comment |
Status | string (enum ReferralRateRuleStatus) | Да | Status: Draft/Active/Archived |
CreatedAt / UpdatedAt | DateTimeOffset | Да | audit-поля |
Version | long | Да | Version |
ReferralAccrualModel (проекция ReferralAccrualEntity — дом: ../domain/referral-accrual.md; platform-area и partner-area с masking)
| Поле | Тип | Обязательность | Источник |
|---|
Id | Guid | Да | ReferralAccrualEntity.Id |
DealId | Guid | Да | DealId |
BondId | Guid | Да | BondId (реферальная связь — основание) |
PartnerUserId | Guid | Да | PartnerUserId |
DeveloperCompanyId | Guid | Да | DeveloperCompanyId |
CommissionAccrualId | Guid? | Нет; только platform-area | CommissionAccrualId (родительское начисление — гейт денег) |
AppliedPercent | decimal | Да | AppliedRateSnapshot.Percent |
AppliedRateScope | string (enum ReferralRateScope) | Да | AppliedRateSnapshot.Scope |
BaseAmount | MoneyModel | Да; только platform-area | BaseAmount (конечная цена сделки) |
Amount | MoneyModel | Да | Amount (INV-RA-2; после first-class корректировки — скорректированное значение, INV-RA-6) |
OriginalAmount | MoneyModel? | Нет; только platform-area | OriginalAmount (исходная сумма до корректировок; null — не корректировалась, INV-RA-6) |
Status | string (enum ReferralAccrualStatus) | Да | Status: Pending/Approved/Paid/Cancelled |
DealCompletedAt | DateTimeOffset | Да | DealCompletedAt |
ApprovedAt / PaidAt / CancelledAt | DateTimeOffset? | Нет | статусные даты |
CancelReason | string? (enum ReferralCancelReason) | Нет | CancelReason |
PayoutOrderItemId | Guid? | Нет; только platform-area | PayoutOrderItemId |
CreatedAt | DateTimeOffset | Да | CreatedAt |
Version | long | Да | Version |
InvestorUserId в модель не проецируется ни в одной area (PII приведённого инвестора — дом
../domain/referral-accrual.md).
PlatformReceiptModel (полная проекция PlatformReceiptEntity — дом: ../domain/platform-receipt.md; только platform-area)
| Поле | Тип | Обязательность | Источник |
|---|
Id | Guid | Да | PlatformReceiptEntity.Id |
Number | string | Да | Number (RC-{yyyy}-{seq}) |
DeveloperCompanyId | Guid | Да | DeveloperCompanyId |
Amount | MoneyModel | Да | Amount (сумма фактического поступления) |
ItemsCount | int | Да | ItemsCount |
PaymentReference | string? | Нет | PaymentReference |
Comment | string? | Нет | Comment |
Status | string (enum PlatformReceiptStatus) | Да | Status: Draft/Registered/Cancelled |
RegisteredAt / CancelledAt | DateTimeOffset? | Нет | статусные даты |
CreatedAt | DateTimeOffset | Да | CreatedAt |
Version | long | Да | Version |
Items | IReadOnlyList<PlatformReceiptItemModel> | Да | child-коллекция позиций |
| Поле | Тип | Обязательность | Источник |
|---|
Id | Guid | Да | PlatformReceiptItemEntity.Id |
CommissionAccrualId | Guid | Да | CommissionAccrualId |
AgencyCompanyId | Guid | Да | AgencyCompanyId |
Amount | MoneyModel | Да | Amount (= CommissionAmount начисления на момент включения) |
CreatedAt | DateTimeOffset | Да | CreatedAt |
| Поле | Тип | Обязательность | Источник |
|---|
Id | Guid | Да | id задачи выгрузки (jobId маршрутов) |
ReportType | string (enum RewardsReportType) | Да | ByEmployeePerDeal/PeriodSummary |
Status | string (enum RewardsExportJobStatus) | Да | Queued/Running/Completed/Failed/Expired |
PeriodFrom / PeriodTo | DateTimeOffset | Да | снапшот фильтров задачи |
AgentUserId | Guid? | Нет | снапшот фильтров |
StatusFilter | string? (enum CommissionAccrualStatus) | Нет | снапшот фильтров |
RowsCount | int? | Нет (заполняется при Completed) | число строк файла |
FailureCode | string? | Только при Failed | причина (REWARDS_EXPORT_ROW_LIMIT_EXCEEDED и др.) |
DownloadUrl | string? | Только при Completed и живом файле | короткоживущая подписанная ссылка (TTL 1 час) |
DownloadUrlExpiresAt | DateTimeOffset? | Вместе с DownloadUrl | момент истечения ссылки |
CreatedAt | DateTimeOffset | Да | постановка задачи |
CompletedAt | DateTimeOffset? | Нет | завершение генерации |
ReferralRewardsExportJobModel (задача Excel-выгрузки реферальных вознаграждений — partner/create-referral-rewards-export.md, ADR-0041)
| Поле | Тип | Обязательность | Источник |
|---|
Id | Guid | Да | id задачи выгрузки (jobId маршрутов) |
ReportType | string (enum ReferralRewardsReportType) | Да | ByPartner/PeriodSummary |
Scope | string (own/all) | Да | область выборки, разрешённая по permission (own — свои начисления; all — все партнёры) |
Status | string (enum RewardsExportJobStatus) | Да | Queued/Running/Completed/Failed/Expired |
PeriodFrom / PeriodTo | DateTimeOffset | Да | снапшот фильтров задачи |
PartnerUserId | Guid? | Нет | снапшот фильтров (при Scope = own = актор; при Scope = all — опциональный фильтр) |
StatusFilter | string? (enum ReferralAccrualStatus) | Нет | снапшот фильтров |
RowsCount | int? | Нет (заполняется при Completed) | число строк файла |
FailureCode | string? | Только при Failed | причина (REWARDS_EXPORT_ROW_LIMIT_EXCEEDED и др.) |
DownloadUrl | string? | Только при Completed и живом файле | короткоживущая подписанная ссылка (TTL 1 час) |
DownloadUrlExpiresAt | DateTimeOffset? | Вместе с DownloadUrl | момент истечения ссылки |
CreatedAt | DateTimeOffset | Да | постановка задачи |
CompletedAt | DateTimeOffset? | Нет | завершение генерации |
CommissionSummaryModel (сводка ЛК: «получим/получили × подтверждено/ожидает»)
Каждая метрика — пара сумма+количество; вычисляется SQL-агрегацией (SUM, COUNT) по
rewards.commission_accruals / rewards.commission_distributions (ADR-0056, без ClickHouse).
| Поле | Тип | Обязательность | Формула (источник) |
|---|
PendingConfirmationTotal | MoneyModel | Да | Σ по строкам области видимости со Status = PendingConfirmation («получим, ожидает подтверждения») |
PendingConfirmationCount | int | Да | count тех же строк |
ConfirmedTotal | MoneyModel | Да | Σ со Status = Confirmed («получим, подтверждено; деньги от застройщика ещё не получены») |
ConfirmedCount | int | Да | count тех же строк |
MoneyReceivedTotal | MoneyModel | Да | Σ со Status = MoneyReceived («деньги получены, готово к выплате» — гейт ADR-0067 пройден) |
MoneyReceivedCount | int | Да | count тех же строк |
PaidTotal | MoneyModel | Да | Σ со Status = Paid («получили») |
PaidCount | int | Да | count тех же строк |
CancelledTotal | MoneyModel | Да | Σ со Status = Cancelled (справочно) |
CancelledCount | int | Да | count тех же строк |
База суммирования зависит от области: агентство — CommissionAmount (gross) + отдельно
AgencyRetainedTotal/AgentsShareTotal (дельта в get-agency-commission-summary.md);
агент — Amount его Agent-строки распределения, для PendingConfirmation (строк ещё нет) — прогноз
по активной политике (дельта в get-my-commission-summary.md).
Paging (все list-операции)
| Поле | Источник | Тип | Ограничения |
|---|
Page | query | int | >= 1, default 1 |
PageSize | query | int | 1..100, default 20 |
Ответ — страница: Items : IReadOnlyList<TItem>, Page : int, PageSize : int, TotalCount : long.
Masking-правила (все операции)
| Правило | Значение |
|---|
InvestorUserId | Никогда не отдаётся в API rewards (ни агентству, ни агенту, ни застройщику, ни партнёру) — трассировка только через DealId в crm |
Distributions | Отдаются только agency-area (rewards.commission.view-all); агенту — только собственная Agent-строка (проекция MyAccrualModel); застройщику — не отдаются (внутреннее дело агентства и платформы) |
| Условия платформы и ставки | PlatformTermsModel/ReferralRateRuleModel — только platform-area; агентству/партнёру видны лишь применённые значения в снапшотах начислений (PlatformRetentionPercentagePoints/PlatformFeeAmount, AppliedPercent) |
| Акты поступления средств | PlatformReceiptModel — только platform-area (rewards.receipts.manage); агентству виден эффект: Status = MoneyReceived, MoneyReceivedAt, PlatformReceiptId начисления |
| Реферальные начисления | Партнёру — только свои (record-level PartnerUserId, rewards.referral.view-own); BaseAmount, CommissionAccrualId, PayoutOrderItemId — только platform-area |
| Суммы | Sensitive: не логируются (в logs — только Id/Status/counts), доступ строго по permissions; выгрузки — audit ExportSensitive (ADR-0041) |
| Полный документ политики | Агенту не отдаётся; агент видит только применённое к нему удержание в своих проекциях |
Общие ошибки (все операции; коды не дублируются в файлах операций)
| Код | HTTP status | Условие |
|---|
ValidationError | 400 | Валидатор отклонил вход (формат/диапазоны/enum) |
FORBIDDEN | 403 | Нет permission / чужой tenant / record-level нарушение |
UNAUTHORIZED | 401 | Нет/просрочен JWT (m2m — неверный audience) |
REWARDS_CONCURRENCY_CONFLICT | 409 | ExpectedVersion не совпал с Version агрегата |
Согласованность и порядок событий (общее для area)
Единые гарантии для всех операций контекста — файлы операций на них ссылаются, не повторяя:
- Атомарность. Изменение агрегата и публикация его интеграционных событий происходят в одном
согласованном изменении (транзакционный outbox): наблюдатель никогда не видит изменённое состояние без
соответствующего события и наоборот.
- Ключ партиционирования и порядок. Ключ каждого события — идентификатор его агрегата (
RuleId для
правил, AccrualId для начислений — в т.ч. commission-money-received при регистрации акта,
PayoutOrderId для поручений, id реферального начисления для топика pin.rewards.referral-accruals.v1).
Порядок событий в пределах одного агрегата сохраняется; межагрегатного глобального порядка нет.
- Доставка и идемпотентность. Доставка — at-least-once; потребители обязаны быть идемпотентными
(дедуп по идентификатору агрегата +
Version/переходу либо по натуральному ключу вроде DealId).
Повторная доставка одного события не должна давать двойного эффекта.
- Синхронный ответ vs витрины. HTTP-ответ операции всегда отражает уже зафиксированное состояние
сразу. Производные представления в других сервисах (комиссия в витрине
catalog, self-проекция
AgentPerformance, ленты уведомлений) обновляются асинхронно — окно eventual-consistency измеряется
секундами; в этом окне пользователь может видеть прежнее значение в производном представлении при уже
применённом изменении в источнике (rewards). Конкретные окна — в разделе «Побочные эффекты»
соответствующей операции.
- Конкурентность мутаций. Мутации агрегатов используют optimistic concurrency по
ExpectedVersion;
проигравший параллельную гонку получает REWARDS_CONCURRENCY_CONFLICT (409), перечитывает актуальное
состояние и повторяет. Единственность (приоритет активного правила, одно начисление на сделку) страхуется
уникальными индексами — гонка двух создающих запросов даёт доменный конфликт-код операции.
Связанные документы