# Backend: архитектура модулей

`apps/backend` - новый API-слой и единое хранилище данных на Symfony 7.3. Приложение обслуживается контейнером `php84`, nginx направляет домен `api.sovamed.ru` в `apps/backend/public/index.php`.

## Слои

```mermaid
flowchart TB
  controllers[Controller\n25 классов]
  dto[Dto\n12 классов]
  services[Service\n50 классов]
  repositories[Repository\n26 классов]
  entities[Entity\n26 классов]
  commands[Command\n13 классов]
  messages[Message / Handler\n3 async-сценария]
  external[Внешние системы\nBitrix, Infoclinica, SMS, Calltouch, SmartCaptcha]
  db[(PostgreSQL)]
  mysql[(Bitrix MySQL)]
  cabinet[(Cabinet PostgreSQL)]
  redis[(Redis)]

  controllers --> dto
  controllers --> services
  services --> repositories
  repositories --> entities
  repositories --> db
  services --> external
  services --> redis
  commands --> services
  messages --> services
  services --> mysql
  services --> cabinet
```

## Контроллеры и зоны ответственности

### Пользователь и авторизация

- `UserController` - `/user`: логин, logout, текущий пользователь, смена региона, регистрация/авторизация по UID или pcode.
- Использует `AuthenticationService`, `RegistrationService`, `UserProfileService`, `JWTDecoderService`.
- Авторизация stateless через JWT (`lexik/jwt-authentication-bundle`), пользователь ищется по `User.email`.

```mermaid
sequenceDiagram
  participant Client
  participant UserController
  participant Validator
  participant Auth as AuthenticationService
  participant JWT as JWTTokenManager
  participant DB as UserRepository

  Client->>UserController: POST /user/login
  UserController->>Validator: UserLoginDto
  UserController->>Auth: jsonAuth(dto)
  Auth->>DB: поиск User по email
  DB-->>Auth: User
  Auth-->>UserController: user + isPasswordValid
  UserController->>JWT: create(user)
  UserController-->>Client: token + user
```

### Справочники и CMS-контент

- `ArticleController` - статьи.
- `DiseaseController` - заболевания.
- `MedicalCenterController` - медицинские центры.
- `NewsController` - новости.
- `PromoController` - акции.
- `SiteServiceController` - услуги сайта.
- `StockController` - акции/предложения с привязкой к врачам.

Типовой CRUD-поток:

```mermaid
flowchart LR
  request[HTTP request] --> controller[CRUD Controller]
  controller --> crud[Crud Service\ncreate/update/delete/sync]
  crud --> repository[Repository]
  repository --> entity[Entity]
  entity --> db[(PostgreSQL)]
```

### Врачи, филиалы, расписание и цены

- `SpecialistController` - врачи, карточка врача, фильтрация, фото, расписание, запись.
- `DepartmentController` - отделения.
- `FilialController` - филиалы, поиск по региону, фото.
- `LocationController` - локации врача: отделение, филиал, online mode, ближайшая дата.
- `PriceListController` и `PriceDepartmentController` - цены и группы цен.
- `SpecialistDocsController` - документы/сертификаты врача.
- `SpecialistDcodeDescriptionController` - описания врача по `dcode`.
- `WebGetDocinfoController` - данные врачей из внешнего представления/источника.

Ключевая логика находится в:

- `SpecialistService` - список, карточка, расписание, создание анонимной записи, загрузка фото.
- `ScheduleCacheService` - кеш расписания.
- `ScheduleErrorHandlerService` - нормализация ошибок расписания.
- `PriceListService`, `DepartmentService`, `FilialService`, `LocationService` - чтение справочников.

### Интеграции и служебные endpoints

- `InfoclinicaController` - прокси/интеграция с MIS: расписание, врачи, anonymous reserve.
- `CalltouchController` - создание лида.
- `ServiceController` - отправка email и SmartCaptcha.
- `XmlFeedController` - XML-фиды для Яндекса.
- `HelperController` - вспомогательные методы, например склонение лет.
- `UsrlogController` - список пользовательских логов.

## Сервисы

### HTTP-клиенты

- `AbstractHttpClientService` - общая обертка над HTTP-клиентом, cookies, request.
- `InfoclinicaClientService` - расписание, филиалы, регистрация, anonymous reserve.
- `BitrixClientService` - получение изображения специалиста.
- `CalltouchClientService` - создание заявки.
- `SmartCaptchaClientService` - проверка captcha.
- `Sms4bClientService`, `SmsruClientService` - отправка SMS, отправители, баланс.

### Доменная логика

- `SpecialistService` - врач как центральный доменный объект: расписание, карточка, список, фото, запись.
- `RegistrationService` и `AuthenticationService` - создание пользователя и проверка авторизации.
- `UserProfileService` - изменение профиля пользователя.
- `DiseaseCrudService`, `MedicalCenterCrudService`, `NewsCrudService`, `PromoCrudService`, `SiteServiceCrudService` - CRUD и синхронизация контента из внешних представлений.
- `SequenceService` - синхронизация PostgreSQL sequence после импортов.
- `FileUploaderService`, `ImageService` - файлы и изображения.
- `XmlFeedGeneratorService`, `XmlFeedGeneratorV1Service` - генерация XML-фидов.

### Инфраструктурные сервисы

- `AESCryptService` - шифрование/дешифрование AES.
- `JWTDecoderService` - получение текущего пользователя из JWT.
- `TransliteService` - транслитерация.
- `PerformanceTrackerService` - замер длительности операций.
- `SendMailService`, `SendMailConfig` - отправка почты.

## Консольные команды

```mermaid
flowchart TB
  cron[Cron / ручной запуск] --> command[Symfony Command]
  command --> bitrix[BitrixService]
  command --> crud[Crud/Domain Service]
  command --> repo[Repository]
  repo --> db[(PostgreSQL)]
```

Команды в `src/Command` синхронизируют врачей, отзывы, отделения, заболевания, филиалы, медцентры, новости, цены, акции и услуги. Отдельная команда `ClearScheduleCacheCommand` чистит кеш расписания.

## Асинхронные сообщения

- `GetScheduleMessage` / `GetScheduleMessageHandler` - получение расписания.
- `GetSpecialistPictureMessage` / handler - загрузка изображения специалиста.
- `GetAnonymousReserveRequestMessage` / handler - обработка анонимной записи.

## Главные доменные сущности

- `Specialist` - врач: имя, фото, активность, регион, alias, должность, опыт, расписание, связи с `Location`, `Review`, `SpecialistDocs`, `Stock`.
- `Location` - привязка врача к отделению/филиалу и режиму приема.
- `Schedule` - слот расписания: `dcode`, отделение, филиал, дата, кабинет, интервал, цена, свободность.
- `User` - пользователь API: UID, email, роли, регион, пароль, дата рождения, время входа.
- `Record` - запись пациента: врач, телефон, дата создания, hash, payload `reserve`.
- `PriceList` и `PriceDepartment` - цены и группы цен.
- `Filial`, `Department`, `MedicalCenter` - организационная структура.
- `Article`, `News`, `Promo`, `Disease`, `SiteService`, `Stock` - контент сайта.

Полная ER-схема вынесена на страницу [Модели данных](../data-model.md).

Детальная карта **ограниченных контекстов, сущностей, контроллеров и команд** — на странице [Backend: DDD / бизнес-сущности](./backend-ddd.md).

Пошаговые **бизнес-сценарии** (JWT, расписание, запись, синхронизация, фиды): [Backend: бизнес-сценарии](./backend-scenarios/index.md).
