Files

5.5 KiB
Raw Permalink Blame History

title
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:

  • поле reserveJSON-строка с деталями слота (date, st, en, services, filial, timezone, schedident, rnum, dcode).

Пример упрощённой структуры тела:

{
  "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

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, backend-ddd.md.