diff --git a/API Документация Генерация стратегии продвижения (Frontend/Документация для фронтенда Генерация изображений для постов.md b/API Документация Генерация стратегии продвижения (Frontend/Документация для фронтенда Генерация изображений для постов.md new file mode 100644 index 0000000..e201db1 --- /dev/null +++ b/API Документация Генерация стратегии продвижения (Frontend/Документация для фронтенда Генерация изображений для постов.md @@ -0,0 +1,548 @@ +# Документация для фронтенда: Генерация изображений для постов + +## Обзор изменений + +В систему добавлена автоматическая генерация изображений для постов в социальных сетях. Теперь при создании маркетинговой стратегии для каждого поста автоматически генерируется уникальное изображение с помощью OpenAI DALL-E API. Изображения сохраняются в MinIO и прикрепляются к постам при публикации в Facebook. + +--- + +## Новые поля в API + +### 1. PostCalendarItem (Календарь постов) + +В объекте `PostCalendarItem` добавлены два новых поля для работы с изображениями: + +| Поле | Тип | Описание | Обязательное | +| --------------- | ------ | ------------------------------------------------------------ | ------------ | +| `imageUrl` | string | Имя файла изображения (используется для получения через API) | Нет | +| `imageFilename` | string | Имя файла изображения | Нет | + +**Важно:** + +- Поля могут быть `null`, если генерация изображения не удалась +- В этом случае пост публикуется без изображения +- Оба поля содержат одинаковое значение (имя файла) +- Для получения изображения используйте API эндпоинт `/api/marketing/analysis/images/{imageFilename}` + +### 2. PostingTask (Задачи публикации) + +В объекте `PostingTask` также добавлены поля для изображений: + +| Поле | Тип | Описание | Обязательное | +| --------------- | ------ | ------------------------------------------------------------ | ------------ | +| `imageUrl` | string | Имя файла изображения (используется для получения через API) | Нет | +| `imageFilename` | string | Имя файла изображения | Нет | + +--- + +## Изменения в API эндпоинтах + +### GET `/api/marketing/strategy/{strategyId}` + +Ответ теперь включает поля изображений в каждом элементе календаря постов. + +#### Пример ответа + +```json +{ + "success": true, + "data": { + "strategyId": "507f1f77bcf86cd799439011", + "analysisId": "507f1f77bcf86cd799439012", + "status": "completed", + "strategy": { + "postCalendar": [ + { + "publishDate": "2024-01-15T10:00:00", + "platform": "Facebook", + "contentType": "пост", + "theme": "Презентация нового продукта", + "postText": "Мы рады представить наш новый продукт...", + "hashtags": ["#новинка", "#продукт", "#маркетинг"], + "publishTime": "10:00", + "imageUrl": "post_image_1705312800000_1234567890.png", + "imageFilename": "post_image_1705312800000_1234567890.png" + } + ] + } + } +} +``` + +### GET `/api/marketing/analysis/{analysisId}/strategy` + +Аналогично, ответ включает поля изображений в календаре постов. + +--- + +## Получение изображений + +### Через бэкенд API + +Все изображения должны получаться через бэкенд API. Прямой доступ к MinIO с фронтенда не предусмотрен. + +#### Эндпоинт для получения изображения + +**GET** `/api/marketing/analysis/images/{imageFilename}` + +Возвращает изображение поста в формате PNG. + +#### Параметры пути + +| Параметр | Тип | Описание | +| --------------- | ------ | --------------------- | +| `imageFilename` | string | Имя файла изображения | + +#### Заголовки запроса + +| Заголовок | Тип | Обязательный | Описание | +| --------------- | ------ | ------------ | ------------------------------------ | +| `Authorization` | string | Да | JWT токен в формате `Bearer {token}` | + +#### Пример запроса + +```javascript +const imageUrl = `/api/marketing/analysis/images/${post.imageFilename}`; + +fetch(imageUrl, { + headers: { + Authorization: `Bearer ${token}` + } +}) + .then((response) => { + if (response.ok) { + return response.blob(); + } + throw new Error('Failed to load image'); + }) + .then((blob) => { + const imageObjectUrl = URL.createObjectURL(blob); + // Используйте imageObjectUrl для отображения + }); +``` + +#### Пример ответа + +- **Успешный ответ (200 OK):** + + - Content-Type: `image/png` + - Body: бинарные данные изображения PNG + +- **Ошибка 401 Unauthorized:** + + - Токен отсутствует или невалиден + +- **Ошибка 404 Not Found:** + + - Изображение не найдено на сервере + +- **Ошибка 500 Internal Server Error:** + - Внутренняя ошибка сервера при загрузке изображения + +#### Кэширование + +Сервер возвращает заголовок `Cache-Control: public, max-age=3600`, что позволяет браузеру кэшировать изображения на 1 час. + +--- + +## Рекомендации по отображению + +### 1. Проверка наличия изображения + +Всегда проверяйте наличие изображения перед отображением: + +```javascript +// Пример на JavaScript/TypeScript +const PostCard = ({ post, apiBaseUrl, authToken }) => { + const hasImage = post.imageUrl && post.imageFilename; + const imageUrl = hasImage ? `${apiBaseUrl}/api/marketing/analysis/images/${post.imageFilename}` : null; + + return ( +
+

{post.theme}

+

{post.postText}

+ + {imageUrl ? ( + {post.theme} { + // Fallback если изображение не загрузилось + e.target.style.display = 'none'; + }} + // Если требуется авторизация, используйте fetch с заголовками + /> + ) : ( +
Изображение не сгенерировано
+ )} + +
+ {post.hashtags.map((tag) => ( + #{tag} + ))} +
+
+ ); +}; +``` + +### 2. Обработка ошибок загрузки + +Всегда предусматривайте fallback для случаев, когда: + +- Изображение не сгенерировано (`imageUrl` = `null`) +- Изображение не найдено на сервере +- Ошибка при загрузке изображения + +```javascript +const [imageError, setImageError] = useState(false); + +const getImageUrl = (imageFilename) => { + if (!imageFilename) return null; + return `${API_BASE_URL}/api/marketing/analysis/images/${imageFilename}`; +}; + +const handleImageError = () => { + setImageError(true); +}; + +return ( + <> + {post.imageUrl && !imageError ? ( + {post.theme} + ) : ( +
+ + Изображение недоступно +
+ )} + +); +``` + +### 3. Оптимизация загрузки + +Рекомендуется использовать lazy loading для изображений: + +```javascript +{post.theme} +``` + +### 4. Размеры изображений + +Изображения генерируются в размере **1024x1024 пикселей** (квадратные). При отображении учитывайте это при настройке CSS: + +```css +.post-image { + width: 100%; + max-width: 512px; + height: auto; + border-radius: 8px; + object-fit: cover; +} +``` + +--- + +## Примеры использования + +### React компонент для отображения поста + +```typescript +import React, { useState } from 'react'; + +interface PostCalendarItem { + publishDate: string; + platform: string; + contentType: string; + theme: string; + postText: string; + hashtags: string[]; + publishTime: string; + imageUrl?: string | null; + imageFilename?: string | null; +} + +interface PostCardProps { + post: PostCalendarItem; + apiBaseUrl: string; +} + +const PostCard: React.FC = ({ post, apiBaseUrl }) => { + const [imageError, setImageError] = useState(false); + + const getImageUrl = (): string | null => { + if (!post.imageFilename) return null; + return `${apiBaseUrl}/api/marketing/analysis/images/${post.imageFilename}`; + }; + + const imageUrl = getImageUrl(); + + return ( +
+
+ {post.platform} + {post.contentType} + {post.publishTime} +
+ +

{post.theme}

+ + {imageUrl && !imageError ? ( +
+ {post.theme} setImageError(true)} + /> +
+ ) : ( +
+ + + +

Изображение не сгенерировано

+
+ )} + +

{post.postText}

+ +
+ {post.hashtags.map((tag, index) => ( + + {tag.startsWith('#') ? tag : `#${tag}`} + + ))} +
+ +
+ + {new Date(post.publishDate).toLocaleDateString('ru-RU')} + +
+
+ ); +}; + +export default PostCard; +``` + +### Vue компонент + +```vue + + + +``` + +--- + +## Важные замечания + +### 1. Генерация изображений + +- Изображения генерируются **автоматически** при создании стратегии +- Процесс генерации может занять время (обычно 10-30 секунд на изображение) +- Если генерация не удалась, пост все равно будет создан, но без изображения + +### 2. Хранение изображений + +- Все изображения хранятся на бэкенде +- Формат изображений: **PNG** +- Размер изображений: **1024x1024 пикселей** +- Имя файла уникально для каждого поста +- Доступ к изображениям только через API эндпоинт + +### 3. Публикация постов + +- При публикации поста в Facebook изображение автоматически прикрепляется +- Если изображение отсутствует, пост публикуется только с текстом +- Это не влияет на успешность публикации + +### 4. Обратная совместимость + +- Старые стратегии, созданные до добавления этой функции, не будут иметь изображений +- Поля `imageUrl` и `imageFilename` будут `null` для таких постов +- Фронтенд должен корректно обрабатывать `null` значения + +--- + +## Конфигурация + +Для работы с изображениями вам понадобится базовый URL вашего API: + +```typescript +// config.ts +export const API_CONFIG = { + baseUrl: 'http://your-backend-url' // URL вашего бэкенда + // Например: 'http://localhost:8080' или 'https://api.example.com' +}; +``` + +--- + +## Миграция существующего кода + +Если у вас уже есть компоненты для отображения постов, обновите их следующим образом: + +1. **Добавьте проверку наличия изображения:** + + ```typescript + const hasImage = post.imageUrl && post.imageFilename; + ``` + +2. **Добавьте отображение изображения:** + + ```jsx + { + hasImage && {post.theme}; + } + ``` + +3. **Обновите типы/интерфейсы:** + ```typescript + interface PostCalendarItem { + // ... существующие поля + imageUrl?: string | null; + imageFilename?: string | null; + } + ``` + +--- + +## Поддержка + +При возникновении проблем: + +1. Проверьте, что `imageUrl` и `imageFilename` не `null` +2. Убедитесь, что используете правильный API эндпоинт: `/api/marketing/analysis/images/{imageFilename}` +3. Проверьте, что JWT токен валиден и передается в заголовке `Authorization` +4. Проверьте консоль браузера на наличие ошибок сети или авторизации +5. Убедитесь, что используете правильный базовый URL API + +--- + +## Пример полного ответа API + +```json +{ + "success": true, + "data": { + "strategyId": "507f1f77bcf86cd799439011", + "analysisId": "507f1f77bcf86cd799439012", + "status": "completed", + "createdAt": "2024-01-15T10:00:00", + "completedAt": "2024-01-15T10:05:00", + "durationWeeks": 4, + "priorityPlatforms": ["Facebook", "Instagram"], + "strategy": { + "weeklyPlans": [ + { + "weekNumber": 1, + "mainThemes": ["Презентация продукта", "Преимущества"], + "contentRecommendations": "Создавайте контент...", + "priorityPlatforms": ["Facebook"] + } + ], + "postCalendar": [ + { + "publishDate": "2024-01-16T10:00:00", + "platform": "Facebook", + "contentType": "пост", + "theme": "Презентация нового продукта", + "postText": "Мы рады представить наш новый продукт, который поможет вам...", + "hashtags": ["#новинка", "#продукт", "#маркетинг"], + "publishTime": "10:00", + "imageUrl": "post_image_1705312800000_1234567890.png", + "imageFilename": "post_image_1705312800000_1234567890.png" + }, + { + "publishDate": "2024-01-18T14:00:00", + "platform": "Instagram", + "contentType": "сторис", + "theme": "Преимущества продукта", + "postText": "Узнайте о главных преимуществах нашего продукта...", + "hashtags": ["#преимущества", "#качество"], + "publishTime": "14:00", + "imageUrl": null, + "imageFilename": null + } + ] + } + } +} +``` + +Обратите внимание, что второй пост не имеет изображения (`imageUrl` и `imageFilename` равны `null`). Это нормальная ситуация, если генерация изображения не удалась. + +--- + +**Дата обновления:** 2024-01-15 +**Версия API:** 1.0