69 lines
3.9 KiB
Markdown
69 lines
3.9 KiB
Markdown
---
|
||
title: Генерация XML-фида для Яндекса (Backend)
|
||
---
|
||
|
||
# Сценарий 4.3: XML-фиды (Яндекс)
|
||
|
||
## Бизнес-цель
|
||
|
||
Сгенерировать **YML/XML фид** для рекламных / информационных площадок (исторически Яндекс): в фид попадают **врачи**, **клиники/услуги**, **цены**, тексты и URL с UTM-метками.
|
||
|
||
## Точки входа
|
||
|
||
| Тип | Метод + URL | Класс |
|
||
| --- | --- | --- |
|
||
| HTTP | `GET /xml/feed` | `XmlFeedController::generateFeed` |
|
||
| HTTP | `GET /xml/feed/v1` | `XmlFeedController::generateFeedV1` — выбор филиалов по `filials` (csv `fid`) или по `regionId` |
|
||
|
||
Для `/xml/feed`: query-параметр `filial` — числовой `fid`; поддерживаются UTM-поля.
|
||
|
||
## Пошаговый алгоритм (`generateFeed`)
|
||
|
||
1. `FilialRepository::findOneBy(['fid' => filialId])` — если филиал **не найден**, контроллер возвращает **пустой `Response` (HTTP 200 без тела)** — в коде нет явного статуса ошибки.
|
||
2. Собираются UTM-параметры в массив (utm_source, utm_medium, utm_campaign, ...).
|
||
3. `XmlFeedGeneratorService::generateFeed($filial, $utmParams)` строит `DOMDocument`:
|
||
- `addShopInfo` — метаданные магазина/сети;
|
||
- `addDoctors` — врачи филиала (`SpecialistService::getList` с фильтром `active=true`, `filial=fid`);
|
||
- `addClinics`, `addServices`, `addOffers` — прайс и структура услуг через `PriceListService`, отделения через `DepartmentService`, локации через `LocationService`, филиалы через `FilialService`, тексты dcode через `SpecialistDcodeDescriptionRepository`.
|
||
4. Контроллер возвращает `Response` с `Content-Type: application/xml` и телом `saveXML()`.
|
||
|
||
Версия **V1** использует `XmlFeedGeneratorV1Service` — та же идея, другой шаблон дерева XML (см. класс).
|
||
|
||
## Mermaid
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
C[GET /xml/feed?filial=...] --> F{Филиал найден?}
|
||
F -->|нет| E404[Пустой Response 200]
|
||
F -->|да| X[XmlFeedGeneratorService.generateFeed]
|
||
X --> D[SpecialistService.getList]
|
||
X --> P[PriceListService.getList]
|
||
X --> L[LocationService / DepartmentService]
|
||
X --> DOM[DOMDocument saveXML]
|
||
DOM --> R[Response XML]
|
||
```
|
||
|
||
## Внешние зависимости
|
||
|
||
| Система | Роль |
|
||
| --- | --- |
|
||
| PostgreSQL | все справочники и врачи |
|
||
| Инфоклиника / Bitrix | **не вызываются** при генерации |
|
||
| Redis | **не используется** |
|
||
|
||
## Обработка ошибок и edge cases
|
||
|
||
- **Пустой/неверный `filial`** — пустой ответ `200` без XML (так задумано в текущем контроллере).
|
||
- **Большой XML** — генерация синхронна; долгие запросы на проде стоит кешировать на уровне nginx/CDN или вынести в задачу.
|
||
- **Пустые списки врачей/цен** — фид всё равно строится, но может не пройти требования площадки — нужна валидация бизнес-правил.
|
||
|
||
## Ссылки на классы
|
||
|
||
- `apps/backend/src/Controller/XmlFeedController.php`
|
||
- `apps/backend/src/Service/XmlFeedGenerator/XmlFeedGeneratorService.php`
|
||
- `apps/backend/src/Service/XmlFeedGenerator/XmlFeedGeneratorV1Service.php`
|
||
- `apps/backend/src/Service/Specialist/SpecialistService.php`
|
||
- `apps/backend/src/Service/PriceList/PriceListService.php`
|
||
|
||
См. [backend-architecture.md](../backend-architecture.md) и [backend-ddd.md](../backend-ddd.md).
|