Files
docs/apps/backend-scenarios/anonymous-reserve.md
T

109 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Анонимная запись на приём через MIS (Backend)
---
# Сценарий 3.1: Анонимная запись (**Anonymous Reserve**)
## Бизнес-цель
Посетитель сайта может **записаться на приём**, указав контактные данные и выбранный слот, **без обязательной регистрации** в Laravel/Next-сенсах личного кабинета: запись фиксируется в **МИС (Инфоклиника)**.
## Точки входа
| Тип | Метод + URL | Класс |
| --- | --- | --- |
| HTTP | `POST /reservation/anonymous-reserve` | `InfoclinicaController::bookingAnonymous` |
Внутренне вызывается Messenger-сообщение **`GetAnonymousReserveRequestMessage`** (транспорт `sync` по `messenger.yaml`).
## Входной контракт (DTO)
`App\Dto\AnonymousReserveRequestDto` валидирует:
- ФИО, email, телефон в формате `+7(999)999-99-99`;
- `workDate` — 8 цифр `YYYYMMDD`;
- `time` — интервал `HH:MM-HH:MM`;
- `filial`, `schedident`, `rnum`, `specialist` (dcode), `accept`, `captcha` и т.д.
Метод `toArray()` формирует тело для MIS:
- поле `reserve`**JSON-строка** с деталями слота (`date`, `st`, `en`, `services`, `filial`, `timezone`, `schedident`, `rnum`, `dcode`).
Пример упрощённой структуры тела:
```json
{
"accept": true,
"fio": "Иванов Иван",
"captcha": "...",
"email": "user@example.com",
"phone": "+7(903)123-45-67",
"reserve": "{\"date\":\"20260520\",\"st\":\"10:00\",\"en\":\"10:30\", ... }"
}
```
## Пошаговый алгоритм
1. `InfoclinicaController::bookingAnonymous` десериализует JSON в `AnonymousReserveRequestDto`, валидирует.
2. `SpecialistService::createAnonymousReserve($dto)` создаёт `GetAnonymousReserveRequestMessage` и диспатчит через `MessageBusInterface` (sync).
3. `GetAnonymousReserveRequestMessageHandler::__invoke`:
- логирует старт;
- вызывает `InfoclinicaClientService::anonymousReserve($dto)`;
- выполняет `POST` на путь **`/api/reservation/anonymous-reserve`** MIS с `json_encode($dto->toArray())`;
- возвращает массив ответа `toArray()` HTTP-клиента Symfony;
- при `HttpExceptionInterface` — лог и массив с `status_code`, телом ответа MIS.
4. Контроллер делает `$this->json($reserve, $reserve['status_code'] ?? 200)`**если в ответе есть числовой `status_code`, он подставляется как HTTP-код ответа API**.
## Создание строки `Record` в PostgreSQL
В текущем дереве `apps/backend/src` **не найдено** кода `persist(new Record(...))` или использования `RecordRepository` в связке с этим эндпоинтом. Сущность `Record` и таблица описаны в модели данных, но **локальное сохранение факта записи вместе с анонимным reserve в этом HTTP-сценарии не реализовано** (или перенесено в другой сервис).
## Mermaid
```mermaid
sequenceDiagram
participant C as Клиент
participant IC as InfoclinicaController
participant SS as SpecialistService
participant BUS as MessageBus
participant H as GetAnonymousReserveRequestMessageHandler
participant CL as InfoclinicaClientService
participant MIS as Инфоклиника API
C->>IC: POST /reservation/anonymous-reserve
IC->>SS: createAnonymousReserve(dto)
SS->>BUS: dispatch(GetAnonymousReserveRequestMessage)
BUS->>H: __invoke
H->>CL: anonymousReserve(dto)
CL->>MIS: POST /api/reservation/anonymous-reserve
MIS-->>CL: JSON
CL-->>H: массив
H-->>IC: результат
IC-->>C: HTTP код из status_code или 200
```
## Внешние зависимости
| Система | Роль |
| --- | --- |
| Инфоклиника | создание записи |
| PostgreSQL | **не задействуется** для `Record` в этом сценарии (по текущему коду) |
## Обработка ошибок и edge cases
- **`InvalidArgumentException` в контроллере** — `400` с текстом валидации.
- **Ошибки десериализации JSON в DTO** — должны обрабатываться обработчиком исключений приложения (в контроллере явного try/catch на `ExceptionInterface` нет).
- **Ответ MIS с ошибкой**: может прийти как `200` с полем `status_code` внутри JSON — клиентский код фронта должен учитывать оба уровня (HTTP и вложенный).
## Ссылки на классы
- `apps/backend/src/Controller/InfoclinicaController.php`
- `apps/backend/src/Service/Specialist/SpecialistService.php`
- `apps/backend/src/Message/GetAnonymousReserveRequestMessage.php`
- `apps/backend/src/MessageHandler/GetAnonymousReserveRequestMessageHandler.php`
- `apps/backend/src/Service/Client/InfoclinicaClientService.php`
- `apps/backend/src/Dto/AnonymousReserveRequestDto.php`
См. [sms-record.md](./sms-record.md), [backend-ddd.md](../backend-ddd.md).