--- 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).