Files
docs/apps/backend-ddd.md

14 KiB
Raw Permalink Blame History

Backend: бизнес-сущности и границы (DDD-обзор)

Страница описывает apps/backend с точки зрения предметной области: какие сущности относятся к одному смысловому блоку, какие HTTP-контроллеры и сервисы их обслуживают, и как устроены фоновые задачи. Это не «каноничное» DDD-приложение с явными bounded context в коде, а карта домена поверх существующей Symfony-структуры (Entity, Repository, Controller, Service, Command, Message).

См. также: архитектура модулей, бизнес-сценарии по потокам, CRUD контента, модели данных, потоки данных.

Карта контекстов

flowchart TB
  subgraph identity[Идентичность и доступ]
    User[User]
  end

  subgraph org[Организация клиники]
    Filial[Filial]
    Department[Department]
    MedicalCenter[MedicalCenter]
  end

  subgraph staff[Врач, локации, расписание]
    Specialist[Specialist]
    Location[Location]
    Schedule[Schedule]
    Docs[SpecialistDocs]
    DcodeDesc[SpecialistDcodeDescription]
    Docinfo[WebGetDocinfo]
    Idoctor[Idoctor]
  end

  subgraph booking[Запись и уведомления]
    Record[Record]
    AlertSms[AlertSms]
    MarkKiosk[MarkKiosk]
  end

  subgraph pricing[Прайс]
    PriceList[PriceList]
    PriceDepartment[PriceDepartment]
  end

  subgraph content[Контент сайта]
    Article[Article]
    News[News]
    Promo[Promo]
    Disease[Disease]
    SiteService[SiteService]
    Stock[Stock]
  end

  subgraph reputation[Отзывы]
    Review[Review]
  end

  subgraph integrations[Интеграции и утилиты]
    Calltouch[Calltouch API]
    XmlFeed[XML фиды]
    MailCaptcha[Почта / SmartCaptcha]
  end

  Specialist --> Location
  Specialist --> Review
  Specialist --> Docs
  Specialist --> DcodeDesc
  Record --> AlertSms
  PriceList --> PriceDepartment

1. Идентичность и доступ

Смысл: учётная запись пользователя API, вход по паролю, JWT, регистрация, смена региона, сценарии с UID/pcode.

Роль в DDD Артефакт Путь / класс
Агрегат / сущность User src/Entity/User.php
Репозиторий UserRepository src/Repository/UserRepository.php
Входная точка API UserController префикс маршрута /user
Доменные сервисы AuthenticationService, RegistrationService, UserProfileService src/Service/User/
Инфраструктура JWTDecoderService, Lexik JWT src/Service/DecoderJWT/
DTO UserLoginDto, RegistrationDto, UserAuthDto, UserUidAuthDto, RegionDto src/Dto/

Консольных команд импорта для User в текущем дереве нет: пользователи создаются через API и админские сценарии.


2. Организация клиники (филиалы, отделения, медцентры)

Смысл: где оказываются услуги, структура сети, справочники для сайта и записи.

Сущность Репозиторий Контроллер (префикс) Сервисы Команды синхронизации
Filial FilialRepository FilialController/filial FilialService UploadFilialsCommand
Department DepartmentRepository DepartmentController/department DepartmentService UploadDepartmentsCommand
MedicalCenter MedicalCenterRepository MedicalCenterController/medical-center MedicalCenterCrudService UploadMedicalCentersCommand

3. Врач, локации приёма, расписание и материалы

Смысл: центральный домен — врач (Specialist), его локации (Location: отделение, филиал, online, ближайшая дата), слоты расписания (Schedule), справочные тексты и медиа.

Сущность Репозиторий Где в API Основная логика
Specialist SpecialistRepository SpecialistController/specialist SpecialistService (список, карточка, расписание, фото, запись, интеграция с MIS)
Location LocationRepository LocationController (admin) — пути вида /specialist/{id}/location/..., /locations/empty LocationService, EntityManager в контроллере
Schedule ScheduleRepository косвенно через SpecialistService, кеш ScheduleCacheService, ScheduleErrorHandlerService
SpecialistDocs SpecialistDocsRepository SpecialistDocsController/specialist-docs/... загрузка файлов, ImageService, FileUploaderService
SpecialistDcodeDescription SpecialistDcodeDescriptionRepository SpecialistDcodeDescriptionController/specialist-dcode-description/... пагинация, CRUD
WebGetDocinfo WebGetDocinfoRepository WebGetDocinfoController/docinfo чтение внешнего/legacy-представления врача
Idoctor IdoctorRepository InfoclinicaController/idoctor/list фильтрация, пагинация

Асинхронные сообщения (Messenger):

  • GetScheduleMessageGetScheduleMessageHandler
  • GetSpecialistPictureMessageGetSpecialistPictureMessageHandler
  • GetAnonymousReserveRequestMessageGetAnonymousReserveRequestMessageHandler

Команды: UploadDoctorsCommand, BitrixUpdateDoctorsCommand, ClearScheduleCacheCommand.

Внешние системы в этом контексте: Infoclinica/MIS (InfoclinicaClientService), Bitrix (BitrixClientService, BitrixService) для врачей и медиа.


4. Запись пациента, отметки киоска, SMS

Смысл: факт записи, уведомление по SMS, отметка прохождения для киоска.

Сущность Репозиторий / доступ Где используется
Record RecordRepository создание/учёт записи через SpecialistService и сценарии записи
AlertSms AlertSmsRepository связь записи с ответом SMS-провайдера (RecordAlertSms)
MarkKiosk EntityManager::getRepository(MarkKiosk::class) InfoclinicaController::clvisitsovacheckpass — отметка по pcode и филиалу

HTTP: POST /reservation/anonymous-reserve (InfoclinicaController) — анонимная запись; проверка киоска — GET /infoclinica/clvisitsovacheckpass/{filial} (требуется ROLE_USER).

SMS-клиенты: Sms4bClientService, SmsruClientService.


5. Прейскурант

Сущность Репозиторий Контроллер Сервис Команды
PriceList PriceListRepository PriceListController — префикс /pricelist, список /list PriceListService UploadPriceCommand
PriceDepartment PriceDepartmentRepository PriceDepartmentController — тот же префикс /pricelist, эндпоинт /department через репозиторий и сервисы фидов UploadPriceDepCommand

XmlFeedController использует PriceListService и филиал для генерации фидов — см. контекст интеграций.


6. Контент сайта (статьи, новости, акции, услуги, заболевания, акции у врачей)

Сущность Репозиторий Контроллер Паттерн
Article ArticleRepository ArticleController/article CrudResponder + Paginator + ContentFilterDto (описание CRUD)
News NewsRepository NewsController/news NewsCrudService + типовой CRUD
Promo PromoRepository PromoController/promo PromoCrudService
Disease DiseaseRepository DiseaseController/disease DiseaseCrudService
SiteService SiteServiceRepository SiteServiceController/site-services SiteServiceCrudService
Stock StockRepository StockController/stock/... CRUD, изображения, связь Many-to-Many с Specialist

Команды: UploadNewsCommand, UploadPromoCommand, UploadDiseasesCommand, UploadSiteServicesCommand (остальные сущности этого блока подтягиваются согласно фактическим именам команд в src/Command).


7. Отзывы

Сущность Репозиторий Контроллер Прочее
Review ReviewRepository ReviewController/review список с фильтрами, создание от авторизованного пользователя, CRUD для админа

Команда: BitrixUpdateReviewsCommand — синхронизация с Bitrix.


8. Интеграции и публичные утилиты

Назначение Контроллер / вход Сервисы
Лиды Calltouch CalltouchController/calltouch/create-lead CalltouchClientService
XML для Яндекса XmlFeedController/xml/feed XmlFeedGeneratorService, XmlFeedGeneratorV1Service, данные врачей/цен/филиалов
Отправка почты + captcha ServiceController/service/sendmail SendMailService, SmartCaptchaClientService
Мелкие helper HelperController/helper/text-year HelperService
Заглушка DefaultController GET /

9. Аудит: логи пользователей (legacy БД)

Назначение Контроллер Реализация
Список записей usrlog UsrlogController/usrlog/list DBAL-подключение doctrine.dbal.cabinet_connection, роль ROLE_LOGS

Это интеграционный контекст: сущность в apps/backend/src/Entity не выделяется, данные читаются из базы cabinet.


10. Сущности без выделенного HTTP-слоя в текущем API

Их таблицы и Doctrine-модели есть, репозитории сгенерированы, но отдельного REST-контроллера в src/Controller нет (на момент описания документа):

Сущность Репозиторий Зачем полезно знать
Banner BannerRepository баннеры; возможна выдача через другие сервисы или будущие эндпоинты
WidgetForm, WidgetFormInput WidgetFormRepository, WidgetFormInputRepository Symfony Forms WidgetFormType, WidgetFormInputType — конструктор полей, данные в БД

При появлении новых маршрутов их логично отнести к контексту «виджеты и формы» или «маркетинг».


Сводная таблица: контроллер → базовый префикс

Контроллер Префикс или примечание
ArticleController /article
CalltouchController /calltouch
DefaultController /
DepartmentController /department
DiseaseController /disease
FilialController /filial
HelperController /helper
InfoclinicaController без классового префикса: /infoclinica/..., /idoctor/..., /reservation/...
LocationController без префикса: /locations/..., /specialist/{id}/location/...
MedicalCenterController /medical-center
NewsController /news
PriceDepartmentController /pricelist
PriceListController /pricelist
PromoController /promo
ReviewController /review
ServiceController /service/...
SiteServiceController /site-services
SpecialistController /specialist
SpecialistDcodeDescriptionController /specialist-dcode-description/...
SpecialistDocsController /specialist-docs/...
StockController /stock/...
UserController /user
UsrlogController /usrlog/...
WebGetDocinfoController /docinfo
XmlFeedController /xml/feed

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

Команда (класс) Домен
UploadDoctorsCommand Врачи
BitrixUpdateDoctorsCommand Врачи (Bitrix)
BitrixUpdateReviewsCommand Отзывы
UploadDepartmentsCommand Отделения
UploadDiseasesCommand Заболевания
UploadFilialsCommand Филиалы
UploadMedicalCentersCommand Медцентры
UploadNewsCommand Новости
UploadPriceCommand Цены
UploadPriceDepCommand Группы цен
UploadPromoCommand Акции
UploadSiteServicesCommand Услуги сайта
ClearScheduleCacheCommand Расписание (кеш)

Точные имена команд Symfony: docker exec -it php84 php bin/console list app (или локальный php bin/console из apps/backend).