# 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` (обязательное)

**Описание**: Структурированное описание целевой аудитории в формате JSON. Позволяет выбрать гендер, возрастные диапазоны и типы аудитории. Можно выбрать несколько вариантов в каждой категории.

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

- Должно быть объектом JSON с полями `genders`, `ageRanges`, `types`
- Хотя бы одно поле должно быть заполнено и содержать непустой массив
- Каждое поле должно содержать только допустимые значения

**Структура**:

```json
{
  "genders": ["Женщины", "Мужчины"],
  "ageRanges": ["20-40", "25-45"],
  "types": ["Семьи", "Молодёжь"]
}
```

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

- `genders`: `["Женщины", "Мужчины"]` - можно выбрать один или оба
- `ageRanges`: `["20-40", "25-45", "18-25", "40-60", "60+"]` - можно выбрать один или несколько диапазонов
- `types`: `["Семьи", "Молодёжь", "Все подряд"]` - можно выбрать один или несколько типов

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

```json
"targetAudience": {
  "genders": ["Женщины"],
  "ageRanges": ["20-40"],
  "types": ["Молодёжь"]
}
```

```json
"targetAudience": {
  "genders": ["Женщины", "Мужчины"],
  "ageRanges": ["25-45", "40-60"],
  "types": ["Семьи"]
}
```

```json
"targetAudience": {
  "genders": ["Мужчины"],
  "ageRanges": ["18-25"],
  "types": ["Молодёжь", "Все подряд"]
}
```

**Примечание**: Можно выбрать несколько вариантов в каждой категории. Все выбранные значения будут отражены в анализе.

---

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

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

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

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

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

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

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

```json
"region": ["Алматы"]
```

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

```json
"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` (обязательное)

**Описание**: Тип(ы) анализа, которые необходимо провести. Можно выбрать один или несколько типов анализа. При выборе нескольких типов будет создан отдельный анализ для каждого типа.

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

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

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

- `"РЫНОК"` - Анализ рынка (размер рынка, динамика роста, сегменты, тренды)
- `"КОНКУРЕНТЫ"` - Анализ конкурентов (основные конкуренты, их сильные/слабые стороны, позиционирование)
- `"ЦА"` - Анализ целевой аудитории (демография, психография, потребности, поведение)
- `"КАНАЛЫ"` - Анализ маркетинговых каналов (эффективность каналов, рекомендации по выбору)
- `"SWOT"` - SWOT-анализ (сильные стороны, слабые стороны, возможности, угрозы)

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

```json
"analysisType": ["РЫНОК"]
```

```json
"analysisType": ["РЫНОК", "КОНКУРЕНТЫ", "ЦА"]
```

```json
"analysisType": ["РЫНОК", "КОНКУРЕНТЫ", "ЦА", "КАНАЛЫ", "SWOT"]
```

**Важно**: 
- При выборе нескольких типов анализа API создаст отдельные записи анализа для каждого типа
- В ответе будет возвращен массив с информацией о каждом созданном анализе
- Каждый анализ будет обрабатываться независимо и иметь свой статус

---

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

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

**Пример 1: Один тип анализа, один регион**

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

**Пример 2: Несколько типов анализа, несколько регионов**

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

**Пример 3: Все типы анализа**

```json
{
  "businessNiche": "E-commerce платформы",
  "product": "Разработка мобильных приложений для интернет-магазинов",
  "targetAudience": {
    "genders": ["Женщины", "Мужчины"],
    "ageRanges": ["20-40", "25-45"],
    "types": ["Семьи", "Молодёжь", "Все подряд"]
  },
  "region": ["Алматы", "Астана"],
  "goal": "Увеличить количество клиентов на 50% за следующие 6 месяцев",
  "detailLevel": "ПОДРОБНО",
  "analysisType": ["РЫНОК", "КОНКУРЕНТЫ", "ЦА", "КАНАЛЫ", "SWOT"]
}
```

---

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

### JavaScript/TypeScript

```typescript
interface TargetAudience {
  genders?: ('Женщины' | 'Мужчины')[];
  ageRanges?: ('20-40' | '25-45' | '18-25' | '40-60' | '60+')[];
  types?: ('Семьи' | 'Молодёжь' | 'Все подряд')[];
}

interface MarketingAnalysisRequest {
  businessNiche: string;
  product: string;
  targetAudience: TargetAudience;
  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<MarketingAnalysisResponse | MarketingAnalysisResponse[]> {
  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');
  }

  // Если выбрано несколько типов анализа, result.data будет массивом
  return result.data;
}

interface MarketingAnalysisResponse {
  analysisId: string;
  status: string;
  estimatedCompletion: string;
  message: string;
}

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

// Если выбрано несколько типов анализа, result будет массивом
if (Array.isArray(result)) {
  console.log(`Создано ${result.length} анализов`);
  result.forEach((analysis, index) => {
    console.log(`Анализ ${index + 1}: ${analysis.analysisId}`);
  });
} else {
  console.log('Анализ создан:', result.analysisId);
}
```

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

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

const MarketingAnalysisForm: React.FC = () => {
  const [formData, setFormData] = useState<MarketingAnalysisRequest>({
    businessNiche: '',
    product: '',
    targetAudience: {
      genders: [],
      ageRanges: [],
      types: []
    },
    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>
        <div>
          <div>
            <label>Гендер:</label>
            {['Женщины', 'Мужчины'].map((gender) => (
              <label key={gender}>
                <input
                  type='checkbox'
                  checked={formData.targetAudience.genders?.includes(gender as any)}
                  onChange={(e) => {
                    const genders = formData.targetAudience.genders || [];
                    if (e.target.checked) {
                      setFormData({
                        ...formData,
                        targetAudience: {
                          ...formData.targetAudience,
                          genders: [...genders, gender as any]
                        }
                      });
                    } else {
                      setFormData({
                        ...formData,
                        targetAudience: {
                          ...formData.targetAudience,
                          genders: genders.filter((g) => g !== gender)
                        }
                      });
                    }
                  }}
                />
                {gender}
              </label>
            ))}
          </div>
          <div>
            <label>Возраст:</label>
            {['20-40', '25-45', '18-25', '40-60', '60+'].map((age) => (
              <label key={age}>
                <input
                  type='checkbox'
                  checked={formData.targetAudience.ageRanges?.includes(age as any)}
                  onChange={(e) => {
                    const ageRanges = formData.targetAudience.ageRanges || [];
                    if (e.target.checked) {
                      setFormData({
                        ...formData,
                        targetAudience: {
                          ...formData.targetAudience,
                          ageRanges: [...ageRanges, age as any]
                        }
                      });
                    } else {
                      setFormData({
                        ...formData,
                        targetAudience: {
                          ...formData.targetAudience,
                          ageRanges: ageRanges.filter((a) => a !== age)
                        }
                      });
                    }
                  }}
                />
                {age}
              </label>
            ))}
          </div>
          <div>
            <label>Тип:</label>
            {['Семьи', 'Молодёжь', 'Все подряд'].map((type) => (
              <label key={type}>
                <input
                  type='checkbox'
                  checked={formData.targetAudience.types?.includes(type as any)}
                  onChange={(e) => {
                    const types = formData.targetAudience.types || [];
                    if (e.target.checked) {
                      setFormData({
                        ...formData,
                        targetAudience: {
                          ...formData.targetAudience,
                          types: [...types, type as any]
                        }
                      });
                    } else {
                      setFormData({
                        ...formData,
                        targetAudience: {
                          ...formData.targetAudience,
                          types: types.filter((t) => t !== type)
                        }
                      });
                    }
                  }}
                />
                {type}
              </label>
            ))}
          </div>
        </div>
      </div>

      <div>
        <label>Регион *</label>
        <div>
          {VALID_REGIONS.map((region) => (
            <label key={region}>
              <input
                type='checkbox'
                checked={formData.region.includes(region)}
                onChange={(e) => {
                  if (e.target.checked) {
                    setFormData({
                      ...formData,
                      region: [...formData.region, region]
                    });
                  } else {
                    setFormData({
                      ...formData,
                      region: formData.region.filter((r) => r !== region)
                    });
                  }
                }}
              />
              {region}
            </label>
          ))}
        </div>
      </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>
        <div>
          {['РЫНОК', 'КОНКУРЕНТЫ', 'ЦА', 'КАНАЛЫ', 'SWOT'].map((type) => (
            <label key={type}>
              <input
                type='checkbox'
                checked={formData.analysisType.includes(type as any)}
                onChange={(e) => {
                  if (e.target.checked) {
                    setFormData({
                      ...formData,
                      analysisType: [...formData.analysisType, type as any]
                    });
                  } else {
                    setFormData({
                      ...formData,
                      analysisType: formData.analysisType.filter((t) => t !== type)
                    });
                  }
                }}
              />
              {type === 'РЫНОК' && ' Рынок'}
              {type === 'КОНКУРЕНТЫ' && ' Конкуренты'}
              {type === 'ЦА' && ' Целевая аудитория'}
              {type === 'КАНАЛЫ' && ' Каналы'}
              {type === 'SWOT' && ' SWOT'}
            </label>
          ))}
        </div>
      </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` (если есть)
- Время запроса
- Описание проблемы
- Код ошибки (если есть)
- Пример запроса (без чувствительных данных)
