11 KiB
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 конфигурации
{
"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. Как данные попадают в регистрацию и сессию
Передача в сессию (на каждом экране):
- Пользователь выбирает вариант на экране (например, "Male" с id "male")
- Ответ сохраняется в
FunnelAnswersпод ключом экрана:{ "gender-screen": ["male"] } - При переходе вперед (нажатие Continue или автопереход):
- Вызывается
buildSessionDataFromScreen()для текущего экрана - Создается объект с вложенной структурой:
{ profile: { gender: "male" } } - Вызывается
updateSession()с данными:{ answers: { "gender-screen": ["male"] }, // Старая логика profile: { gender: "male" } // Новая логика с registrationFieldKey }
- Вызывается
- Данные отправляются в API и сохраняются в сессии пользователя
Передача в регистрацию (при авторизации):
- При переходе на email экран вызывается функция
buildRegistrationDataFromAnswers() - Функция обрабатывает все list single selection экраны с
registrationFieldKey - Создается объект с вложенной структурой из всех экранов:
{ profile: { gender: "male", relationship_status: "single" } } - При авторизации этот объект объединяется с базовым payload
- Отправляется на сервер в составе
ICreateAuthorizeRequest
4. Структура payload регистрации
Базовый payload (без registrationFieldKey):
{
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"):
{
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:
{
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"
}
}
Полный пример воронки
{
"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 регистрации будет:
{
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"
}
}
Ограничения
- Только для single selection - работает только с
selectionType: "single" - Только ID опции - передается именно
idвыбранной опции, а неlabelилиvalue - Перезапись значений - если несколько экранов используют один и тот же ключ, последний перезапишет предыдущий
- Обязательный 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
Используется при авторизации для сбора данных со всех экранов воронки:
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
Используется при переходе вперед для сбора данных с текущего экрана:
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
- Используйте понятные ID - ID опций должны соответствовать ожидаемым значениям на сервере
- Документируйте ключи - ведите список используемых
registrationFieldKeyдля избежания конфликтов - Проверяйте типы - убедитесь что ID опций соответствуют типам полей в
ICreateAuthorizeRequest - Тестируйте payload - проверяйте что данные корректно попадают в регистрацию
Примеры использования
Простой профиль
{
"list": {
"selectionType": "single",
"registrationFieldKey": "profile.gender",
"options": [...]
}
}
Вложенная структура
{
"list": {
"selectionType": "single",
"registrationFieldKey": "partner.birthplace.country",
"options": [
{ "id": "US", "label": "United States" },
{ "id": "UK", "label": "United Kingdom" }
]
}
}
Без регистрации (обычный list)
{
"list": {
"selectionType": "single",
// registrationFieldKey не указан - данные не попадут в регистрацию
"options": [...]
}
}