--- title: Смена региона пользователя (Backend) --- # Сценарий 1.3: Смена региона пользователя ## Бизнес-цель Пользователь может переключать **регион** (филиал сети / географическая зона), чтобы видеть контент и услуги, релевантные выбранной территории. В API регион хранится в **`User::$regionId`** и участвует в выдаче данных на фронте. ## Точки входа | Тип | Метод + URL | Класс | | --- | --- | --- | | HTTP | `PUT /user/change-region` | `App\Controller\UserController::changeRegion` | Требуется аутентификация: `#[IsGranted('ROLE_USER')]` — клиент передаёт **JWT** в заголовке. CLI и Messenger **не используются**. ## Пошаговый алгоритм (flow) 1. Клиент отправляет JSON с полем `regionId`. 2. Данные попадают в `App\Dto\RegionDto`; Symfony Validator проверяет ограничения DTO. 3. Вызывается `App\Service\User\UserProfileService::updateRegion($dto)`: - `JWTDecoderService::getUser()` — из текущего токена извлекается **username** и по нему загружается `User` из БД; - на найденного пользователя выставляется `setRegionId($dto->regionId)`; - `EntityManager::persist` + `flush`. 4. Контроллер сериализует **тот же** `User::toArray()` и возвращает `200` с `user` и `successful: true`. ## Mermaid ```mermaid sequenceDiagram participant C as Клиент (JWT) participant UC as UserController participant V as Validator participant UPS as UserProfileService participant JWT as JWTDecoderService participant UR as UserRepository participant EM as EntityManager C->>UC: PUT /user/change-region {regionId} UC->>V: validate(RegionDto) UC->>UPS: updateRegion(dto) UPS->>JWT: getUser() JWT->>UR: find by token username UR-->>JWT: User UPS->>EM: setRegionId + flush UPS-->>UC: User UC-->>C: 200 { user, successful } ``` ## Внешние зависимости | Система | Участие | | --- | --- | | PostgreSQL | обновление строки в `users` | | JWT | идентификация текущего пользователя | ## Обработка ошибок и edge cases - **Невалидный `regionId`** — `400` с телом `errors` из Validator. - **`getUser()` вернул null** — в текущей реализации сервиса нет явной проверки; при `ROLE_USER` обычно токен уже валиден, но при рассинхроне payload/БД возможна ошибка уровня type error или `flush` — сценарий стоит учитывать при доработках. - **Справочник регионов**: этот эндпоинт **не проверяет**, существует ли `regionId` в таблице регионов — допустим любой int, прошедший валидацию DTO. ## Ссылки на классы - `apps/backend/src/Controller/UserController.php` (`changeRegion`) - `apps/backend/src/Service/User/UserProfileService.php` - `apps/backend/src/Dto/RegionDto.php` - `apps/backend/src/Service/DecoderJWT/JWTDecoderService.php` См. [login-jwt.md](./login-jwt.md) и [backend-ddd.md](../backend-ddd.md).