### **Техническое задание №2: Базовое управление кампаниями и каналами (CRUD)** **Цель:** Реализовать полную бизнес-логику и API для управления основными сущностями системы: **маркетинговыми кампаниями (`Campaign`)** и **каналами публикации (`Channel`)**. На этом этапе будет создана базовая административная функциональность, позволяющая создавать, просматривать, редактировать и удалять эти сущности через REST API. --- ## 1\. Data Transfer Objects (DTOs) Для обеспечения чистоты и безопасности API необходимо создать DTO для всех входящих и исходящих данных. ### `CampaignDto.java` Используется для возврата информации о кампании. ```java public class CampaignDto { private UUID id; private String name; private String goal; private BigDecimal budget; private ZonedDateTime startAt; private ZonedDateTime endAt; private CampaignStatus status; } ``` ### `CreateCampaignRequest.java` Используется для создания новой кампании. ```java public class CreateCampaignRequest { @NotBlank private String name; private String goal; @PositiveOrZero private BigDecimal budget; @FutureOrPresent private ZonedDateTime startAt; @Future private ZonedDateTime endAt; private CampaignStatus status = CampaignStatus.PLANNED; } ``` ### `ChannelDto.java` Используется для возврата информации о канале. ```java public class ChannelDto { private UUID id; private String name; private ChannelType type; private boolean isActive; } ``` ### `CreateChannelRequest.java` Используется для создания нового канала. ```java public class CreateChannelRequest { @NotBlank private String name; @NotNull private ChannelType type; @NotBlank private String apiKeyRef; private boolean isActive = true; } ``` --- ## 2\. Сервисный слой (Business Logic) ### `CampaignService.java` Сервис для управления кампаниями. - **Методы:** - `List getAllCampaigns()`: Возвращает список всех кампаний. - `CampaignDto getCampaignById(UUID id)`: Находит кампанию по ID. В случае отсутствия выбрасывает исключение `ResourceNotFoundException`. - `CampaignDto createCampaign(CreateCampaignRequest request)`: Создает новую кампанию на основе DTO, сохраняет в БД и возвращает `CampaignDto`. - `CampaignDto updateCampaign(UUID id, CreateCampaignRequest request)`: Обновляет существующую кампанию. - `void deleteCampaign(UUID id)`: Удаляет кампанию по ID. ### `ChannelService.java` Сервис для управления каналами. - **Методы:** - `List getAllChannels()`: Возвращает список всех каналов. - `ChannelDto getChannelById(UUID id)`: Находит канал по ID. В случае отсутствия выбрасывает исключение `ResourceNotFoundException`. - `ChannelDto createChannel(CreateChannelRequest request)`: Создает новый канал. - `ChannelDto updateChannel(UUID id, CreateChannelRequest request)`: Обновляет существующий канал. - `void deleteChannel(UUID id)`: Удаляет канал по ID. --- ## 3\. API Endpoints (REST Controllers) ### `CampaignController.java` Контроллер для управления кампаниями. - **`GET /api/smm/campaigns`** - **Описание:** Получить список всех кампаний. - **Ответ (200 OK):** `List` - **`GET /api/smm/campaigns/{id}`** - **Описание:** Получить кампанию по ID. - **Ответ (200 OK):** `CampaignDto` - **Ответ (404 Not Found):** Если кампания не найдена. - **`POST /api/smm/campaigns`** - **Описание:** Создать новую кампанию. - **Тело запроса:** `CreateCampaignRequest` - **Ответ (201 Created):** `CampaignDto` - **`PUT /api/smm/campaigns/{id}`** - **Описание:** Обновить существующую кампанию. - **Тело запроса:** `CreateCampaignRequest` - **Ответ (200 OK):** `CampaignDto` - **`DELETE /api/smm/campaigns/{id}`** - **Описание:** Удалить кампанию. - **Ответ (204 No Content):** Успешное удаление. ### `ChannelController.java` Контроллер для управления каналами. - **`GET /api/smm/channels`** - **Описание:** Получить список всех каналов. - **Ответ (200 OK):** `List` - **`POST /api/smm/channels`** - **Описание:** Создать новый канал. - **Тело запроса:** `CreateChannelRequest` - **Ответ (201 Created):** `ChannelDto` - **Прочие эндпоинты (`GET /id`, `PUT /id`, `DELETE /id`)** реализуются по аналогии с `CampaignController`. --- ## 4\. Обработка ошибок - Необходимо создать глобальный обработчик исключений (`@ControllerAdvice`) для перехвата `ResourceNotFoundException` и возврата корректного HTTP-статуса `404 Not Found` с информативным сообщением в теле ответа. - Валидация DTO (`@NotBlank`, `@NotNull` и т.д.) должна быть включена с помощью аннотации `@Valid` в методах контроллера. При ошибке валидации Spring автоматически вернет статус `400 Bad Request`. --- ## Критерии выполнения - Созданы все указанные DTO с аннотациями для валидации. - Реализованы `CampaignService` и `ChannelService` со всей CRUD-логикой. - Реализованы `CampaignController` и `ChannelController` со всеми указанными REST-эндпоинтами. - Все эндпоинты корректно работают и возвращают ожидаемые HTTP-статусы и тела ответов. - Реализована обработка ошибок для случаев, когда сущность не найдена. - Код покрыт базовыми юнит-тестами для сервисного слоя.