Files
marketing-parser/marketing-analysis-api-frontend.md
2025-11-23 18:50:59 +05:00

552 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# API Документация: Маркетинговый анализ (Frontend/AI Agent)
## Базовый URL
```
https://api.konturai.kz
```
## Обзор
API для генерации маркетингового анализа на основе данных о бизнесе. Процесс состоит из двух этапов:
1. **Запуск анализа** - создание задачи и начало асинхронной обработки
2. **Получение результатов** - проверка статуса и получение готового отчета
Анализ выполняется асинхронно и занимает примерно 5-10 минут.
---
## Эндпоинты
### 1. Запуск маркетингового анализа
**POST** `/api/marketing/analysis/start`
Создает новую задачу на генерацию маркетингового анализа и запускает асинхронную обработку.
#### Заголовки запроса
```
Content-Type: application/json
```
#### Тело запроса (JSON)
| Поле | Тип | Обязательный | Описание | Пример значения |
| ---------------- | ------ | ------------ | ------------------------------ | -------------------------------- |
| `product` | string | ✅ | Название продукта или услуги | "Веб-разработка" |
| `location` | string | ✅ | Географическая локация работы | "Алматы, Казахстан" |
| `client` | string | ✅ | Тип целевой аудитории | "B2B клиенты" |
| `differentiator` | string | ✅ | Уникальные особенности бизнеса | "Быстрая разработка за 2 недели" |
#### Валидация полей
**`product`** (string, обязательное)
- Минимальная длина: 3 символа
- Максимальная длина: 200 символов
- Разрешены: буквы, цифры, пробелы, дефисы, запятые
**`location`** (string, обязательное)
- Минимальная длина: 2 символа
- Максимальная длина: 150 символов
- Разрешены: буквы, цифры, пробелы, запятые, дефисы
**`client`** (string, обязательное)
- Допустимые значения (точно):
- `"B2B клиенты"`
- `"B2C клиенты"`
- `"Частные лица"`
- `"Корпорации"`
- `"Малый бизнес"`
**`differentiator`** (string, обязательное)
- Минимальная длина: 10 символов
- Максимальная длина: 500 символов
- Разрешены любые символы
#### Пример запроса
```json
{
"product": "Разработка мобильных приложений",
"location": "Нур-Султан, Казахстан",
"client": "B2B клиенты",
"differentiator": "Специализируемся на быстрой разработке MVP за 4 недели с использованием современных технологий"
}
```
#### Пример успешного ответа (200 OK)
```json
{
"success": true,
"message": "Анализ запущен успешно",
"data": {
"analysisId": "507f1f77bcf86cd799439011",
"status": "processing",
"estimatedCompletionTime": "2025-01-20T15:38:00",
"message": "Анализ запущен успешно. Результаты будут готовы в течение 5-10 минут."
}
}
```
#### Структура ответа
| Поле | Тип | Описание |
| ------------------------------ | ------- | --------------------------------------------------------- |
| `success` | boolean | Флаг успешности операции |
| `message` | string | Сообщение о результате операции |
| `data.analysisId` | string | Уникальный идентификатор анализа (MongoDB ObjectId) |
| `data.status` | string | Статус анализа: `"processing"` |
| `data.estimatedCompletionTime` | string | ISO 8601 дата/время ожидаемого завершения (LocalDateTime) |
| `data.message` | string | Информационное сообщение для пользователя |
#### Пример ошибки валидации (400 Bad Request)
```json
{
"success": false,
"message": "Ошибка валидации",
"error": {
"code": "VALIDATION_ERROR",
"message": "Ошибка валидации входных данных",
"details": {
"product": "Поле 'product' должно содержать от 3 до 200 символов",
"client": "Поле 'client' должно быть одним из: B2B клиенты, B2C клиенты, Частные лица, Корпорации, Малый бизнес"
}
}
}
```
---
### 2. Получение результата анализа
**GET** `/api/marketing/analysis/{analysisId}`
Возвращает статус и результаты анализа по идентификатору.
#### Параметры пути
| Параметр | Тип | Описание |
| ------------ | ------ | --------------------- |
| `analysisId` | string | Идентификатор анализа |
#### Пример запроса
```
GET /api/marketing/analysis/507f1f77bcf86cd799439011
```
#### Пример ответа (когда анализ завершен - 200 OK)
```json
{
"success": true,
"message": "Операция выполнена успешно",
"data": {
"analysisId": "507f1f77bcf86cd799439011",
"status": "completed",
"createdAt": "2025-01-20T15:30:00",
"completedAt": "2025-01-20T15:38:00",
"report": {
"summary": "Краткое резюме анализа...",
"targetAudience": {
"description": "Описание целевой аудитории...",
"channels": ["Instagram", "LinkedIn", "Telegram"]
},
"recommendations": ["Рекомендация 1", "Рекомендация 2", "Рекомендация 3"],
"strategy": {
"duration": "2 недели",
"channels": ["Instagram", "Telegram", "21MC"],
"contentTypes": ["посты", "сторис", "баннеры"]
},
"pdfUrl": "/api/marketing/analysis/507f1f77bcf86cd799439011/download"
}
}
}
```
#### Пример ответа (когда анализ еще обрабатывается - 200 OK)
```json
{
"success": true,
"message": "Операция выполнена успешно",
"data": {
"analysisId": "507f1f77bcf86cd799439011",
"status": "processing",
"createdAt": "2025-01-20T15:30:00",
"completedAt": null,
"report": null
}
}
```
#### Статусы анализа
| Статус | Описание |
| ------------ | ----------------------------- |
| `queued` | Запрос в очереди на обработку |
| `processing` | Анализ выполняется |
| `completed` | Анализ завершен успешно |
| `failed` | Анализ завершился с ошибкой |
#### Структура ответа
| Поле | Тип | Описание |
| ---------------------------------------- | ------- | ------------------------------------------------------ |
| `success` | boolean | Флаг успешности операции |
| `message` | string | Сообщение о результате операции |
| `data.analysisId` | string | Уникальный идентификатор анализа |
| `data.status` | string | Статус анализа |
| `data.createdAt` | string | ISO 8601 дата/время создания |
| `data.completedAt` | string | ISO 8601 дата/время завершения (null если не завершен) |
| `data.report` | object | Объект с результатами (null если не завершен) |
| `data.report.summary` | string | Краткое резюме анализа |
| `data.report.targetAudience` | object | Информация о целевой аудитории |
| `data.report.targetAudience.description` | string | Описание целевой аудитории |
| `data.report.targetAudience.channels` | array | Список рекомендуемых каналов |
| `data.report.recommendations` | array | Список рекомендаций (массив строк) |
| `data.report.strategy` | object | Маркетинговая стратегия |
| `data.report.strategy.duration` | string | Длительность кампании (например, "2 недели") |
| `data.report.strategy.channels` | array | Каналы коммуникации (массив строк) |
| `data.report.strategy.contentTypes` | array | Типы контента (массив строк) |
| `data.report.pdfUrl` | string | URL для скачивания PDF отчета |
#### Пример ошибки (404 Not Found)
```json
{
"success": false,
"message": "Анализ не найден",
"error": {
"code": "NOT_FOUND",
"message": "Анализ с указанным ID не найден"
}
}
```
---
### 3. Скачивание PDF отчета
**GET** `/api/marketing/analysis/{analysisId}/download`
Возвращает PDF файл с полным маркетинговым отчетом.
#### Параметры пути
| Параметр | Тип | Описание |
| ------------ | ------ | --------------------- |
| `analysisId` | string | Идентификатор анализа |
#### Пример запроса
```
GET /api/marketing/analysis/507f1f77bcf86cd799439011/download
```
#### Успешный ответ (200 OK)
- **Content-Type**: `application/pdf`
- **Content-Disposition**: `attachment; filename="marketing_analysis_507f1f77bcf86cd799439011_1234567890.pdf"`
- **Body**: Бинарные данные PDF файла
#### Ошибки
- **404 Not Found** - Анализ не найден или PDF еще не сгенерирован
- **500 Internal Server Error** - Ошибка при получении файла
---
## Обработка ошибок
### Коды ошибок
| Код | HTTP статус | Описание |
| ----------------------- | ----------- | ------------------------------- |
| `VALIDATION_ERROR` | 400 | Ошибка валидации входных данных |
| `NOT_FOUND` | 404 | Ресурс не найден |
| `INTERNAL_SERVER_ERROR` | 500 | Внутренняя ошибка сервера |
### Формат ошибки
```json
{
"success": false,
"message": "Описание ошибки",
"error": {
"code": "ERROR_CODE",
"message": "Детальное сообщение об ошибке",
"details": {
"field1": "Сообщение об ошибке для поля 1",
"field2": "Сообщение об ошибке для поля 2"
}
}
}
```
**Примечание**: Поле `details` присутствует только для ошибок валидации (`VALIDATION_ERROR`).
---
## Примеры использования
### JavaScript/TypeScript (Fetch API)
#### Запуск анализа
```javascript
async function startMarketingAnalysis(data) {
const response = await fetch(
'https://api.konturai.kz/api/marketing/analysis/start',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
product: 'Разработка мобильных приложений',
location: 'Нур-Султан, Казахстан',
client: 'B2B клиенты',
differentiator:
'Специализируемся на быстрой разработке MVP за 4 недели',
}),
}
);
const result = await response.json();
if (result.success) {
console.log('Analysis ID:', result.data.analysisId);
return result.data.analysisId;
} else {
console.error('Error:', result.error);
throw new Error(result.error.message);
}
}
```
#### Проверка статуса и получение результата
```javascript
async function getAnalysisResult(analysisId) {
const response = await fetch(
`https://api.konturai.kz/api/marketing/analysis/${analysisId}`
);
const result = await response.json();
if (result.success) {
const { status, report } = result.data;
if (status === 'completed' && report) {
console.log('Analysis completed!');
console.log('Summary:', report.summary);
console.log('Recommendations:', report.recommendations);
return report;
} else if (status === 'processing') {
console.log('Analysis is still processing...');
return null; // Повторить запрос позже
} else if (status === 'failed') {
throw new Error('Analysis failed');
}
} else {
throw new Error(result.error.message);
}
}
```
#### Полный цикл с polling
```javascript
async function waitForAnalysisCompletion(
analysisId,
maxAttempts = 60,
intervalMs = 10000
) {
for (let i = 0; i < maxAttempts; i++) {
const result = await getAnalysisResult(analysisId);
if (result) {
return result; // Анализ завершен
}
// Ждем перед следующей проверкой
await new Promise((resolve) => setTimeout(resolve, intervalMs));
}
throw new Error('Analysis timeout');
}
// Использование
async function runFullAnalysis() {
try {
// 1. Запускаем анализ
const analysisId = await startMarketingAnalysis({
product: 'Веб-разработка',
location: 'Алматы, Казахстан',
client: 'B2B клиенты',
differentiator: 'Быстрая разработка за 2 недели',
});
console.log(`Analysis started: ${analysisId}`);
// 2. Ждем завершения (проверяем каждые 10 секунд, максимум 10 минут)
const report = await waitForAnalysisCompletion(analysisId, 60, 10000);
// 3. Используем результаты
console.log('Report summary:', report.summary);
console.log('Channels:', report.targetAudience.channels);
console.log('PDF URL:', report.pdfUrl);
return report;
} catch (error) {
console.error('Error:', error);
}
}
```
#### Скачивание PDF
```javascript
async function downloadPdf(analysisId) {
const response = await fetch(
`https://api.konturai.kz/api/marketing/analysis/${analysisId}/download`
);
if (!response.ok) {
throw new Error('Failed to download PDF');
}
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `marketing_analysis_${analysisId}.pdf`;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
}
```
### Python
```python
import requests
import time
BASE_URL = "https://api.konturai.kz"
def start_analysis(product, location, client, differentiator):
response = requests.post(
f"{BASE_URL}/api/marketing/analysis/start",
json={
"product": product,
"location": location,
"client": client,
"differentiator": differentiator
}
)
response.raise_for_status()
data = response.json()
if data["success"]:
return data["data"]["analysisId"]
else:
raise Exception(data["error"]["message"])
def get_analysis_result(analysis_id):
response = requests.get(
f"{BASE_URL}/api/marketing/analysis/{analysis_id}"
)
response.raise_for_status()
return response.json()["data"]
def wait_for_completion(analysis_id, max_attempts=60, interval=10):
for _ in range(max_attempts):
result = get_analysis_result(analysis_id)
if result["status"] == "completed":
return result["report"]
elif result["status"] == "failed":
raise Exception("Analysis failed")
time.sleep(interval)
raise Exception("Analysis timeout")
# Использование
analysis_id = start_analysis(
product="Разработка мобильных приложений",
location="Нур-Султан, Казахстан",
client="B2B клиенты",
differentiator="Быстрая разработка MVP за 4 недели"
)
print(f"Analysis started: {analysis_id}")
report = wait_for_completion(analysis_id)
print(f"Summary: {report['summary']}")
print(f"Channels: {report['targetAudience']['channels']}")
```
---
## Рекомендации по интеграции
### 1. Polling стратегия
Рекомендуется проверять статус анализа каждые 10-15 секунд. Максимальное время ожидания - 10-15 минут.
### 2. Обработка ошибок
Всегда проверяйте поле `success` в ответе и обрабатывайте ошибки соответствующим образом.
### 3. Валидация на клиенте
Перед отправкой запроса рекомендуется валидировать данные на клиенте:
- Проверка длины полей
- Проверка допустимых значений для `client`
- Проверка обязательных полей
### 4. UX рекомендации
- Показывайте индикатор загрузки во время обработки
- Отображайте примерное время завершения
- Предоставьте возможность отменить ожидание и проверить результат позже
- Сохраняйте `analysisId` для последующей проверки статуса
### 5. Кэширование
После получения результатов можно кэшировать их локально, используя `analysisId` как ключ.
---
## Примечания
1. **Формат даты**: Все даты возвращаются в формате ISO 8601 без timezone (LocalDateTime)
2. **Идентификаторы**: Используются MongoDB ObjectId (24 символа hex)
3. **Асинхронность**: Анализ выполняется асинхронно, не блокируя запрос
4. **Таймауты**: Рекомендуется устанавливать таймаут на запросы (минимум 30 секунд для запуска анализа)
5. **Rate Limiting**: В будущем может быть добавлено ограничение на количество запросов
---
## Поддержка
При возникновении проблем с API обращайтесь в техническую поддержку с указанием:
- `analysisId` (если есть)
- Время запроса
- Описание проблемы
- Код ошибки (если есть)