# API Документация: Управление задачами публикации (Frontend/AI Agent)

## Базовый URL

```
https://api.konturai.kz
```

## Обзор

API для управления задачами публикации постов в социальных сетях. Позволяет запускать задачи публикации вручную, не дожидаясь времени выполнения через шедулер.

**Важно**:

- Для выполнения задачи требуются настроенные credentials для соответствующей платформы
- Задачи создаются автоматически при запуске стратегии через `/api/marketing/analysis/strategy/{strategyId}/start`
- Каждая задача связана с элементом календаря постов в стратегии

---

## Изменения в существующих эндпоинтах

### Обновление: Получение стратегии по ID анализа

**GET** `/api/marketing/analysis/{analysisId}/strategy`

Теперь каждый элемент в `postCalendar` содержит поле `taskId`, если задача была создана для этого элемента.

#### Пример ответа (обновленный формат)

```json
{
  "success": true,
  "data": {
    "strategyId": "507f1f77bcf86cd799439012",
    "analysisId": "507f1f77bcf86cd799439011",
    "status": "completed",
    "strategy": {
      "postCalendar": [
        {
          "publishDate": "2025-01-25T10:00:00",
          "platform": "Facebook",
          "contentType": "пост",
          "theme": "Презентация продукта",
          "postText": "Добро пожаловать в наш новый продукт!",
          "hashtags": ["#маркетинг", "#бизнес"],
          "publishTime": "10:00",
          "imageUrl": "post_image_1234567890.png",
          "imageFilename": "post_image_1234567890.png",
          "taskId": "507f1f77bcf86cd799439013"
        }
      ]
    }
  }
}
```

**Новое поле:**

- `taskId` (string, опциональное) - ID задачи публикации, если задача была создана. Может быть `null`, если стратегия еще не была запущена.

---

## Новые эндпоинты

### 1. Ручной запуск задачи публикации

**POST** `/api/marketing/analysis/tasks/{taskId}/execute`

Запускает задачу публикации немедленно, не дожидаясь времени публикации через шедулер. Позволяет выполнить задачу вручную или повторить выполнение неудачной задачи.

#### Параметры запроса

| Параметр | Тип    | Расположение | Обязательный | Описание             |
| -------- | ------ | ------------ | ------------ | -------------------- |
| `taskId` | string | Path         | ✅           | ID задачи публикации |

#### Заголовки запроса

```
Authorization: Bearer <your-jwt-token>
Content-Type: application/json
```

#### Пример запроса

```http
POST /api/marketing/analysis/tasks/507f1f77bcf86cd799439013/execute
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
```

#### Пример успешного ответа (200 OK)

```json
{
  "success": true,
  "message": "Задача успешно запущена",
  "data": {
    "taskId": "507f1f77bcf86cd799439013",
    "status": "processing",
    "platform": "Facebook",
    "publishDate": "2025-01-25T10:00:00"
  }
}
```

#### Описание полей ответа

| Поле          | Тип    | Описание                                              |
| ------------- | ------ | ----------------------------------------------------- |
| `taskId`      | string | ID задачи публикации                                  |
| `status`      | string | Статус задачи: `processing`, `completed` или `failed` |
| `platform`    | string | Платформа для публикации (например, `Facebook`)       |
| `publishDate` | string | Дата и время публикации в формате ISO 8601            |

#### Ошибки

**401 Unauthorized** - Требуется аутентификация

```json
{
  "success": false,
  "message": "Не авторизован",
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Требуется аутентификация. Пожалуйста, предоставьте валидный JWT токен."
  }
}
```

**403 Forbidden** - Пользователь не является владельцем задачи

```json
{
  "success": false,
  "message": "Доступ запрещен",
  "error": {
    "code": "FORBIDDEN",
    "message": "У вас нет доступа к этой задаче"
  }
}
```

**404 Not Found** - Задача не найдена

```json
{
  "success": false,
  "message": "Задача не найдена",
  "error": {
    "code": "NOT_FOUND",
    "message": "Задача с указанным ID не найдена"
  }
}
```

**400 Bad Request** - Задача не может быть запущена

```json
{
  "success": false,
  "message": "Задача не может быть запущена",
  "error": {
    "code": "INVALID_STATUS",
    "message": "Task cannot be executed manually. Current status: completed. Only tasks with status 'pending' or 'failed' can be executed manually."
  }
}
```

#### Правила выполнения

1. **Статусы задач:**

   - `pending` - задача ожидает выполнения (может быть запущена вручную)
   - `failed` - задача завершилась с ошибкой (может быть запущена повторно вручную)
   - `processing` - задача выполняется (не может быть запущена повторно)
   - `completed` - задача успешно выполнена (не может быть запущена повторно)

2. **Повторное выполнение:**

   - Задачи со статусом `failed` автоматически сбрасываются на `pending` перед повторным выполнением
   - Ошибка из предыдущего выполнения очищается

3. **Асинхронное выполнение:**
   - Задача запускается асинхронно
   - Ответ возвращается сразу после начала выполнения
   - Для проверки статуса задачи используйте соответствующие эндпоинты (если доступны)

#### Примеры использования

**Пример 1: Запуск задачи, которая еще не была выполнена**

```javascript
// Получаем стратегию
const strategyResponse = await fetch(
  `/api/marketing/analysis/${analysisId}/strategy`,
  {
    headers: {
      Authorization: `Bearer ${token}`,
    },
  }
);

const strategy = await strategyResponse.json();
const taskId = strategy.data.strategy.postCalendar[0].taskId;

// Запускаем задачу вручную
const executeResponse = await fetch(
  `/api/marketing/analysis/tasks/${taskId}/execute`,
  {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${token}`,
      'Content-Type': 'application/json',
    },
  }
);

const result = await executeResponse.json();
console.log('Задача запущена:', result.data);
```

**Пример 2: Повторное выполнение неудачной задачи**

```javascript
// Если задача завершилась с ошибкой (status: "failed")
// можно повторить её выполнение
const retryResponse = await fetch(
  `/api/marketing/analysis/tasks/${failedTaskId}/execute`,
  {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${token}`,
      'Content-Type': 'application/json',
    },
  }
);

const retryResult = await retryResponse.json();
if (retryResult.success) {
  console.log('Повторная попытка запущена:', retryResult.data);
}
```

---

## Интеграция с существующим workflow

### Типичный сценарий использования

1. **Создание анализа** → `POST /api/marketing/analysis/start`
2. **Генерация стратегии** → `POST /api/marketing/analysis/strategy/generate`
3. **Получение стратегии** → `GET /api/marketing/analysis/{analysisId}/strategy`
   - Теперь содержит `taskId` для каждого элемента календаря
4. **Запуск стратегии** → `POST /api/marketing/analysis/strategy/{strategyId}/start`
   - Создает задачи публикации для всех элементов календаря
5. **Ручной запуск задачи** (опционально) → `POST /api/marketing/analysis/tasks/{taskId}/execute`
   - Запускает задачу немедленно, не дожидаясь времени публикации

### Когда использовать ручной запуск

- **Тестирование**: Проверить публикацию поста перед запланированным временем
- **Повторная попытка**: Повторить выполнение задачи, которая завершилась с ошибкой
- **Срочная публикация**: Опубликовать пост раньше запланированного времени
- **Отладка**: Проверить работу системы публикации

---

## Примечания

1. **Аутентификация**: Все эндпоинты требуют валидный JWT токен в заголовке `Authorization`
2. **Права доступа**: Пользователь может запускать только свои собственные задачи
3. **Статусы задач**: Проверяйте статус задачи перед попыткой ручного запуска
4. **Асинхронность**: Выполнение задачи происходит асинхронно, ответ возвращается сразу
5. **Ошибки выполнения**: Если задача завершится с ошибкой, её можно запустить повторно

---

## Версия API

- **Версия документа**: 1.0
- **Дата обновления**: 2025-01-20
- **Изменения**:
  - Добавлен эндпоинт для ручного запуска задач публикации
  - Добавлено поле `taskId` в элементы календаря постов при получении стратегии
