# Выгрузка данных CRM1 из системы взыскания

Документ для команды CRM. Описывает две ручки, по которым можно забрать то, что реально хранится
у нас по данным CRM1, и сверить с тем, что отдаёт ваш API.

## Как получить

```
GET https://<host>/api/export/crm1/loans
GET https://<host>/api/export/crm1/payments
```

```bash
curl -OJ https://<host>/api/export/crm1/loans
```

Обычный GET, без авторизации, без параметров. Один запрос — весь массив одним файлом.

## Что в файле

CSV: разделитель `;`, кодировка UTF-8 с BOM, первая строка — заголовки.

Набор и порядок колонок **совпадает с ответом вашего API**: у займов это те же 53 поля, что
отдаёт `POST /api/loans`, у платежей — те же 11 полей, что отдаёт `POST /api/payments`. Одна
строка — один займ (соответственно, один платёж). Значения — те, что лежат у нас после загрузки,
а не то, что пришло по API: в этом и смысл сверки.

В выгрузку попадает только то, что получено из CRM1. Данные второго CRM в файл не входят.

## Имя файла

`crm1_loans_2026-09-11_05-56.csv`

В имени — момент, когда **закончилась последняя успешная загрузка** данных этого источника
(местное время, UTC+5). Это дата актуальности содержимого: между загрузками файл не меняется,
сколько бы раз его ни скачали. Прерванная или упавшая загрузка данные не меняла и в имя не
попадает.

Если успешной загрузки ещё не было ни разу, в имени будет `unknown`, а файл будет содержать
только строку заголовков.

## Поля, которые всегда пустые

Эти поля приходят от API, но в нашей модели данных для них нет места — мы их не храним и вернуть
не можем. Расхождением их считать не нужно:

| Поле | |
| --- | --- |
| `total` | у займов |
| `order_id` | у займов |
| `municipality_name` | у займов |
| `status_change_date` | у займов |
| `external_id` | у платежей — идентификатор плательщика, не идентификатор платежа |

Ваш API присылает дату погашения сразу в двух полях — `due_date` и `final_date` — с одинаковым
значением. Мы храним её в одной колонке и возвращаем в оба поля, так что оба сойдутся.

## Почему значения могут отличаться

1. **Время суток в датах теряется.** `disbursement_date`, `final_date`, `due_date_inicial` и дата
   платежа хранятся у нас с точностью до дня — в выгрузке время всегда `00:00:00`. Сравнивайте
   только дату.
2. **`comissions` у займов всегда `0`.** Ваш API присылает по этому полю `null` во всех записях,
   а наша модель требует числа — пустое значение приводится к нулю. По этому полю расхождение
   будет на 100% строк, и это ожидаемо.
3. **Порядок ФИО в `names` другой.** Вы присылаете «Имя Фамилия Отчество», мы храним и отдаём
   «Фамилия Имя Отчество». Отдельные поля `first_name`, `first_surname`, `second_surname` при этом
   совпадают. У платежей (`client_fullname`) порядок совпадает с вашим.
4. **Дата рождения раньше 1900 года не сохраняется.** Такие значения мы считаем испорченными на
   стороне источника и записываем как пустые. В последней сверке на проде таких займов не было.
5. **Хвост нулей в числах.** `162000.0000` может лежать у нас как `162000` или `162000.000` —
   точность зависит от поля. Сравнивайте числа как числа, а не как строки.
6. **Двойные кавычки в значениях у нас не сохраняются.** Заметнее всего на `payments_plan` — он
   возвращается без кавычек и не будет валидным JSON. Но это же касается обычного текста: если в
   адресе есть кавычки (`Микрорайон "Самал"`), в выгрузке они пропадут. В последней сверке таких
   займов 33, во всех трёх адресных полях.
7. **`restruct` пересобран, а не сохранён как есть.** Мы храним историю реструктуризаций, а не
   исходный массив: состав элементов и форматирование JSON могут отличаться, значения полей — нет.
8. **Один документ у нескольких клиентов.** У нас клиент уникален по номеру документа. Если API
   отдаст разные `client_id` с одинаковым `document`, они схлопнутся в одну карточку клиента, и у
   всех таких займов ФИО, телефон, почта, адреса и дата рождения будут от того займа, который
   загрузился последним. В последней сверке на проде такого не встретилось ни разу.
9. **Портфель живой.** Между вашей выгрузкой и нашей часть займов успевает измениться — за 25 минут
   в последней сверке сдвинулось 84 займа. Сравнивайте файлы, снятые как можно ближе по времени, а
   расхождения по `status`, `dpd` и суммам на единичных займах проверяйте по дате обновления.
