# DOMAIN.md

## DOMAIN.md — доменная модель CardApp / МояКарта

Документ описывает доменную модель CardApp в стиле DDD и Event Sourcing. Его задача — общий язык между бизнесом и разработкой: что есть, как устроено, какими правилами живёт.

Документ опирается на:

* `GLOSSARY.md` — canonical-термины и запрещённые синонимы;
* `EVENT_STORMING.md` — карта контекстов, акторов, событий и команд;
* `SERVICE_POLICIES.md` — поименованные правила сервиса.

Если термин в этом документе расходится с `GLOSSARY.md`, приоритет у глоссария. Если правило расходится с `SERVICE_POLICIES.md`, приоритет у политик. События и команды называются так, как в `EVENT_STORMING.md`.

***

### 1. Принципы домена

1. Деньги — append-only. Балансы не меняются прямой записью. Любое изменение — это `LedgerTransaction` из набора `LedgerEntry` (см. `OMNIBUS_FUNDS_LEDGER_ATTRIBUTION`, `MANUAL_ADJUSTMENT_THROUGH_LEDGER_WITH_APPROVAL`).
2. Балансы — это projection. UI/админка показывают `BalanceProjection`, рассчитанный из ledger entries; источник истины — ledger.
3. KYC — risk-based. Не обязательный шаг для всех, а триггерный (см. `RISK_BASED_KYC`).
4. PAN не хранится. Сервис работает с `CardLast4` и `CardTokenId`, полный PAN — только у card issuing/CaaS provider.
5. Поддержка не делает деньги. Support общается, собирает данные, эскалирует. Финансовые действия и снятие ограничений — Admin (плюс `FourEyesApproval` для критичных).
6. AI — не финал. AI-ассистент собирает данные и предварительную оценку, не принимает решения по спорам, KYC, refund, restriction.
7. Каждое событие — факт прошлого. Имя в формате `Context.Aggregate.EventName`, прошедшее время. Команда — намерение, событие — факт.
8. Идемпотентность по умолчанию. Повторный webhook, повторная команда, повторный postback не должны создавать дубль бизнес-эффекта.
9. Внешние интеграции — за `AntiCorruptionLayer`. Терминология провайдеров не протекает в домен.
10. Audit — отдельный поток. Действия операторов, доступ к PII, системные действия пишутся в `AuditLog` (append-only).

***

### 2. Bounded Contexts

Контексты совпадают с `EVENT_STORMING.md`. Классификация по DDD:

| #  | Контекст                    | Canonical name        | Тип        |
| -- | --------------------------- | --------------------- | ---------- |
| 1  | Источники входа и атрибуция | EntrySources          | Supporting |
| 2  | Идентификация и доступ      | IdentityAndAccess     | Supporting |
| 3  | KYC и compliance            | KycAndCompliance      | Supporting |
| 4  | Тарифы и открытие карты     | TariffsAndCardOpening | Core       |
| 5  | Карты                       | Cards                 | Core       |
| 6  | СБП-депозиты                | SbpDeposits           | Core       |
| 7  | Crypto-депозиты             | CryptoDeposits        | Core       |
| 8  | Платежи и 3DS               | PaymentsAnd3DS        | Core       |
| 9  | Ledger и финансы            | LedgerAndFinance      | Core       |
| 10 | Казначейство                | Treasury              | Core       |
| 11 | Risk                        | Risk                  | Core       |
| 12 | Поддержка и споры           | SupportAndDisputes    | Supporting |
| 13 | Реферальная программа       | Referral              | Supporting |
| 14 | Партнёрская программа       | Affiliate             | Supporting |
| 15 | Уведомления                 | Notifications         | Supporting |
| 16 | Админка                     | AdminPanel            | Supporting |
| 17 | Legal и контент             | LegalAndContent       | Supporting |
| 18 | Privacy                     | Privacy               | Supporting |
| 19 | Сверка                      | Reconciliation        | Supporting |

Core — то, где сервис создаёт ценность и где нельзя ошибиться (деньги, карты, риск). Supporting — необходимые контексты вокруг ядра.

#### 2.1. Карта контекстов

```
              ┌──────────────────┐
              │   EntrySources   │
              │   attribution    │
              └────────┬─────────┘
                       │ first-touch
                       ▼
        ┌──────────────────────────┐
        │    IdentityAndAccess     │  ← OTP, 2FA, sessions, devices
        └────────┬─────────────────┘
                 │ user_id
                 ▼
   ┌──────────────────────────────────────────────────────────────┐
   │        KycAndCompliance       (триггеры от Risk и Sbp)       │
   └─────────────────────────────────────────────────────────────-┘
                 │ verified / restricted
                 ▼
   ┌─────────────────────────┐     ┌────────────────────────────┐
   │  TariffsAndCardOpening  │────►│           Cards            │
   │  тариф, quote, оплата   │     │  lifecycle, доставка,      │
   └────────┬────────────────┘     │  freeze/block/close        │
            │                      └─────────┬──────────────────┘
            │                                │
            ▼                                ▼
   ┌──────────────────┐            ┌──────────────────┐
   │   SbpDeposits    │            │ PaymentsAnd3DS   │
   │   payer, KYC     │            │ auth/3DS/clearing│
   │   thresholds     │            └────────┬─────────┘
   └────────┬─────────┘                     │
            │                               │
            ▼                               ▼
   ┌──────────────────┐            ┌──────────────────────────┐
   │  CryptoDeposits  │───────────►│   LedgerAndFinance       │
   │  late/unmatched  │            │  master accounts,        │
   └────────┬─────────┘            │  attribution, projections│
            │                      └────────┬─────────────────┘
            └─────────────────────────────-►│
                                            ▼
                                  ┌──────────────────┐
                                  │     Treasury     │
                                  │  provider funding│
                                  └──────────────────┘

   ┌──────────────┐    ┌────────────────────┐    ┌──────────────┐
   │     Risk     │◄──►│ SupportAndDisputes │    │ Notifications│
   └──────┬───────┘    └─────────┬──────────┘    └──────▲───────┘
          │                      │                      │
          ▼                      ▼                      │
   ┌─────────────────────────────────────────-┐         │
   │         AdminPanel (RBAC, approvals)     │         │
   └────────────────┬───────────────────────-─┘         │
                    │                                   │
                    ▼                                   │
   ┌──────────────────────────────────────────┐         │
   │              AuditLog (append-only)      │         │
   └──────────────────────────────────────────┘         │
                                                        │
   ┌──────────────┐   ┌──────────────┐    ┌─────────────┴──┐
   │   Referral   │   │   Affiliate  │    │ LegalAndContent│
   └──────────────┘   └──────────────┘    └────────────────┘

           ┌──────────────────────┐    ┌──────────────────┐
           │     Privacy          │    │ Reconciliation   │
           └──────────────────────┘    └──────────────────┘
```

#### 2.2. Связи между контекстами

| Связь                                                   | Тип           | Что течёт                                  |
| ------------------------------------------------------- | ------------- | ------------------------------------------ |
| EntrySources → IdentityAndAccess                        | publish       | первый источник пользователя, attribution  |
| IdentityAndAccess → все                                 | shared kernel | `UserId`                                   |
| Sbp/Crypto/Payments → Risk                              | request/reply | запрос риск-оценки                         |
| Risk → Sbp/Cards/Payments                               | publish       | restriction/warning                        |
| Cards/Sbp/Crypto/Payments → LedgerAndFinance            | command       | `PostLedgerEntries`                        |
| Cards → ProviderAdapter                                 | ACL           | команды на provider, нормализация webhooks |
| LedgerAndFinance → Treasury                             | publish       | сигналы о расходовании provider funding    |
| SupportAndDisputes → AdminPanel                         | publish       | эскалации, запросы admin actions           |
| Все → Notifications                                     | publish       | категория + получатель + payload           |
| Все → AuditLog                                          | publish       | системные/admin действия, доступ к PII     |
| Reconciliation → LedgerAndFinance, Treasury, Cards, Sbp | read          | сравнение источников                       |

***

### 3. Тактический дизайн

Для каждого контекста описаны: назначение, основные агрегаты, ключевые инварианты со ссылкой на политики, основные события и команды (полный список — в `EVENT_STORMING.md`).

***

#### 3.1. EntrySources (источники входа и атрибуция)

Назначение: фиксирует первое касание пользователя с сервисом и хранит атрибуцию навсегда.

Агрегаты:

* `Attribution` — первый источник пользователя (referral / partner / marketing). Бессрочная и не перезаписывается (`LIFETIME_FIRST_TOUCH_ATTRIBUTION`).
* `FunnelEntry` — факт попадания в воронку с целевой платформы (`landing | telegram_mini_app | app_store | google_play`).
* `NurtureSequence` — серия дожимных сообщений по незавершённому milestone (расписание `15м / 24ч / 72ч / 7д`, `FUNNEL_NURTURE_SCHEDULE_V1`).
* `ReactivationSequence` — кампания после 10 дней неактивности (`REACTIVATION_AFTER_10_DAYS_INACTIVITY`), уважает marketing preferences (`REACTIVATION_RESPECTS_MARKETING_PREFERENCES`).

Ключевые события: `Acquisition.LinkOpened`, `Acquisition.AttributionCaptured`, `Acquisition.AttributionConflictRejected`, `Acquisition.FunnelEntered`, `Funnel.RegistrationCompleted`, `Funnel.FirstCardOpened`, `Funnel.FirstDepositCompleted`, `Nurture.*`, `Reactivation.*`.

Связи: публикует attribution в `IdentityAndAccess` при регистрации; передаёт реферальные/партнёрские атрибуции в `Referral` / `Affiliate`.

***

#### 3.2. IdentityAndAccess

Назначение: регистрация, OTP, 2FA, кросс-платформенная identity (Telegram / Web / future mobile), сессии и устройства.

Агрегаты:

* `User` — основной аккаунт. Уникальные `Email` и `Phone` (`UNIQUE_EMAIL_PHONE_ACCOUNT`). Регистрация завершена только после ввода ФИО, телефона, email и подтверждения телефона и email (`REGISTRATION_REQUIRES_PHONE_AND_EMAIL_CONFIRMATION`).
* `PlatformIdentity` — привязка к Telegram (а в будущем — к MAKS / mobile). Telegram identity автоматически линкуется при регистрации через Telegram Mini App (`TELEGRAM_IDENTITY_LINKED_ON_REGISTRATION`).
* `Otp` — одноразовый код. TTL 2 минуты, максимум 5 попыток (`OTP_CONFIRMATION_LIMITS`).
* `TwoFactor` — методы пользователя: `email_otp`, `sms_otp`, `telegram_bot_code`, `app_push` (`TWO_FACTOR_METHODS_V1`). Должен быть основной и запасной метод (`TWO_FACTOR_PRIMARY_AND_BACKUP_METHOD`). Смена метода требует текущий 2FA (`TWO_FACTOR_METHOD_CHANGE_REQUIRES_CURRENT_2FA`). Потеря всех методов восстанавливается через Support + KYC (`LOST_2FA_RECOVERY_SUPPORT_AND_KYC`).
* `Session` — авторизованное состояние. С нового устройства открывается только после OTP/2FA (`NEW_DEVICE_REQUIRES_2FA`, `SESSION_REJECTED_IF_NEW_DEVICE_2FA_FAILED`). Отзыв текущего устройства завершает сессию (`REVOKING_CURRENT_DEVICE_LOGS_OUT_USER`).
* `Device` — клиент пользователя. `TrustedDevice` после успешного 2FA. Пользователь видит и может отзывать (`USER_CAN_MANAGE_TRUSTED_DEVICES`).

Ключевые события: `User.Registered`, `User.PhoneConfirmed`, `User.EmailConfirmed`, `Otp.Verified`, `Otp.AttemptsExceeded`, `TwoFactor.Verified`, `Device.Confirmed`, `Device.Revoked`, `Session.Opened`, `Session.Revoked`, `Telegram.IdentityReceived`, `User.TelegramIdentityLinked`.

***

#### 3.3. KycAndCompliance

Назначение: внешняя KYC-проверка, sanctions/PEP/watchlist, депозитные ограничения по compliance-сигналам.

Агрегаты:

* `KycApplication` — заявка к внешнему `KycProvider`. CardApp не хранит документы (`KYC_EXTERNAL_PROVIDER_NO_DOCUMENT_STORAGE`). Принимаются: паспорт, загранпаспорт, водительское, ВНЖ с фото; лицевая проверка обязательна (`KYC_DOCUMENTS_AND_FACE_CHECK`).
* `KycRetry` — счётчик попыток: до 5 за 24 часа, далее окно 24 часа (`KYC_RETRY_LIMIT`, `KYC_RETRY_AFTER_24H`).
* `ComplianceCase` — sanctions/PEP/watchlist hit. Не блокирует аккаунт целиком: ограничивает только депозиты (`SANCTIONS_HIT_DEPOSIT_RESTRICTION_ONLY`). Финальный результат от провайдера снимает ограничение (`SANCTIONS_REVIEW_BY_KYC_PROVIDER`).
* `DepositRestriction` — ограничение на пополнения с типом причины (например `sbp_only_kyc_payer_allowed`). Снимает только compliance/admin (`DEPOSIT_RESTRICTION_RBAC`).

Ключевые события: `KYC.Application.Required`, `KYC.Application.Started`, `KYC.Document.Submitted`, `KYC.FaceCheckPassed/Failed`, `KYC.Application.Approved/Rejected/Expired`, `KYC.RetryLimitExceeded`, `Compliance.SanctionsHitRecorded`, `User.DepositRestrictionApplied/Lifted`.

KYC не является обязательным milestone воронки. Триггерится из `SbpDeposits` (порог `N`, mismatch payer) и из `Risk`.

***

#### 3.4. TariffsAndCardOpening

Назначение: тарифы, цены выпуска, FX markup, расчёт quote и оплата открытия карты.

Тарифы v1 (см. `EVENT_STORMING.md`):

| Тариф                  | Тип      | Стоимость | FX markup |
| ---------------------- | -------- | --------: | --------: |
| Для подписок           | virtual  |  1990 RUB |      +25% |
| Для путешественников   | virtual  |  2990 RUB |      +12% |
| Премиальная            | virtual  | 14999 RUB |       +7% |
| Премиальная-физическая | physical | 19999 RUB |       +5% |

Агрегаты:

* `Tariff` — тариф с конфигурируемой ценой и FX markup. Изменения через approval (`TARIFFS_ARE_CONFIGURABLE`). Изменение цены применяется только к новым картам (`CARD_ISSUANCE_PRICE_APPLIES_TO_NEW_CARDS_ONLY`); FX — ко всем картам тарифа (`FX_RATE_APPLIES_TO_ALL_CARDS`). Лимиты по тарифу — конфигурируемые позже (`TARIFF_LIMITS_CONFIGURABLE_LATER`).
* `PaymentQuote` — фиксированный расчёт оплаты. TTL 2 часа (`PAYMENT_QUOTE_TTL_2H_ALL_METHODS`). Резервирует депозитный лимит карты на это окно (`DEPOSIT_LIMIT_RESERVATION`).
* `CardOpening` — процесс открытия: выбор тарифа, выбор типа, quote, оплата, выпуск. Минимальная сумма при открытии = стоимость карты + первый депозит $10 (`CARD_OPENING_MIN_PAYMENT`). Карта считается открытой только после оплаты, подтверждённого выпуска и выдачи реквизитов (`CARD_OPENED_AFTER_PAYMENT_AND_CREDENTIALS`).

RUB-курс платформы: курс Rapira + наценка администратора (`RUB_PLATFORM_RATE_FROM_RAPIRA_PLUS_MARKUP`). Markup задаётся отдельно по тарифу и типу (`FX_MARKUP_BY_TARIFF_AND_CARD_TYPE`).

Ключевые события: `Tariff.Created/Updated/Published/Archived`, `Tariff.IssuancePriceUpdated`, `Fx.MarkupUpdatedByAdmin`, `Card.TariffSelected`, `Card.TypeSelected`, `Payment.QuoteCreated/Accepted/Expired`, `Card.OpeningPaymentInitiated`, `Card.IssuanceFeeReserved`, `Card.InitialDepositReserved`.

***

#### 3.5. Cards

Назначение: жизненный цикл карты от выпуска до закрытия, реквизиты, заморозка/блокировка, физическая доставка, реакция на provider incident.

Статусы (`GLOSSARY → Статусы карты`):

```
pending_issuance → active → frozen → active
                       ↘
                        blocked → (через Support/Admin) → active | closed
                       ↘
                        closing_pending → closed
                       ↘
                        expired
```

Агрегаты:

* `Card` — карта и её состояние. PAN не хранится; есть `CardLast4` и `CardTokenId`. `CardCredentials` — то, что показываем пользователю; каждый показ чувствительных реквизитов фиксируется в audit (`CARD_CREDENTIALS_AVAILABLE_AFTER_ISSUANCE`).
* `CardIssuance` — попытка выпуска. Каскад провайдеров скрыт от пользователя (`CARD_ISSUANCE_PROVIDER_CASCADE`). SLA: уведомление пользователя через 24 часа задержки (`CARD_ISSUANCE_DELAY_NOTIFICATION_V1`); через 48 часов — открытие support case с выбором «ждать или возврат» (`CARD_ISSUANCE_48H_SUPPORT_CHOICE`). Пользовательский статус ожидания: «Ещё чуть-чуть и ваша карта будет готова» (`CARD_ISSUANCE_PENDING_MESSAGE`).
* `PhysicalDelivery` — производство и доставка. При неудаче — обязательное уведомление и автоматический support ticket (`PHYSICAL_CARD_DELIVERY_FAILURE_SUPPORT_FLOW`). Момент выдачи реквизитов зависит от провайдера (`PHYSICAL_CARD_CREDENTIALS_BY_PROVIDER_MODE`).

Инварианты:

* `Frozen` ставит пользователь без 2FA, размораживает с 2FA (`CARD_FREEZE_SAFE_UNFREEZE_REQUIRES_2FA`).
* `Blocked` — только система/admin/provider; пользователь сам не разблокирует (`BLOCKED_CARD_UNBLOCK_VIA_SUPPORT_ADMIN`).
* Закрытие — только через Support (`CARD_CLOSURE_VIA_SUPPORT_ONLY`), и только когда нет pending authorizations / открытых споров / незавершённых депозитов / ожидаемых возвратов (`CARD_CLOSURE_WAIT_FOR_PENDING_ACTIVITY`). Остаток переводится на другую карту, иначе support/finance case (`CARD_CLOSURE_BALANCE_HANDLING`).
* Истёкшая карта не перевыпускается автоматически; пользователю предлагается купить новую (`EXPIRED_CARD_NEW_PURCHASE_OFFER`).
* При массовом инциденте провайдера — он исключается из каскада (`CARD_PROVIDER_INCIDENT_RESPONSE`); сервис может сам выпустить новую карту за свой счёт (`PROVIDER_INCIDENT_AUTO_CARD_REISSUE`), старая помечается `blocked`, баланс переносится через ledger (`OLD_CARD_BLOCKED_AFTER_PROVIDER_INCIDENT_REISSUE`, `AUTO_BALANCE_TRANSFER_ON_PROVIDER_REISSUE`).

Ключевые события: `Card.IssuancePending`, `Card.IssuanceConfirmed`, `Card.CredentialsIssued`, `Card.CredentialsViewed`, `Audit.CardSensitiveDataViewed`, `Card.Activated`, `Card.Frozen / Unfrozen`, `Card.Blocked / Unblocked`, `Card.ClosingPending / Closed`, `Card.Expired`, `Card.ProviderIssuanceFailed`, `Card.IssuanceCascadedToProvider`, `Card.IssuanceSlaBreached`, `Card.PhysicalProductionStarted/Produced`, `Card.Shipped / Delivered / DeliveryFailed`, `Provider.IncidentDetected`, `Card.MassReissueRequired`, `Card.ReissuedAtServiceExpense`, `Card.BalanceTransferred`.

ACL: `IssuerAdapter` — anti-corruption layer над card issuing/CaaS providers; нормализует команды и webhooks (`Card.IssuanceSubmittedToProvider` ↔ внешний API, `Card.IssuanceConfirmed` ↔ нормализованный webhook).

***

#### 3.6. SbpDeposits

Назначение: приём RUB через СБП, обработка плательщика, лимиты, KYC-триггеры, возвраты.

Агрегаты:

* `SbpDepositIntent` — заявка на пополнение с quote и payment instructions (QR/ссылка). TTL 2 часа.
* `SbpDeposit` — фактическое пополнение от провайдера.
* `SbpPayer` — плательщик с двумя fingerprint:
  * `SbpPayerPersonFingerprint` — человек (нормализованное ФИО + telephone hash). Один человек из разных банков считается одним (`SBP_SAME_NAME_SAME_PERSON_WITH_SIGNAL_ACCUMULATION`).
  * `SbpPayerInstrumentFingerprint` — инструмент (банк/счёт/телефон/provider customer id).
* `ReferenceSbpPayer` — эталонный плательщик пользователя; фиксируется только по первому успешно зачисленному депозиту (`SBP_REFERENCE_PAYER_BINDING`).
* `DepositLimit` — лимит по карте за период. Считается по сумме credited/reserved депозитов, а не по балансу (`DEPOSIT_LIMIT_BY_CREDITED_AMOUNT_NOT_BALANCE`). Перед созданием депозита — precheck (`DEPOSIT_LIMIT_PRECHECK`); резерв на quote window (`DEPOSIT_LIMIT_RESERVATION`).

Инварианты:

* ФИО плательщика и KYC-ФИО сравниваются после нормализации (регистр, пробелы, ё/е, порядок слов, варианты с/без отчества) — `SBP_PAYER_NAME_NORMALIZATION`.
* Lifetime-счётчик уникальных плательщиков — по человеку, не по инструменту (`SBP_PAYER_PERSON_VS_INSTRUMENT`).
* Late-платёж после quote → не зачисляется и возвращается (`SBP_LATE_PAYMENT_REFUND`).
* До KYC: если пришёл новый/чужой плательщик — депозит не зачисляется, инициируется возврат, требуется KYC (`SBP_DIFFERENT_PAYER_REFUND_AND_KYC_BEFORE_KYC`).
* Сумма СБП > `N` RUB → KYC-триггер (`SBP_HIGH_AMOUNT_KYC_THRESHOLD`). Первый депозит выше `N` удерживается до KYC, таймер 1-2 часа; не пройден → возврат (`SBP_HIGH_AMOUNT_FIRST_PAYER_KYC_HOLD`). После KYC порог по сумме снимается, тарифные лимиты остаются (`SBP_KYC_THRESHOLD_REMOVED_AFTER_KYC`).
* 6-й уникальный плательщик после KYC ещё проходит, после этого включается `sbp_only_kyc_payer_allowed` (`SBP_SIXTH_PAYER_GRACE_AND_RESTRICT`). После ограничения разрешены только депозиты от плательщика, ФИО которого совпадает с KYC (`SBP_RESTRICT_TO_KYC_NAME_AFTER_PAYER_LIMIT`). Чужой плательщик после ограничения возвращается (`SBP_PAYER_CHECK_AFTER_PAYMENT`).
* Снять ограничение может только compliance/admin с audit (`SBP_DEPOSIT_RESTRICTION_MANUAL_LIFT`).

Ключевые события: `Sbp.Deposit.Initiated/Paid/Credited/OnHold/Failed/Expired`, `Sbp.Deposit.LatePaid`, `Sbp.Deposit.ExcessDetected`, `Sbp.RefundRequested / Refunded`, `Sbp.PayerObserved`, `Sbp.PayerFingerprintCreated`, `Sbp.PayerBoundToUser`, `Sbp.PayerMatchedToKycIdentity`, `Sbp.PayerMismatchDetected`, `Sbp.UniquePayerCountChanged`, `Card.DepositLimitChecked/Reserved/Released/Consumed/Exceeded`, `Risk.KycThresholdExceeded`, `User.DepositRestrictionApplied/Lifted`.

***

#### 3.7. CryptoDeposits

Назначение: приём crypto и стейблов, обработка late/unmatched депозитов, claim flow.

Агрегаты:

* `CryptoDepositIntent` — заявка с выбором актива и сети, quote 2 часа.
* `DepositAddress` — адрес для пополнения, выданный провайдером.
* `CryptoDeposit` — фактическое пополнение с `TxHash`. Учитывается в стейблах на выходе процессинга (`CRYPTO_PROCESSING_OUTPUT_STABLES`); конкретный стейбл и казначейские операции — внутренние (`INTERNAL_TREASURY_HANDLES_CAAS_FUNDING`).
* `LateCryptoDeposit` — после quote, но всё ещё сопоставимый с заявкой → может быть зачислен (`CRYPTO_LATE_PAYMENT_CAN_COMPLETE_IF_MATCHED`).
* `UnmatchedCryptoDeposit` — нельзя сопоставить → удерживается до обращения отправителя (`UNMATCHED_CRYPTO_DEPOSIT_HELD_UNTIL_CLAIMED`).
* `CryptoDepositClaim` — заявка отправителя на присвоение unmatched. High-risk: строгая проверка (`UNMATCHED_CRYPTO_CLAIM_STRICT_REVIEW`), Support собирает данные, решение — Admin + ControlObserver (`UNMATCHED_CRYPTO_CLAIM_FOUR_EYES`).
* `CryptoLateMatchingMetadata` — служебные данные для будущего сопоставления; retention задаётся технической/compliance политикой (`CRYPTO_LATE_MATCHING_RETENTION`).

Crypto доступно для всего: открытие первой карты, открытие следующих карт, обычные пополнения.

Ключевые события: `Wallet.CryptoDeposit.Initiated/Detected/Confirmed/ConvertedToStable/Credited/Failed`, `Wallet.CryptoDeposit.LateDetected`, `Wallet.CryptoDeposit.MatchedToExpiredQuote`, `Wallet.CryptoDeposit.UnmatchedDetected/UnmatchedHeld`, `Wallet.CryptoDeposit.ClaimStarted/EvidenceSubmitted/ClaimReviewRequested/ClaimApprovedByAdmin/ClaimApprovedByControlObserver/ClaimRejected/MatchedManually`.

***

#### 3.8. PaymentsAnd3DS

Назначение: карточные авторизации, 3DS, клиринг, отказы, лимиты оплаты, настройки карты.

Агрегаты:

* `Authorization` — намерение списать средства; создаёт `LedgerHold`. Может пройти 3DS (`THREE_DS_REQUIREMENT_SOURCES`).
* `Clearing` — финальное списание после авторизации, конвертирует hold в фактическое движение (`HoldCapture`).
* `ThreeDSChallenge` — подтверждение пользователем; неподтверждённое или просроченное → авторизация отклоняется (`THREE_DS_FAILURE_DECLINES_AUTHORIZATION`).
* `PaymentLimit` — лимит карты: суточный, месячный. Применяется более строгий между тарифным и пользовательским (`CARD_PAYMENT_LIMITS`). Уменьшение лимитов и выключение онлайн-платежей — без 2FA (`SAFE_CARD_RESTRICTIONS_WITHOUT_2FA`, `CARD_LIMIT_DIRECTIONAL_2FA`); увеличение — с 2FA, не выше тарифного.
* `OnlinePaymentsSetting` — флаг разрешения онлайн-платежей; включение требует 2FA, выключение — нет.

Decline reasons (`GLOSSARY → Decline reasons v1`): `INSUFFICIENT_FUNDS`, `PAYMENT_LIMIT_EXCEEDED`, `ONLINE_PAYMENTS_DISABLED`, `CARD_FROZEN`, `CARD_BLOCKED`, `THREE_DS_FAILED`, `SUSPICIOUS_OPERATION`, `SERVICE_TEMPORARILY_UNAVAILABLE`. Подозрительная операция в v1 — только декларируется как decline, без авто-заморозки и доп. 2FA (`SUSPICIOUS_OPERATION_DECLINE_ONLY_V1`). Внутренние причины provider liquidity не показываются пользователю (`HIDE_PROVIDER_LIQUIDITY_REASON_FROM_USER`).

Ключевые события: `Tx.Authorization.Registered/Approved/Declined/Reversed/Cleared/RefundedByMerchant`, `Card.PaymentLimitChecked/Exceeded`, `Card.OnlinePaymentPermissionChecked`, `ThreeDS.ChallengeRequired/Presented/Approved/Declined/Expired/Failed`, `Ledger.HoldPlaced/Released/Captured/Expired`, `Card.UserPaymentLimitsUpdated`, `Card.OnlinePaymentsDisabledByUser/EnabledByUser`.

***

#### 3.9. LedgerAndFinance

Назначение: единый источник истины по деньгам через double-entry append-only ledger.

Агрегаты:

* `MasterAccount` — фактический счёт сервиса (omnibus у провайдера / custody / банка). Не пользовательский (`OMNIBUS_FUNDS_LEDGER_ATTRIBUTION`).
* `LedgerAccount` — счёт ledger по назначению (user card balance attribution, partner balance, treasury, fees). Отдельные accounts по типу баланса (`SEPARATE_LEDGER_ACCOUNTS_BY_BALANCE_TYPE`).
* `LedgerTransaction` — логическая операция, состоящая из набора `LedgerEntry`.
* `LedgerEntry` — атомарная проводка `debit`/`credit` со ссылкой на причину (auth, clearing, deposit, refund, manual adjustment, reissue balance transfer и т. п.). Append-only.
* `LedgerHold` — резерв под авторизацию или pending-операцию. Жизненный цикл: `placed → captured | released | expired`.
* `BalanceProjection` — рассчитанный из entries баланс; быстрая проекция для UI/админки.
* `ManualAdjustment` — ручная корректировка только через ledger transaction, с обязательной причиной и approval. Создатель не одобряет сам (`MANUAL_ADJUSTMENT_THROUGH_LEDGER_WITH_APPROVAL`, `FOUR_EYES_MANUAL_ADJUSTMENT`).

Каждая запись имеет attribution: к пользователю, карте, партнёру или внутреннему назначению (`MASTER_ACCOUNTS_WITH_USER_ATTRIBUTED_LEDGER_ENTRIES`).

Ключевые события: `Ledger.MasterAccount.Opened`, `Ledger.Transaction.Posted`, `Ledger.Entries.Posted`, `Ledger.Entries.Reversed`, `Ledger.EntryAttributedToUser/Card/Partner`, `BalanceProjection.Updated/Rebuilt`, `Finance.ManualAdjustmentRequested/SelfApprovalRejected/Approved/Rejected`.

***

#### 3.10. Treasury

Назначение: funding card/CaaS provider balance, контроль credit limit, срочные алерты.

Агрегаты:

* `ProviderBalance` — баланс сервиса у провайдера; недостаточен → `URGENT_CAAS_FUNDING_ALERT`.
* `ProviderCreditLimit` — кредитный лимит/овердрафт у провайдера; покрывает временную нехватку (`PROVIDER_CREDIT_LIMIT_BACKSTOP`). Приближение к исчерпанию → срочный treasury alert.
* `Funding` — операция пополнения провайдера казначейством (вручную в v1).

Ключевые события: `Treasury.ProviderBalanceLowDetected`, `Treasury.ProviderCreditLimitConfigured/Used/NearExhaustion/Exhausted`, `Treasury.UrgentFundingAlertRaised`, `Treasury.FundingRequired/Submitted/Confirmed`.

Если funding и credit limit исчерпаны, пользователь видит `SERVICE_TEMPORARILY_UNAVAILABLE`; внутренний `PROVIDER_LIQUIDITY_EXHAUSTED` доступен только админам.

***

#### 3.11. Risk

Назначение: накопление risk-сигналов и принятие risk decisions.

Агрегаты:

* `RiskSignal` — отдельный сигнал. SBP-сигналы v1 (`SBP_RISK_SIGNALS_V1`):
  * `SBP_TOO_MANY_UNIQUE_PAYERS`
  * `SBP_NEW_PAYER_AFTER_RESTRICTION`
  * `SBP_PAYER_MISMATCH_KYC_NAME`
  * `SBP_FREQUENT_PAYER_CHANGE`
  * `SBP_PAYER_LINKED_TO_MULTIPLE_USERS`
  * `SBP_INSTRUMENT_LINKED_TO_MULTIPLE_USERS`
  * `SBP_INSTRUMENT_HAS_MANY_PROBLEM_PAYMENTS`
  * `SBP_RETRY_AFTER_REFUND_OR_REJECTION`
* `RiskEvaluation` — оценка по набору сигналов и правил.
* `RiskDecision` — итог: `allow | deny | review | restrict | warn`.
* `UserWarning` — мягкое предупреждение пользователю.
* `DepositRestriction` — типизированное ограничение (например `sbp_only_kyc_payer_allowed`).

Реакции v1 (`RISK_ACTIONS_V1`): копим сигналы, показываем в админке, предупреждаем пользователя, ограничиваем депозиты. Автоматический soft-block по этим сигналам не делается. Restriction по СБП-сигналам касается только СБП, crypto не ограничивается (`SBP_ONLY_KYC_PAYER_RESTRICTION`).

Ключевые события: `Risk.SignalRecorded/Aggregated`, `Risk.Evaluation.Performed`, `Risk.ScoreChanged`, `Risk.ThresholdExceeded`, `Risk.UserWarningIssued`.

***

#### 3.12. SupportAndDisputes

Назначение: тикеты, AI-intake, споры, эскалация.

Агрегаты:

* `SupportTicket` — обращение пользователя. Связывается с картой/транзакцией/депозитом/спором (`LinkedEntity`). Support не делает financial actions, refunds, manual adjustments, restriction lift (`SUPPORT_NO_FINANCIAL_OR_RESTRICTION_ACTIONS`).
* `AiIntake` — AI-ассистент собирает первичный контекст. AI отвечает только по опубликованной knowledge base (`AI_GROUNDED_ANSWERS_ONLY`); если данных мало — эскалирует. Ответы желательно логировать с источниками для аудита (`AI_ANSWER_TRACEABILITY`).
* `Dispute` — спор; открывается только по cleared-транзакции и только через Support (`DISPUTE_ONLY_FOR_CLEARED_TX_VIA_SUPPORT`).
* `AiDisputeIntake` — AI собирает данные спора: транзакция, причина, описание, доказательства, ожидание пользователя (`AI_DISPUTE_INTAKE_BEFORE_HUMAN_ESCALATION`). AI не принимает финальное решение (`AI_NO_FINAL_DISPUTE_DECISION`).

Ключевые события: `Support.Ticket.Opened/LinkedTo/AiContextAttached/EscalatedToHuman/EscalatedToAdmin/Resolved`, `Support.AdminRequestCreated`, `Ai.DisputeIntakeStarted`, `Ai.DisputeReasonCaptured`, `Ai.DisputeEvidenceUploaded`, `Ai.DisputeLegitimacyChecked`, `Ai.DisputeSummaryGenerated`, `Ai.DisputePreliminaryAssessmentRecorded`, `Dispute.Opened`, `Dispute.EvidenceAttached`, `Dispute.EscalatedToUpstream`, `Dispute.OutcomeRecorded`.

***

#### 3.13. Referral (программа пользователь → пользователь)

Назначение: рефералы между обычными пользователями.

Агрегаты:

* `ReferralCode` — код пользователя. Создаётся только после открытия хотя бы одной карты и только по явному действию (`REF_PROGRAM_REQUIRES_OPEN_CARD`, `REF_LINK_AFTER_CARD_OPENED`).
* `Referral` — связка реферера и приглашённого. Активируется после открытия карты и первого депозита приглашённого (`REFERRAL_ACTIVATION_REQUIRES_CARD_AND_FIRST_DEPOSIT`).
* `Reward` — бонус. Получатели и суммы — конфигурируемые; гипотеза: бонус обеим сторонам (`REFERRAL_REWARD_RECIPIENTS_CONFIGURABLE`).
* `RewardBalance` — накопленный бонусный баланс пользователя.
* `RewardTransferToCard` — перевод бонусов на карту. Доступен после $200 (`REWARD_TRANSFER_TO_CARD_AFTER_200_USD`, `REFERRAL_PAYOUT_MIN_THRESHOLD`); не автоматический — пользователь сам нажимает «перевести» (`MANUAL_REWARD_TRANSFER`); пользователь сам выбирает целевую карту (`USER_SELECTS_REWARD_TRANSFER_CARD`).

Ключевые события: `Ref.CodeGenerationRequested/Rejected`, `Ref.Code.Generated`, `Ref.LinkCreated`, `Referral.Created`, `Referral.ActivationEligibilityMet`, `Referral.Activated`, `Reward.EligibilityComputed/Accrued/BalanceUpdated/PayoutThresholdReached`, `Reward.TransferTargetCardSelected/TransferToCardRequested/TransferToCardCompleted`.

***

#### 3.14. Affiliate (партнёрская программа)

Назначение: B2B-партнёры, кабинет, индивидуальные условия, postback API, выплаты.

Агрегаты:

* `PartnerApplication` — заявка партнёра. Кабинет и ссылки выдаются только после approval (`AFFILIATE_REQUIRES_APPROVAL`); approve может Admin или affiliate manager (`AFFILIATE_APPROVAL_RBAC`).
* `AffiliatePartner` — партнёр с индивидуальными условиями: фиксированный CPA за активацию и/или RevShare с обменной маржи депозитов (`AFFILIATE_CUSTOM_TERMS`).
* `AffiliateLink` / `AffiliateCreative` / `SubId` — материалы и метки.
* `AffiliateAttribution` — атрибуция трафика партнёру.
* `AffiliateCommission` — комиссия. Начисляется в момент карточной активации привлечённого клиента и каждого его последующего пополнения (`AFFILIATE_COMMISSION_ACCRUAL`).
* `AffiliatePayout` — раз в месяц по индивидуальным условиям (`AFFILIATE_MONTHLY_CUSTOM_PAYOUTS`).
* `AffiliatePostbackEndpoint` — конфигурация partner postback API.

Postback policy:

* Внутренний tracking всегда (`AFFILIATE_INTERNAL_TRACKING_AND_PARTNER_POSTBACKS`).
* Раскрываемые события партнёру: `click`, `registration`, `kyc_approved`, `first_card_opened`, `new_card_bought`, `first_deposit`, `new_deposit`, `first_spend`, `commission_accrued`, `payout_paid`.
* Raw PII не передаётся, только masked (`AFFILIATE_POSTBACK_NO_RAW_PII`).
* Доставка near-realtime (`AFFILIATE_POSTBACK_NEAR_REALTIME`).
* Retry policy (`AFFILIATE_POSTBACK_RETRY_POLICY`): `2xx` — доставлено; `408/429/5xx/network timeout` — exponential backoff до 8 попыток / 24 часа; `400/401/403/404` — ошибка настройки без retry; payload подписан HMAC; manual retry разрешён.

Ключевые события: `Affiliate.ApplicationSubmitted/Reviewed/Approved/Rejected`, `Affiliate.PartnerRegistered`, `Affiliate.CabinetAccessGranted`, `Affiliate.LinkCreated`, `Affiliate.ClickRecorded`, `Affiliate.AttributionCaptured`, `Affiliate.RegistrationAttributed`, `Affiliate.KycApprovedAttributed`, `Affiliate.FirstCardOpenedAttributed`, `Affiliate.NewCardBoughtAttributed`, `Affiliate.FirstDepositAttributed`, `Affiliate.NewDepositAttributed`, `Affiliate.FirstSpendAttributed`, `Affiliate.RevenueAttributed`, `Affiliate.CustomerActivated`, `Affiliate.CardOpeningCommissionAccrued`, `Affiliate.DepositCommissionAccrued`, `Affiliate.ExchangeRevenueCommissionAccrued`, `Affiliate.BalanceUpdated`, `Affiliate.TierProgressChanged/TierChanged`, `Affiliate.PayoutCycleStarted/Computed/Approved/Paid`, `Affiliate.Postback*` (см. EVENT\_STORMING § Affiliate).

***

#### 3.15. Notifications

Назначение: пользовательские настройки и доставка уведомлений.

Агрегаты:

* `NotificationPreference` — настройки пользователя по категориям и каналам.
* `NotificationCategory` — категория с признаком important. Для important нельзя отключить все каналы (`IMPORTANT_NOTIFICATION_CATEGORY_MIN_ONE_CHANNEL`); для не-important — можно (`NON_IMPORTANT_NOTIFICATIONS_CAN_BE_FULLY_DISABLED`).
* `NotificationChannel` — `tg | email | push | in_app`. Канал — это атрибут события доставки, не отдельный event type (`NOTIFICATION_CHANNEL_AS_PAYLOAD`).
* `NotificationTemplate` — текст. Изменение требует approval (`NOTIFICATION_TEMPLATE_CHANGES_REQUIRE_APPROVAL`).
* `NotificationOutbox` — очередь гарантированной доставки.

Категории и важность — `GLOSSARY → Notification categories`. Важные категории: `TxAll`, `ThreeDS`, `Disputes`, `Security`, `KycCompliance`, `LegalUpdates`, `Cards` (`IMPORTANT_NOTIFICATION_CATEGORIES`, `CARD_NOTIFICATIONS_ARE_IMPORTANT`).

Ключевые события: `Notification.PreferenceChangeRequested/Updated/Rejected`, `Notification.Outbox.Enqueued`, `Notification.Sent / Failed / DeadLettered`, `Notification.Opened / Read / ActionClicked`.

***

#### 3.16. AdminPanel

Назначение: внутренний интерфейс операторов с ролями, правами, approval-ами и audit.

Разделы v1: Dashboard, Users, Support, Transactions, Cards, Finance, Partners, Content, Analytics, System. Feature flags и Settings — future scope (`NO_ADMIN_FEATURE_FLAGS_OR_SYSTEM_SETTINGS_V1`, `FEATURE_FLAGS_AND_SETTINGS_FUTURE_SCOPE`). Массовые exports/raw downloads в v1 нет (`NO_BULK_DATA_EXPORTS_V1`).

Роли v1 (`ADMIN_PANEL_V1_ROLES`): `Admin`, `Support`, `ControlObserver`. Модель построена на ролях и granular permissions, расширяема (`ADMIN_RBAC_EXTENSIBLE`).

Approval:

* Все критичные admin actions требуют four-eyes (`FOUR_EYES_FOR_CRITICAL_ADMIN_ACTIONS_V1`).
* `SelfApproval` запрещён.
* Снятие депозитного ограничения — только compliance/admin, не support (`DEPOSIT_RESTRICTION_RBAC`).

Агрегаты:

* `Role`, `Permission`, `Operator`.
* `CriticalAdminAction` — действие, требующее approval.
* `Approval` — подтверждение action другим оператором.
* `AuditLog` — append-only (см. ниже).

Ключевые события: `Admin.RoleCreated/Updated`, `Admin.PermissionGranted/Revoked`, `Admin.OperatorCreated/RoleAssigned/PermissionOverridden`, `Admin.CriticalActionRequested/SelfApprovalRejected/Approved/Rejected`, `Audit.AdminAction.Performed`, `Audit.SystemAction.Performed`.

***

#### 3.17. LegalAndContent

Назначение: юридические документы, тарифы как документы, FAQ/knowledge base, шаблоны уведомлений.

Агрегаты:

* `LegalDocument` с версионированием. Принятие по контексту (`LEGAL_ACCEPTANCE_BY_CONTEXT`):
  * Общие Terms + Privacy — при регистрации.
  * Условия тарифа и выпуска карты — при открытии каждой новой карты.
  * Новая версия может требовать re-acceptance перед следующим релевантным действием.
* `KnowledgeBase` — публикуется через approval (`KNOWLEDGE_BASE_CHANGES_REQUIRE_APPROVAL`).
* `NotificationTemplate` — публикуется через approval.

Ключевые события: `Legal.Document.Published/Viewed/AcceptanceRequired/Accepted/VersionSuperseded`, `Card.TermsAcceptanceRequired/Accepted`, `NotificationTemplate.ChangeRequested/Approved/Published/Rejected`, `KnowledgeBase.ChangeRequested/Approved/Published/Rejected`, `Ai.KnowledgeBaseUpdated`.

***

#### 3.18. Privacy

Назначение: PII, доступ к ним, закрытие аккаунта, retention.

Агрегаты:

* `PiiAccessRequest` — запрос на полный доступ к PII; только Admin, с причиной и audit (`FULL_PII_ACCESS_REQUIRES_JUSTIFICATION`, `ADMIN_ONLY_FULL_PII_ACCESS`). По умолчанию PII в админке маскированы (`PII_MASKED_BY_DEFAULT_INTERNAL_UI`).
* `AccountClosure` — закрытие аккаунта. Возможно только при нулевом балансе (`ACCOUNT_CLOSURE_REQUIRES_ZERO_BALANCE`). Остаток выводится только crypto withdrawal (`ACCOUNT_CLOSURE_WITHDRAWAL_CRYPTO_ONLY`); withdrawal требует Admin + ControlObserver (`ACCOUNT_CLOSURE_WITHDRAWAL_FOUR_EYES`). После закрытия данные продолжают храниться по retention (`Privacy.RetentionStarted`).
* `Withdrawal` — в v1 только при закрытии аккаунта (`WITHDRAWAL_ONLY_FOR_ACCOUNT_CLOSURE_V1`).

Ключевые события: `Privacy.AccountClosureRequested`, `Account.ClosureBlockedByPositiveBalance`, `User.WithdrawalRequired`, `Withdrawal.Requested/ApprovedByAdmin/ApprovedByControlObserver/SubmittedToCustody/Settled`, `Account.ClosureReady`, `User.Closed`, `Privacy.RetentionStarted`, `Privacy.DataMaskedForOperator`, `PiiAccess.Requested/Granted`, `PiiAccessed`, `Audit.PiiAccessed`.

***

#### 3.19. Reconciliation

Назначение: ежедневная сверка между ledger, master accounts, провайдерами и проекциями.

Агрегаты:

* `ReconRun` — запуск сверки за период/слой.
* `SourceSnapshot` — снимок источника для сверки.
* `ReconciliationDiscrepancy` — выявленное расхождение.
* `DailyClose` — закрытие операционного дня.

В v1 сверка и закрытие дня подтверждаются вручную: Admin + ControlObserver (`MANUAL_RECON_APPROVAL_V1`, `RECON_APPROVAL_ADMIN_AND_CONTROL_OBSERVER_V1`). Автоматизация — позже.

Ключевые события: `Recon.Run.Started/Completed`, `Recon.SourceSnapshotCaptured`, `Recon.DiscrepancyDetected/Resolved`, `Recon.ReviewRequired/Started/ApprovedByControlObserver/ApprovedByAdmin/Rejected`, `Recon.DailyClose.Signed`.

***

### 4. Refunds и withdrawals (сводно по контекстам)

Из `REFUND_SCENARIOS_V1`, в v1 разрешены:

* Автоматический СБП-возврат (late/mismatch) — без approval, но с audit (`AUTOMATIC_SBP_REFUNDS_AUDITED`).
* Возврат при неуспешном/задержанном выпуске карты — через support flow.
* Crypto withdrawal при закрытии аккаунта.
* Возврат при положительном исходе спора.

Все, кроме автоматических СБП-возвратов, требуют Admin + ControlObserver (`REFUND_APPROVAL_RULES_V1`).

***

### 5. Event Sourcing

#### 5.1. Event Store

* Хранилище событий — append-only поток per stream.
* `stream_id = "{context}.{aggregate}.{aggregate_id}"`, например `cards.card.<id>`, `sbp.deposit.<id>`, `ledger.account.<id>`.
* `stream_version` — позиция события в стриме; `(stream_id, stream_version)` уникален.
* Глобальный порядок — через `global_seq` для проекций и replay.
* Партиционирование по `recorded_at` (например, помесячно) — для отрезания старых партиций без переезда.

#### 5.2. Конверт события

Каждое событие несёт стандартный конверт:

```
event_id            идентификатор события
event_type          Context.Aggregate.EventName
event_version       версия схемы события
stream_id           {context}.{aggregate}.{id}
stream_version      позиция в стриме
occurred_at         когда событие случилось в домене
recorded_at         когда событие записано
metadata
  correlation_id    сквозной идентификатор бизнес-потока
  causation_id      event_id события или command_id, породившего это
  actor             { kind: User | Operator | System | Webhook, id }
  source            { service, version }
  request_id        для трассировки
payload             поля события
```

`correlation_id` пробрасывается между всеми BC одного бизнес-потока. `causation_id` указывает прямого предка.

#### 5.3. Идемпотентность

Каждый источник входящих событий имеет ключ дедупликации:

| Источник                                           | Ключ                                             |
| -------------------------------------------------- | ------------------------------------------------ |
| webhook от card issuing/CaaS provider              | provider request\_id из payload                  |
| webhook от crypto/custody provider                 | provider event\_id                               |
| webhook от СБП-провайдера                          | payment\_id + provider\_id                       |
| команда от пользователя                            | заголовок `Idempotency-Key`, TTL 24 часа         |
| внутренняя команда (например, `PostLedgerEntries`) | детерминированный hash от originating\_event\_id |

При повторе возвращается тот же результат, новое событие не создаётся.

#### 5.4. Snapshots

* Snapshot per stream — кэш состояния агрегата каждые N событий (по умолчанию N = 200).
* Snapshot не источник истины: его всегда можно отбросить и пересобрать стрим из событий.
* Для `LedgerAccount` дополнительно — snapshot на конец операционного дня.

#### 5.5. Эволюция схемы (event versioning)

Допустимо без bump:

* Добавление optional-полей.

С bump `event_version`:

* Расширение enum.
* Изменение семантики или структуры.

Запрещено:

* Удаление полей. Помечается `deprecated`, читается старыми проекциями через upcaster.

Upcaster: для каждого `event_type` цепочка `upcast(payload, version) → next_version`.

#### 5.6. CQRS и проекции

Каждая проекция:

* хранит свой `last_processed_global_seq`;
* читает события по `event_type`;
* может быть пересобрана (`Rebuild`) с нуля.

Минимальный набор проекций (соответствие `EVENT_STORMING.md`):

* `users_view` (IdentityAndAccess)
* `user_kyc_view`, `deposit_restrictions_view` (KycAndCompliance)
* `tariffs_view`, `payment_quotes_view` (TariffsAndCardOpening)
* `cards_view`, `card_credentials_audit_view` (Cards)
* `sbp_deposits_view`, `sbp_payers_view` (SbpDeposits)
* `crypto_deposits_view`, `unmatched_crypto_view` (CryptoDeposits)
* `transactions_view`, `holds_view` (PaymentsAnd3DS)
* `balance_projections_view`, `ledger_attribution_view` (LedgerAndFinance)
* `treasury_alerts_view` (Treasury)
* `risk_signals_view`, `user_warnings_view` (Risk)
* `tickets_view`, `disputes_view` (SupportAndDisputes)
* `referral_dashboard_view`, `reward_balance_view` (Referral)
* `partner_dashboard_view`, `postback_log_view` (Affiliate)
* `notifications_outbox_view`, `delivery_log_view` (Notifications)
* `admin_actions_view`, `audit_log_view` (AdminPanel)
* `legal_acceptance_view` (LegalAndContent)
* `pii_access_view`, `closures_view` (Privacy)
* `recon_runs_view`, `discrepancies_view` (Reconciliation)

#### 5.7. Outbox

Внешние эффекты (внешние API, отправка уведомления, postback партнёру) пишутся в `outbox` в той же транзакции, что и доменное событие. Воркер отправляет, retry-ит, помечает `Sent` / `DeadLettered`.

#### 5.8. Replay и rebuild

* При фиксе бага в проекции: `DROP` таблицы → replay с `global_seq = 1`.
* При новой read-модели: создать таблицу + проектор → catch up.
* Все события неизменяемые → replay даёт идентичный результат с точностью до версии проектора.

***

### 6. Process Managers (саги)

Process Manager — длинный кросс-контекстный процесс. Реагирует на события, отправляет команды, ждёт следующих событий, держит таймеры. Сохраняется как event stream `pm.{name}.{id}`.

#### 6.1. CardOpening

Триггер: `Payment.QuoteAccepted` после оплаты (СБП или crypto credited).

Шаги:

1. Зарезервировать стоимость выпуска и первый депозит ($10 минимум).
2. Дождаться `Sbp.Deposit.Credited` или `Wallet.CryptoDeposit.Credited`.
3. Отправить `Card.IssuanceSubmittedToProvider`.
4. Каскад на следующего провайдера при `Card.ProviderIssuanceFailed` (`CARD_ISSUANCE_PROVIDER_CASCADE`).
5. Через 24 часа — `Card.IssuanceDelayed` + уведомление и алерт админам.
6. Через 48 часов — `Support.Ticket.Opened` с выбором «ждать или возврат».
7. По `Card.IssuanceConfirmed` → `Card.CredentialsIssued` → `Card.Activated` → `Funnel.FirstCardOpened`.

#### 6.2. SbpDepositSaga

Триггер: `Sbp.Deposit.Initiated`.

Шаги:

1. `DEPOSIT_LIMIT_PRECHECK` → если не проходит, депозит не создаётся.
2. Зарезервировать лимит на 2 часа (`DEPOSIT_LIMIT_RESERVATION`).
3. Ожидание `Sbp.Deposit.Paid`.
4. Если quote истёк до оплаты → `Sbp.Deposit.LatePaid` → возврат.
5. Если плательщик не подходит до KYC или после restriction → возврат + KYC trigger при необходимости.
6. Если сумма > `N` и первый депозит → hold + KYC, таймер 1-2 часа.
7. По успеху → `Ledger.PostEntries` → `Sbp.Deposit.Credited` → консьюм лимита → notifications.

#### 6.3. CryptoDepositSaga

Триггер: `Wallet.CryptoDeposit.Initiated` или `Wallet.CryptoDeposit.Detected`.

Шаги:

1. Дождаться подтверждений сети.
2. Сопоставить с заявкой (включая late-сценарий).
3. Если matched → конверсия в стейбл, `Ledger.PostEntries`, `Credited`.
4. Если unmatched → `UnmatchedHeld` до claim.
5. Claim flow — high-risk: support собирает данные, Admin + ControlObserver одобряют.

#### 6.4. AuthorizationToClearing

Триггер: `Tx.Authorization.Registered`.

Шаги:

1. Risk evaluation, payment limit, online payments check.
2. 3DS при необходимости; не подтверждён в срок → `Tx.Authorization.Declined` (`THREE_DS_FAILURE_DECLINES_AUTHORIZATION`).
3. По `Approved` → `Ledger.HoldPlaced`.
4. По webhook clearing → `Ledger.HoldCaptured` + `Ledger.Entries.Posted` + notification.
5. По reversal до clearing → `Ledger.HoldReleased`.
6. По `RefundedByMerchant` → reversal entries.

#### 6.5. CardClosureSaga

Триггер: `Card.ClosingPending` (от Support).

Шаги:

1. Дождаться завершения pending authorizations, споров, депозитов и ожидаемых возвратов.
2. Перевод остатка на другую карту пользователя через `Ledger.Entries.Posted` (либо открытие support/finance case).
3. `Card.Closed`.

#### 6.6. AccountClosureSaga

Триггер: `Privacy.AccountClosureRequested`.

Шаги:

1. Если положительный баланс → `Account.ClosureBlockedByPositiveBalance` → `User.WithdrawalRequired`.
2. По запросу crypto withdrawal → `Withdrawal.Requested` → Admin + ControlObserver approve → `Withdrawal.SubmittedToCustody` → `Withdrawal.Settled`.
3. По `Account.ClosureReady` → `User.Closed` → `Privacy.RetentionStarted`.

#### 6.7. ProviderIncidentSaga

Триггер: `Provider.IncidentDetected`.

Шаги:

1. Исключить провайдера из каскада (`Provider.DisabledFromCascade`).
2. Если затронуты карты пользователей → `Card.MassReissueRequired`.
3. По каждой карте: `Card.ReissueStarted` → новая карта за счёт сервиса (`Card.ReissuedAtServiceExpense`) → `Card.CredentialsIssued`.
4. Перенос баланса: `Card.BalanceTransferStarted` → `Ledger.Entries.Posted` → `Card.BalanceTransferred`.
5. Старая карта → `Card.Blocked`.

#### 6.8. NurtureAndReactivation

Триггеры: незавершённый funnel milestone / 10 дней неактивности.

Шаги:

1. По расписанию `15м / 24ч / 72ч / 7д` — `Nurture.StepTriggered` → `Nurture.MessageSent` через канал по платформе входа.
2. По `Funnel.*` соответствующая цепочка останавливается.
3. После 10 дней неактивности — `Reactivation.SequenceStarted`, кроме случаев отключённых маркетинговых преференций.

#### 6.9. ReconciliationDailyClose

Триггер: cron-задача конца дня.

Шаги:

1. `Recon.Run.Started` для каждого слоя.
2. Снимки источников, поиск discrepancies.
3. `Recon.ReviewRequired` → ручной review ControlObserver и Admin.
4. `Recon.DailyClose.Signed`.

***

### 7. Каталог событий (минимальный, по контекстам)

Полный список и формулировки — в `EVENT_STORMING.md`. Здесь — навигация.

| Контекст              | События (фрагмент)                                                                                                                                                                                                                                                                                                                                |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| EntrySources          | `Acquisition.LinkOpened`, `Acquisition.AttributionCaptured`, `Acquisition.FunnelEntered`, `Funnel.RegistrationCompleted`, `Funnel.FirstCardOpened`, `Funnel.FirstDepositCompleted`, `Nurture.*`, `Reactivation.*`                                                                                                                                 |
| IdentityAndAccess     | `User.Registered`, `User.PhoneConfirmed`, `User.EmailConfirmed`, `Otp.*`, `TwoFactor.*`, `Device.*`, `Session.*`, `Telegram.*`, `User.TelegramIdentityLinked`                                                                                                                                                                                     |
| KycAndCompliance      | `KYC.Application.*`, `KYC.Document.Submitted`, `KYC.FaceCheckPassed/Failed`, `KYC.RetryLimitExceeded`, `Compliance.SanctionsHitRecorded`, `User.DepositRestriction*`                                                                                                                                                                              |
| TariffsAndCardOpening | `Tariff.*`, `Fx.MarkupUpdatedByAdmin`, `Payment.Quote*`, `Card.OpeningPaymentInitiated`, `Card.IssuanceFeeReserved`, `Card.InitialDepositReserved`                                                                                                                                                                                                |
| Cards                 | `Card.IssuancePending/Confirmed`, `Card.CredentialsIssued/Viewed`, `Card.Activated`, `Card.Frozen/Unfrozen`, `Card.Blocked/Unblocked`, `Card.ClosingPending/Closed`, `Card.Expired`, `Card.Shipped/Delivered/DeliveryFailed`, `Provider.IncidentDetected`, `Card.MassReissueRequired`, `Card.ReissuedAtServiceExpense`, `Card.BalanceTransferred` |
| SbpDeposits           | `Sbp.Deposit.*`, `Sbp.Payer*`, `Card.DepositLimit*`, `Risk.KycThresholdExceeded`                                                                                                                                                                                                                                                                  |
| CryptoDeposits        | `Wallet.CryptoDeposit.*`, `Wallet.CryptoDeposit.Unmatched*`, `Wallet.CryptoDeposit.Claim*`                                                                                                                                                                                                                                                        |
| PaymentsAnd3DS        | `Tx.Authorization.*`, `ThreeDS.*`, `Card.PaymentLimit*`, `Card.OnlinePayments*`, `Ledger.Hold*`                                                                                                                                                                                                                                                   |
| LedgerAndFinance      | `Ledger.MasterAccount.Opened`, `Ledger.Transaction.Posted`, `Ledger.Entries.Posted/Reversed`, `Ledger.EntryAttributedTo*`, `BalanceProjection.Updated/Rebuilt`, `Finance.ManualAdjustment*`                                                                                                                                                       |
| Treasury              | `Treasury.ProviderBalance*`, `Treasury.ProviderCreditLimit*`, `Treasury.UrgentFundingAlertRaised`, `Treasury.Funding*`                                                                                                                                                                                                                            |
| Risk                  | `Risk.SignalRecorded/Aggregated`, `Risk.Evaluation.Performed`, `Risk.ScoreChanged`, `Risk.UserWarningIssued`                                                                                                                                                                                                                                      |
| SupportAndDisputes    | `Support.Ticket.*`, `Ai.Dispute*`, `Dispute.*`                                                                                                                                                                                                                                                                                                    |
| Referral              | `Ref.Code.Generated`, `Referral.*`, `Reward.*`                                                                                                                                                                                                                                                                                                    |
| Affiliate             | `Affiliate.Application*`, `Affiliate.PartnerRegistered`, `Affiliate.*Attributed`, `Affiliate.*CommissionAccrued`, `Affiliate.Payout*`, `Affiliate.Postback*`                                                                                                                                                                                      |
| Notifications         | `Notification.PreferenceChange*`, `Notification.Outbox.Enqueued`, `Notification.Sent/Failed/DeadLettered`, `Notification.Opened/Read/ActionClicked`                                                                                                                                                                                               |
| AdminPanel            | `Admin.Role*`, `Admin.Permission*`, `Admin.Operator*`, `Admin.CriticalAction*`, `Audit.AdminAction.Performed`, `Audit.SystemAction.Performed`                                                                                                                                                                                                     |
| LegalAndContent       | `Legal.Document.*`, `Card.TermsAcceptance*`, `NotificationTemplate.*`, `KnowledgeBase.*`, `Ai.KnowledgeBaseUpdated`                                                                                                                                                                                                                               |
| Privacy               | `Privacy.AccountClosureRequested`, `Withdrawal.*`, `User.Closed`, `Privacy.RetentionStarted`, `PiiAccess.*`, `Audit.PiiAccessed`                                                                                                                                                                                                                  |
| Reconciliation        | `Recon.Run.*`, `Recon.SourceSnapshotCaptured`, `Recon.Discrepancy*`, `Recon.Review*`, `Recon.DailyClose.Signed`                                                                                                                                                                                                                                   |

***

### 8. Каталог команд (минимальный)

| Контекст              | Команды                                                                                                                                                                                                                                                                                                                                                                        |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| EntrySources          | `OpenLink`, `CaptureAttribution`, `EnterFunnel`, `StartNurtureSequence`, `StopNurtureSequence`, `StartReactivationSequence`                                                                                                                                                                                                                                                    |
| IdentityAndAccess     | `StartRegistration`, `LinkPhone`, `LinkEmail`, `RequestOtp`, `VerifyOtp`, `EnableTwoFactor`, `DisableTwoFactor`, `ChangeTwoFactorMethod`, `OpenSession`, `RefreshSession`, `RevokeSession`, `RevokeDevice`, `LinkTelegramIdentity`                                                                                                                                             |
| KycAndCompliance      | `RequireKyc`, `StartKycApplication`, `SubmitKycDocument`, `RecordProviderResult`, `RetryKyc`, `ApplyDepositRestriction`, `LiftDepositRestriction`                                                                                                                                                                                                                              |
| TariffsAndCardOpening | `CreateTariff`, `UpdateTariff`, `PublishTariff`, `ArchiveTariff`, `UpdateIssuancePrice`, `UpdateFxMarkup`, `CreatePaymentQuote`, `AcceptPaymentQuote`, `ExpirePaymentQuote`, `InitiateCardOpeningPayment`, `ReserveIssuanceFee`, `ReserveInitialDeposit`                                                                                                                       |
| Cards                 | `RequestCardIssuance`, `SubmitCardIssuanceToProvider`, `CascadeIssuanceToNextProvider`, `ConfirmIssuance`, `IssueCredentials`, `ActivateCard`, `FreezeCard`, `UnfreezeCard`, `BlockCard`, `UnblockCard`, `RequestCardClosure`, `CloseCard`, `MarkCardExpired`, `SubmitDeliveryAddress`, `RecordDeliveryFailure`, `ReissueAtServiceExpense`, `TransferCardBalance`              |
| SbpDeposits           | `InitiateSbpDeposit`, `RegisterIncomingPayment`, `CreditSbpDeposit`, `RefundSbpDeposit`, `ObservePayer`, `BindReferencePayer`, `ReserveDepositLimit`, `ConsumeDepositLimit`, `ReleaseDepositLimit`                                                                                                                                                                             |
| CryptoDeposits        | `InitiateCryptoDeposit`, `AssignDepositAddress`, `RegisterCryptoTransaction`, `ConfirmCryptoDeposit`, `CreditCryptoDeposit`, `HoldUnmatchedDeposit`, `StartCryptoClaim`, `SubmitClaimEvidence`, `ApproveClaim`, `RejectClaim`, `MatchManually`                                                                                                                                 |
| PaymentsAnd3DS        | `RegisterAuthorization`, `ApproveAuthorization`, `DeclineAuthorization`, `ReverseAuthorization`, `ClearAuthorization`, `RecordMerchantRefund`, `RequestThreeDsChallenge`, `ConfirmThreeDs`, `ExpireThreeDs`, `UpdateUserPaymentLimits`, `EnableOnlinePayments`, `DisableOnlinePayments`, `PlaceLedgerHold`, `CaptureLedgerHold`, `ReleaseLedgerHold`                           |
| LedgerAndFinance      | `OpenMasterAccount`, `PostLedgerEntries`, `ReverseLedgerEntries`, `RebuildBalanceProjection`, `RequestManualAdjustment`, `ApproveManualAdjustment`, `RejectManualAdjustment`                                                                                                                                                                                                   |
| Treasury              | `ConfigureProviderCreditLimit`, `RaiseUrgentFundingAlert`, `RequestProviderFunding`, `SubmitProviderFunding`, `ConfirmProviderFunding`                                                                                                                                                                                                                                         |
| Risk                  | `RecordRiskSignal`, `EvaluateRisk`, `IssueUserWarning`                                                                                                                                                                                                                                                                                                                         |
| SupportAndDisputes    | `OpenTicket`, `LinkTicketToEntity`, `AttachAiContext`, `EscalateTicketToHuman`, `EscalateTicketToAdmin`, `ResolveTicket`, `OpenDispute`, `AttachDisputeEvidence`, `EscalateDisputeToUpstream`, `RecordDisputeOutcome`                                                                                                                                                          |
| Referral              | `RequestReferralCode`, `GenerateReferralCode`, `CreateReferralLink`, `RegisterReferral`, `ActivateReferral`, `AccrueReward`, `RequestRewardTransferToCard`, `CompleteRewardTransferToCard`                                                                                                                                                                                     |
| Affiliate             | `SubmitPartnerApplication`, `ReviewPartnerApplication`, `ApprovePartnerApplication`, `RejectPartnerApplication`, `GrantCabinetAccess`, `CreateAffiliateLink`, `CapturePartnerAttribution`, `AccrueCommission`, `StartPayoutCycle`, `ComputePayout`, `ApprovePayout`, `PayPayout`, `ConfigurePostback`, `RotatePostbackSecret`, `EnqueuePostback`, `RequestManualPostbackRetry` |
| Notifications         | `UpdateNotificationPreference`, `EnqueueOutbox`, `MarkSent`, `MarkFailed`, `MarkDeadLettered`                                                                                                                                                                                                                                                                                  |
| AdminPanel            | `CreateRole`, `UpdateRole`, `GrantPermission`, `RevokePermission`, `CreateOperator`, `AssignOperatorRole`, `OverrideOperatorPermission`, `RequestCriticalAction`, `ApproveCriticalAction`, `RejectCriticalAction`                                                                                                                                                              |
| LegalAndContent       | `PublishLegalDocument`, `RequireAcceptance`, `AcceptDocument`, `RequestKnowledgeBaseChange`, `ApproveKnowledgeBaseChange`, `PublishKnowledgeBase`, `RequestNotificationTemplateChange`, `ApproveNotificationTemplate`, `PublishNotificationTemplate`                                                                                                                           |
| Privacy               | `RequestAccountClosure`, `RequestWithdrawal`, `ApproveWithdrawal`, `SubmitWithdrawalToCustody`, `SettleWithdrawal`, `CloseAccount`, `StartRetention`, `RequestPiiAccess`, `GrantPiiAccess`                                                                                                                                                                                     |
| Reconciliation        | `StartReconRun`, `CaptureSourceSnapshot`, `CompleteReconRun`, `RecordDiscrepancy`, `ResolveDiscrepancy`, `ApproveReconReview`, `RejectReconReview`, `SignDailyClose`                                                                                                                                                                                                           |

***

### 9. Соответствие документам

| Тема в DOMAIN.md                               | Источник правды                                                                                                   |
| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| Термины, canonical names, запрещённые синонимы | `GLOSSARY.md`                                                                                                     |
| Полные списки событий и команд по контекстам   | `EVENT_STORMING.md`                                                                                               |
| Поименованные правила сервиса                  | `SERVICE_POLICIES.md`                                                                                             |
| Тарифы v1 (имена, цены, FX markup)             | `EVENT_STORMING.md → Tariffs & Card Opening`                                                                      |
| Список SBP risk signals v1                     | `EVENT_STORMING.md → Risk` и `SERVICE_POLICIES.md → SBP_RISK_SIGNALS_V1`                                          |
| Decline reasons v1                             | `GLOSSARY.md → Decline reasons v1`                                                                                |
| Notification categories и important            | `GLOSSARY.md → Notification categories` и `SERVICE_POLICIES.md → IMPORTANT_NOTIFICATION_CATEGORIES`               |
| Роли v1 и approvals                            | `GLOSSARY.md → Роли v1` и `SERVICE_POLICIES.md → ADMIN_PANEL_V1_ROLES`, `FOUR_EYES_FOR_CRITICAL_ADMIN_ACTIONS_V1` |

***

### 10. Future scope и open questions

Из всех трёх документов сводно. В v1 не делаем, но модель должна позволять.

Future scope:

* MAKS Mini App как платформа входа.
* Feature flags и system settings через админку.
* Массовые exports / raw downloads.
* Расширенные роли: affiliate manager, finance, compliance.
* Автоматизация reconciliation после стабилизации процессов.
* Обычный (не closure) withdrawal.
* Более широкая матрица risk scoring за пределами СБП.

Open questions:

* Точные депозитные и платёжные лимиты по тарифам.
* Точные значения `N` для СБП KYC threshold.
* Нужны ли KYC levels в продуктовой модели или достаточно `not_verified | verified`.
* Состав полей плательщика, который вернёт выбранный СБП-провайдер.
* Контракт с card issuing/CaaS provider: когда доступны реквизиты физической карты по тарифу.
* Retention period для late/unmatched crypto matching metadata.
* Точные суммы и получатели referral rewards.
* Final templates уведомлений и тексты legal documents.

***

### 11. Версия документа

* Версия: 2.0.0.
* Базируется на `GLOSSARY.md`, `EVENT_STORMING.md`, `SERVICE_POLICIES.md` от 2026-04-30.
* Принцип эволюции: каждое изменение domain-модели — minor; breaking — major. Ссылки на политики и события не должны протухать; при переименовании политики обновляется и DOMAIN.md.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://alt3-capital.gitbook.io/funding-arbitrage-strategy/cart/proektnaya-dokumentaciya/domain-md.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
