> ## Documentation Index
> Fetch the complete documentation index at: https://docs.yume.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Модель данных

> Все сущности сервиса автоштрафов и их связи: авто, водители, компании-нарушители, штрафы со всеми реквизитами оплаты и документами, кастомные статусы, привязки авто к компаниям, журнал синхронизации и записи об отправленных уведомлениях, включая сохранение PDF протокола в облачном хранилище.

Полный перечень полей — в [глоссарии](/ru/logic/auto-penalties/models-glossary).

## Модель данных

Модуль сервиса автоштрафов хранит данные о штрафах ПДД и обо всём, что с ними связано: об автомобилях, водителях, компаниях-нарушителях, о привязке машин к компаниям-арендодателям, о журнале синхронизации и об отправленных клиентам уведомлениях. Все справочники (авто, водители, компании, штрафы) — общие: они живут в общей части системы и наполняются данными, которые приходят из внешнего сервиса автоштрафов. А вот привязки авто, кастомные статусы и уведомления привязаны к конкретной компании.

Ключевая идея всей модели — каждая внешняя сущность сервиса автоштрафов имеет собственный **внешний ID** (уникальный идентификатор во внешнем сервисе). Именно по нему система узнаёт «тот же самый» объект при повторной синхронизации и не создаёт дубликаты.

### Автомобиль сервиса автоштрафов

Автомобиль, известный сервису автоштрафов, — именно по нему подтягиваются штрафы.

| Поле                            | Тип        | Назначение                                                           |
| ------------------------------- | ---------- | -------------------------------------------------------------------- |
| Внешний ID                      | число      | Уникальный идентификатор авто во внешнем сервисе; уникален в системе |
| Номер автомобиля                | текст      | Госномер                                                             |
| Номер техпаспорта               | текст      | Номер технического паспорта                                          |
| Дата активации                  | дата/время | Момент, с которого авто включено в синхронизацию (может быть пустым) |
| Активен                         | флаг       | Включена ли синхронизация штрафов по этому авто (по умолчанию да)    |
| Дата создания / Дата обновления | дата/время | Служебные отметки времени                                            |

<Info>
  Флаг «Активен» по умолчанию включён. Он управляет тем, тянутся ли штрафы по конкретной машине. Поле «Дата активации» хранит момент, с которого авто включено в синхронизацию, и может быть пустым.
</Info>

### Водитель сервиса автоштрафов

Водитель-нарушитель, которого сервис связывает со штрафом. Записи не дублируются — совпадение определяется по **внешнему ID**.

| Поле                      | Тип   | Назначение                                           |
| ------------------------- | ----- | ---------------------------------------------------- |
| Внешний ID                | число | Уникальный идентификатор водителя во внешнем сервисе |
| ИИН                       | текст | Индивидуальный идентификационный номер               |
| Номер удостоверения       | текст | Номер водительского удостоверения                    |
| Дата выдачи удостоверения | дата  | —                                                    |
| Имя / Фамилия / Отчество  | текст | ФИО водителя                                         |

Все поля, кроме идентификатора, могут быть пустыми — сервис не всегда присылает полный набор данных о водителе.

### Компания сервиса автоштрафов

Компания-нарушитель, то есть владелец автомобиля со стороны сервиса автоштрафов. Не путать с компанией-арендодателем внутри системы. Дедупликация — по **внешнему ID**.

| Поле              | Тип   | Назначение                                           |
| ----------------- | ----- | ---------------------------------------------------- |
| Внешний ID        | число | Уникальный идентификатор компании во внешнем сервисе |
| БИН               | текст | Бизнес-идентификационный номер                       |
| Название компании | текст | —                                                    |

### Кастомный статус штрафа

Пользовательский статус, который компания заводит для себя, чтобы вручную помечать штрафы (например «Передан клиенту», «Оспаривается», «Закрыт»).

| Поле     | Тип   | Назначение                                                         |
| -------- | ----- | ------------------------------------------------------------------ |
| Компания | связь | Компания-владелец статуса (может быть пустой — тогда статус общий) |
| Название | текст | Название статуса                                                   |
| Цвет     | текст | Цвет статуса в формате HEX, по умолчанию белый (#ffffff)           |

### Штраф

Центральная модель модуля. Хранит штраф ПДД со всеми реквизитами оплаты, документами и связями. Штрафы не дублируются — совпадение по **внешнему ID**.

**Основные данные**

| Поле                            | Тип             | Назначение                                                  |
| ------------------------------- | --------------- | ----------------------------------------------------------- |
| Внешний ID                      | число           | Уникальный идентификатор штрафа во внешнем сервисе          |
| Номер протокола                 | текст           | Номер протокола о нарушении                                 |
| Описание нарушения              | текст           | —                                                           |
| Орган, выявивший правонарушение | текст           | Название органа, зафиксировавшего нарушение                 |
| Основная мера наказания         | текст           | —                                                           |
| Сумма штрафа                    | число (2 знака) | Сумма в тенге                                               |
| Просмотрен                      | флаг            | Отметка, что штраф просмотрен оператором (по умолчанию нет) |

**Адрес и время нарушения**

| Поле            | Тип   | Назначение |
| --------------- | ----- | ---------- |
| Адрес нарушения | текст | —          |
| Дата нарушения  | дата  | —          |
| Время нарушения | время | —          |

**Статус оплаты**

| Поле                  | Тип        | Назначение                                   |
| --------------------- | ---------- | -------------------------------------------- |
| Оплачен               | флаг       | Оплачен ли штраф (по умолчанию нет)          |
| Дата оплаты           | дата/время | —                                            |
| Дата истечения скидки | дата/время | До какого момента действует скидка на оплату |

**Реквизиты оплаты**

| Поле                       | Тип   | Назначение                  |
| -------------------------- | ----- | --------------------------- |
| КНО                        | текст | Код налогового органа       |
| КБК                        | текст | Код бюджетной классификации |
| КНП                        | текст | Код назначения платежа      |
| Название налогового органа | текст | Получатель платежа          |
| IBAN налогового органа     | текст | Банковский счёт получателя  |
| БИН налогового органа      | текст | БИН получателя платежа      |

**Документы**

| Поле                     | Тип    | Назначение                                                        |
| ------------------------ | ------ | ----------------------------------------------------------------- |
| PDF протокола            | файл   | PDF, сохранённый в облачном хранилище                             |
| Ссылка на PDF протокола  | ссылка | Исходный URL PDF во внешнем сервисе, по которому файл скачивается |
| Ссылки на фото нарушения | список | Список ссылок на фотографии нарушения                             |

**Связи**

| Поле             | Тип   | Назначение                                          |
| ---------------- | ----- | --------------------------------------------------- |
| Автомобиль       | связь | Авто сервиса автоштрафов, по которому выписан штраф |
| Водитель         | связь | Водитель-нарушитель                                 |
| Компания         | связь | Компания-нарушитель (владелец авто)                 |
| Кастомный статус | связь | Ручной статус штрафа                                |

<Note>
  Все четыре связи (авто, водитель, компания, кастомный статус) необязательны. Если связанный объект будет удалён, ссылка в штрафе просто обнуляется — сам штраф при этом сохраняется.
</Note>

### Привязка авто компании к сервису автоштрафов

Связывает конкретную единицу инвентаря компании-арендодателя с автомобилем сервиса автоштрафов. Это мост между внутренним автопарком и справочником сервиса автоштрафов.

| Поле                            | Тип        | Назначение                                                   |
| ------------------------------- | ---------- | ------------------------------------------------------------ |
| Компания                        | связь      | Компания-владелец привязки                                   |
| Автомобиль сервиса автоштрафов  | связь      | Связанный автомобиль сервиса автоштрафов (может быть пустым) |
| ID единицы инвентаря            | число      | Идентификатор машины во внутреннем инвентаре компании        |
| Дата создания / Дата обновления | дата/время | Служебные отметки времени                                    |

<Info>
  Привязка уникальна по сочетанию **компания + автомобиль сервиса автоштрафов + ID единицы инвентаря**. Одну и ту же машину нельзя привязать к одному и тому же авто сервиса автоштрафов дважды внутри одной компании.
</Info>

### Уведомление о штрафе

Запись о том, что клиенту было отправлено WhatsApp-уведомление о штрафе. Служит одновременно и историей отправок, и защитой от повторов.

| Поле        | Тип   | Назначение                                                     |
| ----------- | ----- | -------------------------------------------------------------- |
| Телефон     | текст | Номер получателя                                               |
| ID клиента  | число | Идентификатор клиента-получателя                               |
| Компания    | связь | Компания, отправившая уведомление                              |
| Штраф       | связь | Штраф, о котором уведомляют                                    |
| Доп. данные | JSON  | Дополнительные данные — имя клиента, название компании и т. п. |

<Warning>
  Запись уникальна по сочетанию **телефон + штраф**. Это гарантия «одно уведомление на один штраф на один номер»: повторная попытка отправить то же уведомление на тот же номер не пройдёт из-за ограничения уникальности.
</Warning>

### Лог синхронизации

Журнал операций обмена данными с сервисом автоштрафов: выгрузка штрафов, приём уведомлений, авторизация.

| Поле                | Тип          | Назначение                                                |
| ------------------- | ------------ | --------------------------------------------------------- |
| Тип синхронизации   | список       | Выгрузка данных / Получение уведомления / Авторизация     |
| Статус              | список       | В процессе / Успешно / Ошибка (по умолчанию «В процессе») |
| Обработано записей  | число        | Сколько записей затронуто                                 |
| Создано записей     | число        | Сколько создано новых                                     |
| Обновлено записей   | число        | Сколько обновлено существующих                            |
| Сообщение об ошибке | текст        | Текст ошибки, если операция не удалась                    |
| Время выполнения    | длительность | Продолжительность операции                                |

Статус по умолчанию — «В процессе», что позволяет завести запись в начале операции и дополнить её итогами по завершении.

## Логика и побочные эффекты

### Сохранение PDF протокола в облачном хранилище

При сохранении штрафа, если у него задана ссылка на PDF протокола, система скачивает файл по этой ссылке и кладёт его в поле «PDF протокола» в облачное хранилище. Имя файла берётся из последней части ссылки (то, что идёт после последнего слэша).

Скачивание выполняется **только когда в этом есть смысл** — в одном из трёх случаев:

* ссылка на протокол появилась впервые;
* ссылка сменилась на другую;
* файла ещё нет в хранилище (например, предыдущая попытка скачивания не удалась — тогда следующее сохранение попробует снова).

<Note>
  В обычном случае (файл уже лежит, ссылка та же) внешнего обращения не происходит вовсе. Поэтому прикладные правки штрафа — отметка «просмотрен», смена кастомного статуса — файл заново не качают и не перезаписывают.
</Note>

<Note>
  Неудачная загрузка **не затирает** уже сохранённый протокол: если внешний сервис недоступен или ответил ошибкой, в поле остаётся прежний файл, а повторная попытка произойдёт при следующем сохранении, только если файла нет.
</Note>

### Автоматическая отправка WhatsApp при появлении уведомления

Создание записи «Уведомление о штрафе» само по себе запускает отправку. Как только запись впервые создаётся (не при последующих изменениях), происходит две вещи:

1. **Отправка сообщения в WhatsApp** клиенту на указанный номер — **фоновой задачей**, поставленной в очередь после того, как запись фактически сохранилась. Текст сообщения — двуязычный (казахский и русский) — содержит госномер автомобиля, дату нарушения, сумму штрафа и орган, зафиксировавший нарушение. К сообщению прикладывается PDF протокола под именем «penalty.pdf». Имя клиента и название компании подставляются из поля «Доп. данные».
2. **Создание системного уведомления** внутри платформы (веб, push и Telegram) о новом штрафе по автомобилю — с номером авто, датой нарушения и суммой.

<Note>
  Отправка в WhatsApp не задерживает сохранение записи: запрос к внешнему сервису выполняется уже после записи, в фоне. Если сервис недоступен, задача повторяется **до трёх раз с интервалом 5 минут**, а не теряется молча.
</Note>

<Note>
  Если у штрафа не заполнен связанный автомобиль, отправка не выполняется — уведомление молча пропускается, потому что в тексте сообщения госномер обязателен. Если протокол ещё не скачан, сообщение тоже не отправляется, но факт пропуска попадает в журнал предупреждением.
</Note>

<Info>
  Токен доступа к WhatsApp выбирается по режиму работы системы: в отладочном режиме используется тестовый токен, в боевом — рабочий.
</Info>

## Как это используется

* **Автомобиль сервиса автоштрафов, Водитель сервиса автоштрафов, Компания сервиса автоштрафов** — наполняются автоматически из данных внешнего сервиса при синхронизации; связываются со штрафами по внешним идентификаторам.
* **Штраф** — основной объект, который видит оператор: по нему видно нарушение, реквизиты оплаты, документы и связи. Просмотр и управление вынесены в админку.
* **Привязка авто компании к сервису автоштрафов** — определяет, какие машины компании отслеживаются в сервисе автоштрафов; через неё штраф сопоставляется с конкретной единицей инвентаря и активной арендой.
* **Уведомление о штрафе** — фиксирует факт рассылки и не даёт задвоить сообщение клиенту; создание записи и есть команда «отправить».
* **Лог синхронизации** — источник для диагностики: показывает, когда и с каким результатом проходил обмен с сервисом автоштрафов.
* **Кастомный статус штрафа** — инструмент ручной пометки штрафов внутри компании.

## Особенности поведения

* Если у штрафа не заполнен автомобиль, ни сообщение в WhatsApp, ни системное уведомление не отправляются — запись уведомления создаётся, но клиент ничего не получает.
* Протокол скачивается только при появлении или смене ссылки либо когда файла ещё нет; неудачная попытка не затирает уже сохранённый файл.
* Сообщение в WhatsApp уходит фоновой задачей и повторяется до трёх раз с интервалом 5 минут при недоступности сервиса; если протокол ещё не скачан, сообщение не отправляется, а в журнал пишется предупреждение.
* Уведомление уникально по паре «телефон + штраф», поэтому повторно отправить тот же штраф на тот же номер нельзя; но один и тот же штраф можно разослать на разные номера, создав несколько записей.
* Дата нарушения подставляется в текст системного уведомления без проверки на пустоту, поэтому штраф без даты нарушения приведёт к ошибке при отправке.
* При удалении связанного объекта ссылки штрафа на авто, водителя, компанию и кастомный статус обнуляются (сам штраф сохраняется), а привязки авто и уведомления удаляются вместе с компанией-арендодателем.

## Связанные страницы

<CardGroup cols={2}>
  <Card title="Глоссарий: Модель данных" icon="book" href="/ru/logic/auto-penalties/models-glossary">
    Полный перечень полей всех сущностей сервиса автоштрафов.
  </Card>

  <Card title="Сервис автоштрафов (штрафы и синхронизация авто)" icon="car-burst" href="/ru/logic/auto-penalties">
    Обзор модуля и навигация по всем его страницам.
  </Card>

  <Card title="Синхронизация автомобилей" icon="arrows-rotate" href="/ru/logic/auto-penalties/car-sync">
    Выгрузка списка авто, сверка активных и неактивных, удаление осиротевших машин.
  </Card>

  <Card title="API компании: авто и штрафы" icon="list-check" href="/ru/logic/auto-penalties/company-api">
    Адреса арендодателя: привязка своих машин к сервису автоштрафов и просмотр штрафов только по ним.
  </Card>

  <Card title="Уведомления о штрафах" icon="whatsapp" href="/ru/logic/auto-penalties/notifications">
    Сопоставление штрафа с арендой и отправка клиенту двуязычного WhatsApp-сообщения с PDF.
  </Card>
</CardGroup>
