# Пример заявки M2M end-to-end

Типовой сценарий: инвестор Иванов И.И. подаёт через ЛК заявку на
перевод 3 ценных бумаг с депо-счёта у БКС в депо-счёт у Ренессанс
Брокера. Один из переводов — паи ПИФ с дробным количеством. ИИС
тип T03.

## Какие данные нужны m2m-core для формирования M2MTransferRequest

Сервис `m2m-core` достаёт следующее из `fansy-store` (рабочая схема
`fansy`) по идентификатору клиента и набору ЦБ:

### 1. Анкета клиента (для `InvestorInformation`)

```sql
SELECT
    c.last_name,
    c.first_name,
    c.middle_name,
    d.document_type,
    d.series   AS document_series,
    d.number   AS document_number
FROM fansy.clients c
JOIN fansy.client_documents d ON d.client_id = c.id
WHERE c.id = :client_id
ORDER BY d.created_at DESC
LIMIT 1;
```

### 2. ИИС-договор (для `IIAAgreementDetails`)

```sql
SELECT agreement_type, agreement_number, agreement_date, broker_inn
FROM fansy.iia_contracts
WHERE client_id = :client_id
ORDER BY agreement_date DESC
LIMIT 1;
```

### 3. Реквизиты передающего/принимающего депозитариев

```sql
SELECT inn
FROM fansy.settlement_requisites
WHERE inn IN (:transferring_inn, :receiving_inn);
```

### 4. Депо-счета и разделы инвестора (для `SettlementAccount`)

```sql
SELECT
    da.deponent_code,
    da.account_id,
    da.section_id,
    da.depository_inn
FROM fansy.depo_accounts da
WHERE da.client_id = :client_id
  AND da.depository_inn = :depository_inn
  AND da.is_active = true;
```

### 5. Информация о ценных бумагах и их остатках

```sql
SELECT
    p.security_code,
    s.isin,
    s.classification,
    s.category,
    s.security_type,
    s.reg_number,
    s.fund_class,
    p.quantity_whole,
    p.quantity_fractional,
    p.isolation_status
FROM fansy.portfolios p
JOIN fansy.securities s USING (security_code)
WHERE p.client_id = :client_id
  AND p.security_code = ANY(:requested_codes)
  AND p.valued_at >= now() - interval '5 minutes';
```

### 6. Проверка достаточности остатков

```sql
SELECT
    p.security_code,
    COALESCE(p.quantity_whole, 0) + COALESCE(p.quantity_fractional, 0) AS available
FROM fansy.portfolios p
WHERE p.client_id = :client_id
  AND p.security_code = ANY(:requested_codes);
```

Сравниваем `available` с запрошенным количеством. Если меньше — отказ
от формирования M2MTransferRequest, ошибка в ЛК.

## Какие данные команда Fansy обязана положить в staging

Из примера выше:

- `clients`: запись на инвестора Иванова И.И.
- `client_documents`: документ с DocumentType `21`.
- `iia_contracts`: договор T03 с брокером (БКС, ИНН 5406121446).
- `depo_accounts`: счёт у БКС с разделом для перевода и счёт у
  Ренессанс Брокера.
- `securities`: 3 записи (SHAR/ORDN, SHAR/PREF, MFUN/UKWN с
  fund_class='A').
- `portfolios`: остатки по этим 3 ЦБ на 1500 / 300 / 2500.75
  соответственно.
- `participants`: НРД, БКС (5406121446), Ренессанс (7709258228) — из
  начального seed.

## Результат

`m2m-core` собирает данные → формирует `M2MTransferRequest` →
валидирует → подписывает (через `crypto-service`) → отправляет в НРД
через `nsd-adapter`. Получает `M2MTransferDecision` от принимающей
стороны, обновляет статус сделки и шлёт callback в ЛК.
