# Registration Field Key для List Single Selection

## Описание

Функциональность `registrationFieldKey` позволяет автоматически передавать выбранные значения из list single selection экранов в payload регистрации пользователя при авторизации через email экран.

## Как это работает

### 1. Настройка в админке

Для list экранов с `selectionType: "single"` в админке появляется дополнительное поле **"Ключ поля для регистрации"**.

В это поле можно указать путь к полю в объекте регистрации, используя точечную нотацию для вложенных объектов.

**Примеры:**
- `profile.gender` → `{ profile: { gender: "selected-id" } }`
- `profile.relationship_status` → `{ profile: { relationship_status: "selected-id" } }`
- `partner.gender` → `{ partner: { gender: "selected-id" } }`

### 2. Пример JSON конфигурации

```json
{
  "id": "gender-screen",
  "template": "list",
  "title": {
    "text": "What is your gender?"
  },
  "list": {
    "selectionType": "single",
    "registrationFieldKey": "profile.gender",
    "options": [
      {
        "id": "male",
        "label": "Male",
        "emoji": "👨"
      },
      {
        "id": "female",
        "label": "Female",
        "emoji": "👩"
      },
      {
        "id": "other",
        "label": "Other",
        "emoji": "🧑"
      }
    ]
  }
}
```

### 3. Как данные попадают в регистрацию и сессию

#### **Передача в сессию (на каждом экране):**

1. **Пользователь выбирает вариант** на экране (например, "Male" с id "male")
2. **Ответ сохраняется** в `FunnelAnswers` под ключом экрана: `{ "gender-screen": ["male"] }`
3. **При переходе вперед** (нажатие Continue или автопереход):
   - Вызывается `buildSessionDataFromScreen()` для текущего экрана
   - Создается объект с вложенной структурой: `{ profile: { gender: "male" } }`
   - Вызывается `updateSession()` с данными:
     ```typescript
     {
       answers: { "gender-screen": ["male"] },  // Старая логика
       profile: { gender: "male" }              // Новая логика с registrationFieldKey
     }
     ```
4. **Данные отправляются в API** и сохраняются в сессии пользователя

#### **Передача в регистрацию (при авторизации):**

1. **При переходе на email экран** вызывается функция `buildRegistrationDataFromAnswers()`
2. **Функция обрабатывает** все list single selection экраны с `registrationFieldKey`
3. **Создается объект** с вложенной структурой из всех экранов: `{ profile: { gender: "male", relationship_status: "single" } }`
4. **При авторизации** этот объект объединяется с базовым payload
5. **Отправляется на сервер** в составе `ICreateAuthorizeRequest`

### 4. Структура payload регистрации

**Базовый payload (без registrationFieldKey):**
```typescript
{
  email: "user@example.com",
  timezone: "Europe/Moscow",
  locale: "en",
  source: "funnel-id",
  sign: true,
  signDate: "2024-01-01T00:00:00.000Z",
  feature: "stripe"
}
```

**С registrationFieldKey (profile.gender = "male"):**
```typescript
{
  email: "user@example.com",
  timezone: "Europe/Moscow",
  locale: "en",
  source: "funnel-id",
  sign: true,
  signDate: "2024-01-01T00:00:00.000Z",
  feature: "stripe",
  profile: {
    gender: "male"
  }
}
```

**С несколькими registrationFieldKey:**
```typescript
{
  email: "user@example.com",
  timezone: "Europe/Moscow",
  locale: "en",
  source: "funnel-id",
  sign: true,
  signDate: "2024-01-01T00:00:00.000Z",
  feature: "stripe",
  profile: {
    gender: "male",
    relationship_status: "single"
  },
  partner: {
    gender: "female"
  }
}
```

## Полный пример воронки

```json
{
  "meta": {
    "id": "dating-funnel",
    "title": "Dating Profile",
    "firstScreenId": "gender"
  },
  "screens": [
    {
      "id": "gender",
      "template": "list",
      "title": { "text": "What is your gender?" },
      "list": {
        "selectionType": "single",
        "registrationFieldKey": "profile.gender",
        "options": [
          { "id": "male", "label": "Male", "emoji": "👨" },
          { "id": "female", "label": "Female", "emoji": "👩" }
        ]
      },
      "navigation": {
        "defaultNextScreenId": "relationship-status"
      }
    },
    {
      "id": "relationship-status",
      "template": "list",
      "title": { "text": "What is your relationship status?" },
      "list": {
        "selectionType": "single",
        "registrationFieldKey": "profile.relationship_status",
        "options": [
          { "id": "single", "label": "Single" },
          { "id": "relationship", "label": "In a relationship" },
          { "id": "married", "label": "Married" }
        ]
      },
      "navigation": {
        "defaultNextScreenId": "partner-gender"
      }
    },
    {
      "id": "partner-gender",
      "template": "list",
      "title": { "text": "What is your partner's gender?" },
      "list": {
        "selectionType": "single",
        "registrationFieldKey": "partner.gender",
        "options": [
          { "id": "male", "label": "Male", "emoji": "👨" },
          { "id": "female", "label": "Female", "emoji": "👩" }
        ]
      },
      "navigation": {
        "defaultNextScreenId": "email"
      }
    },
    {
      "id": "email",
      "template": "email",
      "title": { "text": "Enter your email" },
      "emailInput": {
        "label": "Email",
        "placeholder": "your@email.com"
      }
    }
  ]
}
```

**Результат после прохождения воронки:**

Если пользователь выбрал:
- Gender: Male
- Relationship Status: Single  
- Partner Gender: Female
- Email: user@example.com

Payload регистрации будет:
```typescript
{
  email: "user@example.com",
  timezone: "Europe/Moscow",
  locale: "en",
  source: "dating-funnel",
  sign: true,
  signDate: "2024-01-01T00:00:00.000Z",
  feature: "stripe",
  profile: {
    gender: "male",
    relationship_status: "single"
  },
  partner: {
    gender: "female"
  }
}
```

## Ограничения

1. **Только для single selection** - работает только с `selectionType: "single"`
2. **Только ID опции** - передается именно `id` выбранной опции, а не `label` или `value`
3. **Перезапись значений** - если несколько экранов используют один и тот же ключ, последний перезапишет предыдущий
4. **Обязательный email экран** - данные передаются только при авторизации через email экран

## Техническая реализация

### Файлы

- **types.ts** - добавлено поле `registrationFieldKey` в `ListScreenDefinition`
- **ListScreenConfig.tsx** - UI для настройки ключа в админке
- **registrationHelpers.ts** - утилиты `buildRegistrationDataFromAnswers()` и `buildSessionDataFromScreen()`
- **FunnelRuntime.tsx** - вызывает `buildSessionDataFromScreen()` при переходе вперед и передает в `updateSession()`
- **useAuth.ts** - принимает `registrationData` и объединяет с базовым payload
- **EmailTemplate.tsx** - вызывает `buildRegistrationDataFromAnswers()` и передает в `useAuth`
- **screenRenderer.tsx** - передает `answers` в `EmailTemplate`

### Функция buildRegistrationDataFromAnswers

Используется при авторизации для сбора данных со всех экранов воронки:

```typescript
export function buildRegistrationDataFromAnswers(
  funnel: FunnelDefinition,
  answers: FunnelAnswers
): RegistrationDataObject {
  const registrationData: RegistrationDataObject = {};

  for (const screen of funnel.screens) {
    if (screen.template === "list") {
      const listScreen = screen as ListScreenDefinition;
      
      if (
        listScreen.list.selectionType === "single" &&
        listScreen.list.registrationFieldKey &&
        answers[screen.id] &&
        answers[screen.id].length > 0
      ) {
        const selectedId = answers[screen.id][0];
        const fieldKey = listScreen.list.registrationFieldKey;
        
        // Устанавливаем значение по многоуровневому ключу
        setNestedValue(registrationData, fieldKey, selectedId);
      }
    }
  }

  return registrationData;
}
```

### Функция buildSessionDataFromScreen

Используется при переходе вперед для сбора данных с текущего экрана:

```typescript
export function buildSessionDataFromScreen(
  screen: { template: string; id: string; list?: { selectionType?: string; registrationFieldKey?: string } },
  selectedIds: string[]
): RegistrationDataObject {
  const sessionData: RegistrationDataObject = {};

  if (screen.template === "list" && screen.list) {
    const { selectionType, registrationFieldKey } = screen.list;
    
    if (
      selectionType === "single" &&
      registrationFieldKey &&
      selectedIds.length > 0
    ) {
      const selectedId = selectedIds[0];
      setNestedValue(sessionData, registrationFieldKey, selectedId);
    }
  }

  return sessionData;
}
```

## Best Practices

1. **Используйте понятные ID** - ID опций должны соответствовать ожидаемым значениям на сервере
2. **Документируйте ключи** - ведите список используемых `registrationFieldKey` для избежания конфликтов
3. **Проверяйте типы** - убедитесь что ID опций соответствуют типам полей в `ICreateAuthorizeRequest`
4. **Тестируйте payload** - проверяйте что данные корректно попадают в регистрацию

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

### Простой профиль
```json
{
  "list": {
    "selectionType": "single",
    "registrationFieldKey": "profile.gender",
    "options": [...]
  }
}
```

### Вложенная структура
```json
{
  "list": {
    "selectionType": "single",
    "registrationFieldKey": "partner.birthplace.country",
    "options": [
      { "id": "US", "label": "United States" },
      { "id": "UK", "label": "United Kingdom" }
    ]
  }
}
```

### Без регистрации (обычный list)
```json
{
  "list": {
    "selectionType": "single",
    // registrationFieldKey не указан - данные не попадут в регистрацию
    "options": [...]
  }
}
```
