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

## Обзор изменений

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

---

## Изменения в структуре запроса

### Удаленные поля (больше не используются)

Следующие поля были **удалены** из API и больше не принимаются:

- ❌ `location` - заменено на `region`
- ❌ `client` - заменено на `targetAudience`
- ❌ `differentiator` - заменено на комбинацию `businessNiche`, `strongSide`, `weakSide`

### Новые обязательные поля

| Поле             | Тип    | Обязательный | Описание                               | Пример значения                                        |
| ---------------- | ------ | ------------ | -------------------------------------- | ------------------------------------------------------ |
| `businessNiche`  | string | ✅           | Ниша бизнеса                           | "E-commerce платформы"                                 |
| `product`        | string | ✅           | Продукт или услуга                     | "Разработка мобильных приложений"                      |
| `targetAudience` | string | ✅           | Целевая аудитория (детальное описание) | "Малый и средний бизнес, владельцы интернет-магазинов" |
| `region`         | string | ✅           | Регион (город Казахстана)              | "Алматы"                                               |
| `goal`           | string | ✅           | Цель на 6-12 месяцев                   | "Увеличить количество клиентов на 50%"                 |
| `detailLevel`    | string | ✅           | Уровень детализации анализа            | "СТАНДАРТНО"                                           |
| `analysisType`   | string | ✅           | Тип анализа                            | "РЫНОК"                                                |

### Новые опциональные поля

| Поле         | Тип    | Обязательный | Описание                | Пример значения                                   |
| ------------ | ------ | ------------ | ----------------------- | ------------------------------------------------- |
| `strongSide` | string | ❌           | Сильная сторона бизнеса | "Опытная команда разработчиков, быстрая доставка" |
| `weakSide`   | string | ❌           | Слабая сторона бизнеса  | "Ограниченный маркетинговый бюджет"               |

---

## Детальное описание полей

### 1. `businessNiche` (обязательное)

**Описание**: Ниша бизнеса, в которой работает компания.

**Валидация**:

- Минимальная длина: 3 символа
- Максимальная длина: 200 символов
- Разрешены: буквы, цифры, пробелы, дефисы, запятые
- Паттерн: `^[\p{L}\p{N}\s\-,]+$`

**Примеры**:

```json
"businessNiche": "E-commerce платформы"
"businessNiche": "Образовательные технологии"
"businessNiche": "Финансовые услуги для малого бизнеса"
```

---

### 2. `product` (обязательное)

**Описание**: Конкретный продукт или услуга, которую предоставляет компания.

**Валидация**:

- Минимальная длина: 3 символа
- Максимальная длина: 200 символов
- Разрешены: буквы, цифры, пробелы, дефисы, запятые
- Паттерн: `^[\p{L}\p{N}\s\-,]+$`

**Примеры**:

```json
"product": "Разработка мобильных приложений"
"product": "Консультации по маркетингу"
"product": "Веб-разработка и дизайн"
```

---

### 3. `targetAudience` (обязательное)

**Описание**: Детальное описание целевой аудитории. Это поле заменяет старое поле `client` и должно содержать более подробную информацию.

**Валидация**:

- Минимальная длина: 3 символа
- Максимальная длина: 300 символов
- Разрешены любые символы

**Примеры**:

```json
"targetAudience": "Малый и средний бизнес, владельцы интернет-магазинов в возрасте 30-50 лет"
"targetAudience": "Стартапы и технологические компании, нуждающиеся в быстрой разработке MVP"
"targetAudience": "Частные лица, желающие создать личный бренд в социальных сетях"
```

**Примечание**: В отличие от старого поля `client`, которое принимало только фиксированные значения, `targetAudience` принимает свободный текст для более гибкого описания.

---

### 4. `region` (обязательное)

**Описание**: Регион (город Казахстана), в котором работает бизнес. Это поле заменяет старое поле `location`.

**Валидация**:

- Должно быть одним из допустимых городов Казахстана
- Проверка выполняется через валидатор `@ValidRegion`

**Допустимые значения** (точное совпадение):

- `"Алматы"`
- `"Астана"`
- `"Шымкент"`
- `"Караганда"`
- `"Актобе"`
- `"Тараз"`
- `"Павлодар"`
- `"Усть-Каменогорск"`
- `"Семей"`
- `"Костанай"`
- `"Кызылорда"`
- `"Уральск"`
- `"Петропавловск"`
- `"Атырау"`
- `"Актау"`
- `"Туркестан"`
- `"Кокшетау"`
- `"Талдыкорган"`
- `"Экибастуз"`
- `"Рудный"`

**Примеры**:

```json
"region": "Алматы"
"region": "Астана"
"region": "Шымкент"
```

**Важно**: Значение должно точно совпадать с одним из допустимых городов (регистр важен).

---

### 5. `goal` (обязательное)

**Описание**: Цель бизнеса на период 6-12 месяцев. Это новое поле, которое помогает AI лучше понять приоритеты бизнеса.

**Валидация**:

- Минимальная длина: 10 символов
- Максимальная длина: 500 символов
- Разрешены любые символы

**Примеры**:

```json
"goal": "Увеличить количество клиентов на 50% за следующие 6 месяцев"
"goal": "Выйти на рынок соседних регионов и открыть 3 новых филиала"
"goal": "Повысить узнаваемость бренда и увеличить продажи через онлайн-каналы на 30%"
```

---

### 6. `detailLevel` (обязательное)

**Описание**: Уровень детализации анализа. Влияет на объем и глубину генерируемого анализа.

**Валидация**:

- Должно быть одним из допустимых значений
- Проверка выполняется через валидатор `@ValidDetailLevel`

**Допустимые значения** (точное совпадение, регистр важен):

- `"КРАТКО"` - Краткий анализ (1-2 абзаца)
- `"СТАНДАРТНО"` - Стандартный анализ (3-5 абзацев) - **рекомендуется по умолчанию**
- `"ПОДРОБНО"` - Подробный анализ (5-8 абзацев)

**Влияние на анализ**:

| Уровень      | Длина ответов | Количество рекомендаций | Детализация стратегии    |
| ------------ | ------------- | ----------------------- | ------------------------ |
| `КРАТКО`     | 1-2 абзаца    | 3-4 рекомендации        | Краткая                  |
| `СТАНДАРТНО` | 3-5 абзацев   | 4-6 рекомендаций        | Стандартная              |
| `ПОДРОБНО`   | 5-8 абзацев   | 6-8 рекомендаций        | Детальная с обоснованием |

**Примеры**:

```json
"detailLevel": "КРАТКО"
"detailLevel": "СТАНДАРТНО"
"detailLevel": "ПОДРОБНО"
```

---

### 7. `strongSide` (опциональное)

**Описание**: Сильная сторона бизнеса. Помогает AI лучше понять конкурентные преимущества.

**Валидация**:

- Максимальная длина: 500 символов
- Разрешены любые символы
- Может быть пустым или отсутствовать

**Примеры**:

```json
"strongSide": "Опытная команда разработчиков с 10+ летним опытом, быстрая доставка проектов"
"strongSide": "Уникальная технология, низкие цены, отличная поддержка клиентов"
```

**Примечание**: Если поле не указано, AI будет анализировать сильные стороны на основе других данных.

---

### 8. `weakSide` (опциональное)

**Описание**: Слабая сторона бизнеса. Помогает AI лучше понять области для улучшения.

**Валидация**:

- Максимальная длина: 500 символов
- Разрешены любые символы
- Может быть пустым или отсутствовать

**Примеры**:

```json
"weakSide": "Ограниченный маркетинговый бюджет, недостаточная узнаваемость бренда"
"weakSide": "Небольшая команда, ограниченные ресурсы для масштабирования"
```

**Примечание**: Если поле не указано, AI будет анализировать слабые стороны на основе других данных.

---

### 9. `analysisType` (обязательное)

**Описание**: Тип анализа, который необходимо провести. Поле осталось без изменений.

**Допустимые значения**:

- `"РЫНОК"` - Анализ рынка
- `"КОНКУРЕНТЫ"` - Анализ конкурентов
- `"ЦА"` - Анализ целевой аудитории
- `"КАНАЛЫ"` - Анализ маркетинговых каналов
- `"SWOT"` - SWOT-анализ

---

## Полный пример запроса

### POST `/api/marketing/analysis/start`

```json
{
  "businessNiche": "E-commerce платформы",
  "product": "Разработка мобильных приложений для интернет-магазинов",
  "targetAudience": "Малый и средний бизнес, владельцы интернет-магазинов в возрасте 30-50 лет, нуждающиеся в мобильных решениях",
  "region": "Алматы",
  "goal": "Увеличить количество клиентов на 50% за следующие 6 месяцев и выйти на рынок соседних регионов",
  "detailLevel": "СТАНДАРТНО",
  "strongSide": "Опытная команда разработчиков с 10+ летним опытом, быстрая доставка проектов, использование современных технологий",
  "weakSide": "Ограниченный маркетинговый бюджет, недостаточная узнаваемость бренда в новых регионах",
  "analysisType": "РЫНОК"
}
```

---

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

### JavaScript/TypeScript

```typescript
interface MarketingAnalysisRequest {
  businessNiche: string;
  product: string;
  targetAudience: string;
  region: string;
  goal: string;
  detailLevel: 'КРАТКО' | 'СТАНДАРТНО' | 'ПОДРОБНО';
  strongSide?: string;
  weakSide?: string;
  analysisType: 'РЫНОК' | 'КОНКУРЕНТЫ' | 'ЦА' | 'КАНАЛЫ' | 'SWOT';
}

// Список допустимых регионов
const VALID_REGIONS = [
  'Алматы',
  'Астана',
  'Шымкент',
  'Караганда',
  'Актобе',
  'Тараз',
  'Павлодар',
  'Усть-Каменогорск',
  'Семей',
  'Костанай',
  'Кызылорда',
  'Уральск',
  'Петропавловск',
  'Атырау',
  'Актау',
  'Туркестан',
  'Кокшетау',
  'Талдыкорган',
  'Экибастуз',
  'Рудный',
];

// Список уровней детализации
const DETAIL_LEVELS = ['КРАТКО', 'СТАНДАРТНО', 'ПОДРОБНО'] as const;

// Функция для отправки запроса
async function startMarketingAnalysis(
  data: MarketingAnalysisRequest
): Promise<string> {
  const response = await fetch(
    'https://api.konturai.kz/api/marketing/analysis/start',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: 'Bearer YOUR_JWT_TOKEN', // Если требуется
      },
      body: JSON.stringify(data),
    }
  );

  const result = await response.json();

  if (!result.success) {
    throw new Error(result.error?.message || 'Failed to start analysis');
  }

  return result.data.analysisId;
}

// Пример использования
const analysisId = await startMarketingAnalysis({
  businessNiche: 'E-commerce платформы',
  product: 'Разработка мобильных приложений',
  targetAudience: 'Малый и средний бизнес, владельцы интернет-магазинов',
  region: 'Алматы',
  goal: 'Увеличить количество клиентов на 50% за следующие 6 месяцев',
  detailLevel: 'СТАНДАРТНО',
  strongSide: 'Опытная команда, быстрая доставка',
  weakSide: 'Ограниченный маркетинговый бюджет',
  analysisType: 'РЫНОК',
});
```

### React компонент с формой

```tsx
import React, { useState } from 'react';

const MarketingAnalysisForm: React.FC = () => {
  const [formData, setFormData] = useState<MarketingAnalysisRequest>({
    businessNiche: '',
    product: '',
    targetAudience: '',
    region: '',
    goal: '',
    detailLevel: 'СТАНДАРТНО',
    strongSide: '',
    weakSide: '',
    analysisType: 'РЫНОК',
  });

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    try {
      const analysisId = await startMarketingAnalysis(formData);
      console.log('Analysis started:', analysisId);
      // Перенаправление на страницу с результатами
    } catch (error) {
      console.error('Error:', error);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>Ниша бизнеса *</label>
        <input
          type='text'
          value={formData.businessNiche}
          onChange={(e) =>
            setFormData({ ...formData, businessNiche: e.target.value })
          }
          required
          minLength={3}
          maxLength={200}
        />
      </div>

      <div>
        <label>Продукт / услуга *</label>
        <input
          type='text'
          value={formData.product}
          onChange={(e) =>
            setFormData({ ...formData, product: e.target.value })
          }
          required
          minLength={3}
          maxLength={200}
        />
      </div>

      <div>
        <label>Целевая аудитория *</label>
        <textarea
          value={formData.targetAudience}
          onChange={(e) =>
            setFormData({ ...formData, targetAudience: e.target.value })
          }
          required
          minLength={3}
          maxLength={300}
        />
      </div>

      <div>
        <label>Регион *</label>
        <select
          value={formData.region}
          onChange={(e) => setFormData({ ...formData, region: e.target.value })}
          required
        >
          <option value=''>Выберите регион</option>
          {VALID_REGIONS.map((region) => (
            <option key={region} value={region}>
              {region}
            </option>
          ))}
        </select>
      </div>

      <div>
        <label>Цель на 6-12 месяцев *</label>
        <textarea
          value={formData.goal}
          onChange={(e) => setFormData({ ...formData, goal: e.target.value })}
          required
          minLength={10}
          maxLength={500}
        />
      </div>

      <div>
        <label>Уровень детализации анализа *</label>
        <div>
          {DETAIL_LEVELS.map((level) => (
            <label key={level}>
              <input
                type='radio'
                name='detailLevel'
                value={level}
                checked={formData.detailLevel === level}
                onChange={(e) =>
                  setFormData({
                    ...formData,
                    detailLevel: e.target.value as any,
                  })
                }
              />
              {level === 'КРАТКО' && ' Кратко'}
              {level === 'СТАНДАРТНО' && ' Стандартно'}
              {level === 'ПОДРОБНО' && ' Подробно'}
            </label>
          ))}
        </div>
      </div>

      <div>
        <label>Сильная сторона</label>
        <textarea
          value={formData.strongSide}
          onChange={(e) =>
            setFormData({ ...formData, strongSide: e.target.value })
          }
          maxLength={500}
        />
      </div>

      <div>
        <label>Слабая сторона</label>
        <textarea
          value={formData.weakSide}
          onChange={(e) =>
            setFormData({ ...formData, weakSide: e.target.value })
          }
          maxLength={500}
        />
      </div>

      <div>
        <label>Тип анализа *</label>
        <select
          value={formData.analysisType}
          onChange={(e) =>
            setFormData({ ...formData, analysisType: e.target.value as any })
          }
          required
        >
          <option value='РЫНОК'>Рынок</option>
          <option value='КОНКУРЕНТЫ'>Конкуренты</option>
          <option value='ЦА'>Целевая аудитория</option>
          <option value='КАНАЛЫ'>Каналы</option>
          <option value='SWOT'>SWOT</option>
        </select>
      </div>

      <button type='submit'>Сгенерировать анализ бизнеса</button>
    </form>
  );
};
```

---

## Валидация на клиенте

Рекомендуется выполнять валидацию на клиенте перед отправкой запроса:

```typescript
function validateMarketingAnalysisRequest(data: MarketingAnalysisRequest): {
  valid: boolean;
  errors: Record<string, string>;
} {
  const errors: Record<string, string> = {};

  // Валидация businessNiche
  if (!data.businessNiche || data.businessNiche.trim().length < 3) {
    errors.businessNiche = 'Ниша бизнеса должна содержать минимум 3 символа';
  }
  if (data.businessNiche && data.businessNiche.length > 200) {
    errors.businessNiche = 'Ниша бизнеса не должна превышать 200 символов';
  }

  // Валидация product
  if (!data.product || data.product.trim().length < 3) {
    errors.product = 'Продукт должен содержать минимум 3 символа';
  }
  if (data.product && data.product.length > 200) {
    errors.product = 'Продукт не должен превышать 200 символов';
  }

  // Валидация targetAudience
  if (!data.targetAudience || data.targetAudience.trim().length < 3) {
    errors.targetAudience =
      'Целевая аудитория должна содержать минимум 3 символа';
  }
  if (data.targetAudience && data.targetAudience.length > 300) {
    errors.targetAudience =
      'Целевая аудитория не должна превышать 300 символов';
  }

  // Валидация region
  if (!data.region || !VALID_REGIONS.includes(data.region)) {
    errors.region = 'Выберите допустимый регион из списка';
  }

  // Валидация goal
  if (!data.goal || data.goal.trim().length < 10) {
    errors.goal = 'Цель должна содержать минимум 10 символов';
  }
  if (data.goal && data.goal.length > 500) {
    errors.goal = 'Цель не должна превышать 500 символов';
  }

  // Валидация detailLevel
  if (!data.detailLevel || !DETAIL_LEVELS.includes(data.detailLevel)) {
    errors.detailLevel = 'Выберите допустимый уровень детализации';
  }

  // Валидация strongSide (опциональное)
  if (data.strongSide && data.strongSide.length > 500) {
    errors.strongSide = 'Сильная сторона не должна превышать 500 символов';
  }

  // Валидация weakSide (опциональное)
  if (data.weakSide && data.weakSide.length > 500) {
    errors.weakSide = 'Слабая сторона не должна превышать 500 символов';
  }

  // Валидация analysisType
  const validAnalysisTypes = ['РЫНОК', 'КОНКУРЕНТЫ', 'ЦА', 'КАНАЛЫ', 'SWOT'];
  if (!data.analysisType || !validAnalysisTypes.includes(data.analysisType)) {
    errors.analysisType = 'Выберите допустимый тип анализа';
  }

  return {
    valid: Object.keys(errors).length === 0,
    errors,
  };
}
```

---

## Миграция со старого API

Если у вас есть код, использующий старые поля, необходимо обновить его следующим образом:

### Старый формат (больше не работает):

```json
{
  "product": "Разработка мобильных приложений",
  "location": "Алматы, Казахстан",
  "client": "B2B клиенты",
  "differentiator": "Быстрая разработка за 2 недели",
  "analysisType": "РЫНОК"
}
```

### Новый формат:

```json
{
  "businessNiche": "Разработка программного обеспечения",
  "product": "Разработка мобильных приложений",
  "targetAudience": "B2B клиенты, технологические компании, стартапы",
  "region": "Алматы",
  "goal": "Увеличить количество клиентов на 50% за следующие 6 месяцев",
  "detailLevel": "СТАНДАРТНО",
  "strongSide": "Быстрая разработка за 2 недели, опытная команда",
  "weakSide": "",
  "analysisType": "РЫНОК"
}
```

### Маппинг старых полей на новые:

| Старое поле      | Новое поле(я)                             | Примечание                                       |
| ---------------- | ----------------------------------------- | ------------------------------------------------ |
| `location`       | `region`                                  | Только название города из списка                 |
| `client`         | `targetAudience`                          | Более детальное описание (свободный текст)       |
| `differentiator` | `businessNiche`, `strongSide`, `weakSide` | Разделено на несколько полей для лучшего анализа |

---

## Обработка ошибок валидации

При ошибках валидации API возвращает следующий формат:

```json
{
  "success": false,
  "message": "Ошибка валидации",
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Ошибка валидации входных данных",
    "details": {
      "businessNiche": "Поле 'businessNiche' должно содержать от 3 до 200 символов",
      "region": "Поле 'region' должно быть одним из допустимых городов Казахстана",
      "detailLevel": "Поле 'detailLevel' должно быть одним из: КРАТКО, СТАНДАРТНО, ПОДРОБНО"
    }
  }
}
```

---

## Важные замечания

1. **Регистр важен**: Значения `region`, `detailLevel` и `analysisType` чувствительны к регистру. Используйте точные значения из списка допустимых.

2. **Все новые поля передаются в OpenAI**: Все указанные поля включаются в контекст для генерации анализа, что улучшает качество и релевантность результатов.

3. **Уровень детализации влияет на результат**: Выбор `detailLevel` напрямую влияет на объем и глубину генерируемого анализа.

4. **Опциональные поля улучшают анализ**: Хотя `strongSide` и `weakSide` опциональны, их указание помогает AI лучше понять бизнес и дать более точные рекомендации.

5. **Обратная совместимость**: Старые поля больше не поддерживаются. Необходимо обновить все клиентские приложения.

---

## Поддержка

При возникновении проблем с API обращайтесь в техническую поддержку с указанием:

- `analysisId` (если есть)
- Время запроса
- Описание проблемы
- Код ошибки (если есть)
- Пример запроса (без чувствительных данных)
