---
title: SMS-уведомления и сущности Record / AlertSms (Backend)
---

# Сценарий 3.2: Уведомления (SMS), связь `Record` ↔ `AlertSms`

## Бизнес-цель

После записи к врачу пациент может получить **SMS** (напоминание, код подтверждения и т.п.). В модели данных предусмотрено локальное хранение **факта записи** (`Record`) и **ответа SMS-провайдера** (`AlertSms`) в связке один-к-одному.

## Точки входа (фактический код)

| Компонент | Назначение |
| --- | --- |
| `App\Entity\Record` | Телефон, `specialistId`, `hash`, JSON-блоб `reserve`, время создания. |
| `App\Entity\AlertSms` | Ссылка на `Record`, время, текст/ответ провайдера. |
| `Sms4bClientService`, `SmsruClientService` | Реализации `SmsClientServiceInterface` (HTTP-клиенты). |

**Поиск по дереву `apps/backend/src`:** вызовов `Sms4bClientService` / `SmsruClientService` или `RecordRepository` из контроллеров и обработчиков **не обнаружено**. То есть **интеграция SMS заложена на уровне инфраструктуры/сервисов, но не подключена к HTTP-сценарию анонимной записи** в этом репозитории на момент документирования.

## Как бы выглядел целевой flow (рекомендуемая логика)

1. После успешного ответа MIS о записи backend создаёт `Record` с телефоном и сериализованным `reserve`.
2. Асинхронно или синхронно вызывается SMS-клиент с текстом шаблона.
3. Ответ провайдера сохраняется в `AlertSms`, линкуется через `Record::setAlertSms` (Doctrine `OneToOne`).

## Mermaid (целевая схема — не полностью реализована в коде)

```mermaid
sequenceDiagram
    participant API as Backend API
    participant DB as PostgreSQL
    participant SMS as SMS шлюз (Sms4b / sms.ru)

    API->>DB: persist Record
    API->>SMS: отправить SMS
    SMS-->>API: ответ / статус
    API->>DB: persist AlertSms ↔ Record
```

## Внешние зависимости

| Система | Статус в коде |
| --- | --- |
| Sms4b / sms.ru | Классы-клиенты есть |
| PostgreSQL | Таблицы под `Record` / `AlertSms` предполагаются миграциями |

## Обработка ошибок и edge cases

- **Нет вызова SMS** — риск «тихого» пропуска уведомления; фронт не может отличить по API, если нет явного шага.
- **Повторная отправка** — нужна идемпотентность по `hash` записи (поле в `Record`) — в коде не просматривалось.

## Ссылки на классы

- `apps/backend/src/Entity/Record.php`
- `apps/backend/src/Entity/AlertSms.php`
- `apps/backend/src/Repository/RecordRepository.php`, `AlertSmsRepository.php`
- `apps/backend/src/Service/Client/Sms4bClientService.php`
- `apps/backend/src/Service/Client/SmsruClientService.php`

Модель данных: [data-model.md](../../data-model.md). Сценарий записи в MIS: [anonymous-reserve.md](./anonymous-reserve.md).
