---
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).
