14 KiB
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):
GetScheduleMessage→GetScheduleMessageHandlerGetSpecialistPictureMessage→GetSpecialistPictureMessageHandlerGetAnonymousReserveRequestMessage→GetAnonymousReserveRequestMessageHandler
Команды: UploadDoctorsCommand, BitrixUpdateDoctorsCommand, ClearScheduleCacheCommand.
Внешние системы в этом контексте: Infoclinica/MIS (InfoclinicaClientService), Bitrix (BitrixClientService, BitrixService) для врачей и медиа.
4. Запись пациента, отметки киоска, SMS
Смысл: факт записи, уведомление по SMS, отметка прохождения для киоска.
| Сущность | Репозиторий / доступ | Где используется |
|---|---|---|
Record |
RecordRepository |
создание/учёт записи через SpecialistService и сценарии записи |
AlertSms |
AlertSmsRepository |
связь записи с ответом SMS-провайдера (Record ↔ AlertSms) |
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).