Направление работ: Mobile Код раздела: 5.2 Раздел: Профиль > Настройки профиля Статус: Готов Ответственный: Панкова Л.А. Версия: 0.1 Обновлено: 21.07.26
1. Назначение
Данный раздел описывает меню действий профиля и настройки профиля пользователя в мобильном приложении.
Пользователь открывает меню действий рядом с аватаром и может изменить аватар, перейти к редактированию профиля, перейти к настройкам приложения или выйти из аккаунта. Экран связан с главным экраном профиля и соседними разделами настроек, но не раскрывает сценарии редактирования учетных данных и настроек приложения.
Раздел зависит от Back: 1.3 Клиенты. Детальная работа с учетными данными описывается в разделе 5.2.1 Редактирование учетных данных.
2. Ключевые понятия
Настройки профиля - раздел мобильного приложения, в котором пользователь управляет меню действий профиля, аватаром, персональными данными профиля и выходом из аккаунта.
Карточка клиента - сущность для хранения персональной информации об аккаунте и истории его взаимодействий с партнерами.
Учетные данные - телефон и почта аккаунта, которые отображаются в настройках профиля, но их изменения описываются в соседнем разделе.
3. Scope
Входит
S1: Действия в рамках настройки профиля S2: Выход из системы
Не входит
- Mobile 5.1 Главный экран - просмотр главного экрана профиля и переход к настройкам профиля
- Mobile 5.2.1 Редактирование учетных данных - смена номера телефона и почты
- Mobile 5.3 Настройки приложения - настройки приложения, пароля, код-пароля и привязанных карт
- Mobile 1.3 Вход - авторизация пользователя после выхода из аккаунта
- Backend/API-контракты, структура БД, хранение файлов и техническая реализация
4. BR
Указаны в пункте 4 раздела Back: 1.3 Клиенты.
5. Функциональные требования (UC + FR)
FR – functional requirements, что интерфейс должен уметь делать по определенному UC.
| ID | Cценарий | Функциональное требование | BR | Вес | Статус |
|---|---|---|---|---|---|
| S1: #FR5.2-1 | Пользователь открывает меню действий профиля | Интерфейс открывает меню действий рядом с аватаром и показывает пункты в следующем порядке: «Редактировать профиль» → «Изменить/Загрузить аватар» → «Настройки» → «Выйти». Подпись пункта аватара динамическая: «Загрузить аватар» при пустом фото и «Изменить аватар» при наличии. | 1 | Частично \ #OQ5.2-3 | |
| S1: #FR5.2-2 | Пользователь изменяет аватар | Интерфейс открывает нижний лист «Изменить аватар», показывает источники изображения «Из галереи» и «Сделать фото», позволяет выбрать источник и применяет выбранное или сделанное фото как аватар пользователя. | 1 | Реализовано | |
| S1: #FR5.2-3 | Пользователь выбирает источник аватарки впервые | Интерфейс вызывает системное разрешение на доступ к фото или камере при первом обращении к выбранному источнику. | 1 | Частично \ #OQ5.2-5 | |
| S1: #FR5.2-4 | Пользователь редактирует профиль | Интерфейс открывает экран «Редактировать профиль» и позволяет изменить имя, фамилию, отчество, дату рождения, пол, социальные сети и дополнительную информацию профиля. | 1 | Реализовано | |
| S1: #FR5.2-5 | Пользователь просматривает учетные данные | Интерфейс показывает телефон и почту пользователя как контактные данные и позволяет перейти к их изменению в раздел 5.2.1 Редактирование учетных данных. | 1 | Реализовано | |
| S1: #FR5.2-6 | Пользователь настраивает блок “Дополнительная информация” | Интерфейс показывает поля: вид деятельности, уровень навыков, музыкальный жанр, музыкальный инструмент и стиль танца; открывает список значений для выбранного поля, показывает текущее выбранное значение и применяет новый выбор к полю профиля. | 2 | Реализовано | |
| S1: #FR5.2-7 | Пользователь переходит в настройки приложения | Интерфейс позволяет перейти из пункта «Настройки» в раздел 5.3 Настройки приложения. | 1 | Реализовано | |
| S2: #FR5.2-8 | Пользователь инициирует выход из аккаунта | Интерфейс открывает подтверждение «Выйти из аккаунта» с действиями «Отмена» и «Выйти». | 1 | Реализовано | |
| S2: #FR5.2-9 | Пользователь отменяет выход из аккаунта | Интерфейс закрывает подтверждение выхода и оставляет пользователя в текущем аккаунте. | 1 | Реализовано | |
| S2: #FR5.2-10 | Пользователь подтверждает выход из аккаунта | Интерфейс завершает пользовательскую сессию и переводит пользователя в раздел 1.3 Вход. | 1 | Реализовано |
6. Открытые вопросы
| ID | Источник | Вопрос | Кому | Статус | Рекомендации | Итоговое решение |
|---|---|---|---|---|---|---|
| #OQ5.2-1 | Код FR5.2-6 | Требование говорит: блок «Дополнительная информация» — выбор значений полей применяется к полю профиля. В коде все 6 полей есть, но блок собран из хардкод-заглушки SharedActivity._test_data («временный словарик… заглушка с сохранением в Shared Preference», «пока нет сервиса рекомендаций»). Выбор пишется только локально. \ spheres_activitiy_TEMP.dart:3-25; edit_profile_screen.dart:557-589 | Бизнес (Герман) | Open | Решение: это полноценная фича (и на что влияет выбор — рекомендации?) или заглушку скрыть до появления сервиса. (А, рекоменд.) до серверного сервиса скрыть/задизейблить блок или пометить «скоро», чтобы не собирать данные «в никуда»; (Б) признать фичей — завести серверную модель полей профиля и заменить _test_data реальным справочником. Связать с OQ5.2-2, OQ5.2-4. | Жду решения от бизнеса От бизнеса: доработать, используя API из 8.2.5 Клиентские справочники (есть на вики). Если API не работает, отправить задачу в статус «Ожидает API». |
| #OQ5.2-2 | Код FR5.2-6 | Проблема: значения поля «Сферы деятельности» в заглушке — это типы площадок (Репетиционные базы, Музыкальные классы, Танцевальные залы, Фотостудии), а не сферы деятельности клиента; описание поля вообще «Каталог стилей танцев». Таксономия полей перепутана. \ spheres_activitiy_TEMP.dart:32-77 | Бизнес (Герман) | Open | Решение по корректной таксономии полей профиля клиента. При реализации фичи (OQ5.2-1, вариант Б) — исправить: «сфера деятельности» ≠ тип площадки; согласовать состав значений с продуктом/Back 1.3. Пока блок на заглушке — самостоятельного смысла не несёт. | Жду решения от бизнеса От бизнеса: «Сферы деятельности» убрали из мобильного приложения. Вид деятельности — доктор, учитель, ветеринар и пр.; значения настраиваются в админке в клиентских справочниках, а на бэке передаются через API 8.2.5 Клиентские справочники. |
| #OQ5.2-3 | Код FR5.2-1 | Требование говорит: меню действий — «Изменить аватар», «Редактировать профиль», «Настройки», «Выйти из аккаунта» (в этом порядке); пункт назван «Изменить аватар». В коде все 4 пункта есть, но порядок иной (Редактировать профиль → Изменить/Загрузить аватар → Настройки → Выйти), а подпись пункта аватара динамическая: «Загрузить аватар» при пустом фото и «Изменить аватар» при наличии. \ profile_title.dart:213-354 | Бизнес (Герман) | Closed | Какой вариант канонический. (А, рекоменд.) привести BRD к коду — порядок пунктов + динамическая подпись «Загрузить/Изменить аватар»; (Б) если порядок/подпись из BRD канонические — поправить код. Пересекается с 5.1/OQ5.1-4 (то же меню «⋯»). | привести BRD к коду — порядок пунктов + динамическая подпись «Загрузить/Изменить аватар» От бизнеса: ок, уточнили в БРД. |
| #OQ5.2-4 | Код FR5.2-6 | Проблема: выбор доп. информации сохраняется мгновенно по тапу в локальный spheresPinStorage.save(...) (SharedPreferences), не входит в модель User и не уходит на бэкенд; кнопка «Сохранить» шлёт changeUser(state.changedUser) без этих данных. Данные теряются при переустановке, не синхронизируются между устройствами, невидимы партнёру. Плюс UX-рассинхрон: доп. информация сохраняется сразу, остальная форма — по кнопке. \ sphere_picker.dart:113-127; edit_profile_screen.dart:60-66,606-617 | Бизнес/Разработка | Open | По сути FR5.2-6 не реализован (данные в профиль не попадают). (А, рекоменд.) после серверного контракта сохранять выбор в профиль (User + gRPC) и включить в общий поток «Сохранить»; (Б, временно) если фича остаётся локальной — зафиксировать ограничение в BRD и убрать мгновенное авто-сохранение в пользу единой кнопки. Зависит от OQ5.2-1. | Жду решения от бизнеса От бизнеса: доработка, вес 1, API 8.2.5 Клиентские справочники. |
| #OQ5.2-5 | Код FR5.2-3 | Требование говорит: при первом обращении к источнику вызывается системное разрешение на доступ к фото/камере. В коде системный диалог вызывается неявно самим image_picker.pickImage (первое обращение — ок). Но отказ / «запрещено навсегда» проглатывается: try/catch пишет debugPrint и возвращает null; пользователю не показывается ни ошибка, ни переход в настройки ОС — при отказе «ничего не происходит». \ profile_title.dart:25-73 | Разработка | Closed | Первичный вызов разрешения работает; тихое проглатывание отказа — дефект. Закрываю сам: обрабатывать denied/permanentlyDenied (через permission_handler) — показывать пояснение и кнопку «Открыть настройки»; минимум — снекбар при отказе → тикет в Bitrix. Поведение при отказе зафиксировать в BRD. | Мы не запрашиваем разрешение ни к камере, ни к галерее, поскольку используем системные элементы. От бизнеса: ок. |
| #OQ5.2-6 | Код FR5.2-6 | Проблема (найдено при досверке 1c4ad0e): блок «Дополнительная информация» теперь грузит категории с сервера (ClientsService/GetServiceGroupsWithSubGroups), но при ошибке запроса (сеть/5xx/таймаут) catch в _loadServiceGroups молча гасит исключение и просто снимает спиннер — пользователь видит пустой блок без полей и без сообщения об ошибке, повторить загрузку нечем (нет кнопки «Повторить»). \ edit_profile_screen.dart:86-99 | Разработка | Open | Продуктового выбора не требуется. Рекомендация: показать состояние ошибки с кнопкой «Повторить» (или как минимум toast) вместо тихого пустого блока → тикет в Bitrix. |
Вопросы по сверке с кодом
BRD 5.2 v0.1 · booking.mobile.flutter · commit
1c4ad0e/ веткаorigin/main(2026-09-08) · дата сверки 2026-09-08 — повторная (дельта) сверка по итогам дейликов, вторая итерация; предыдущие сверки: 2026-07-10 commitdad0c65(полная), 2026-09-08 commit2b93d4fa(дельта №1) · якорьlib/src/feature/profile_page/(меню действий —profile/widget/profile_title.dart; редактирование —edit_profile/; экран «Настройки»/5.3 —profile_settings/) · маршрутизация без сверки с гайдбуком (не передан) Досверка №2, 2026-09-08 (commit1c4ad0e, mergedev→main): дельта2b93d4fa→1c4ad0e(коммитd8f0a99«additional information form server») закрывает главную находку прошлого прохода: блок «Дополнительная информация» (FR5.2-6) больше не хардкод-заглушкаSharedActivity/spheres_activitiy_TEMP.dart(файл удалён из импортов,edit_profile_screen.dart:1-16) — категории и подгруппы теперь грузятся с сервера через новыйServiceGroupsRepository.getAllServiceGroups()→ClientsService/GetServiceGroupsWithSubGroups(5 групп: виды деятельности, стиль танцев, муз. инструменты, муз. жанры, уровни навыков; архивные подгруппы отфильтрованы) —service_groups_repository.dart:7-56,edit_profile_screen.dart:86-99. Плейсхолдер поля теперь берётся из имени группы с сервера, а не захардкожен «Сферы деятельности» (закрывает таксономию из OQ5.2-2) —edit_profile_screen.dart:547. Выбор подгрупп (реальные UUID вместо тестовых строк) наконец уходит на бэкенд:activeGroupsпередаются какclientServiceGroupIdsвchangeUser→UserRepository.changeUser→UpdateClientMobile(закрывает персистентность из OQ5.2-4) —edit_profile_screen.dart:654-668,profile_bloc.dart:66-70,205-210,user_repository.dart:20-25,94-104,user.dart:79-103,user_update_model.dart:33; кнопка «Сохранить» теперь реагирует и на изменение доп.информации, не только на смену полей формы (_hasUnsavedActiveGroups,edit_profile_screen.dart:83-84,654). Итог: OQ5.2-1, OQ5.2-2 и OQ5.2-4 выглядят закрытыми кодом — FR5.2-6 переведён в «Реализовано» (сами строки OQ не редактирую, см.5.2-mobile.changes.md). Новая находка обратного прохода — тихое проглатывание ошибки загрузки категорий, без UI-сигнала — заведена как OQ5.2-6 (Разработка, Open). OQ5.2-3 (порядок пунктов меню) и OQ5.2-5 (тихий отказ в разрешении камеры/галереи) вне этой дельты — файлprofile_title.dartв2b93d4fa..1c4ad0eне менялся, статусы не трогаю. Детали —5.2-mobile.changes.md. Дельта-сверка 2026-09-08: междуdad0c65и2b93d4faякорные для 5.2 файлы (spheres_activitiy_TEMP.dart,sphere_picker.dart,edit_profile_screen.dart,profile_title.dart) менялись толькоdart format(commit0d2c5cb) — заглушка сфер деятельности и локальное сохранение в SharedPreferences (OQ5.2-1/2/4) не тронуты.profile_settings_screen.dart(цель FR5.2-7 — переход в 5.3) переработан коммитамиdd54f5dи9db8346(биометрия/код-пароль — вне scope 5.2/5.3), заголовок «Настройки» на месте (profile_settings_screen.dart:419), переход из пункта «Настройки» работает без изменений. Все 10 FR и оба открытых OQ (OQ5.2-1…5) перепроверены — расхождений с прошлой сверкой не найдено, статусы без изменений; детали —5.2-mobile.changes.md. Сводка (после досверки 1c4ad0e): вопросов 6 (бизнесовых 3 / программных 3, добавлен OQ5.2-6) · подтверждено без вопросов 8 (FR5.2-2, FR5.2-4, FR5.2-5, FR5.2-6, FR5.2-7, FR5.2-8, FR5.2-9, FR5.2-10) · отрезано находок обратного прохода 3 (сверка 2b93d4fa) + 0 (сверка 1c4ad0e, 1 новая находка не отрезана, а заведена как OQ5.2-6) Под особым вниманием: OQ5.2-6 (новый, тихая ошибка загрузки доп.информации — нет UI-сигнала при сбое запроса); связанные изменения по email/кнопке «Продолжить» (OQ5.2.1-3/-5/-6/-8) — см. досверку 5.2.1.
Бизнесовые
| № | Связано с | Что в BRD | Что в коде | Где в коде |
|---|---|---|---|---|
| Б1 | FR5.2-6 | Блок «Дополнительная информация»: пользователь выбирает значения полей (сфера деятельности, вид деятельности, уровень навыков, муз. жанр, муз. инструмент, стиль танца), выбор «применяется к полю профиля». | Все 6 полей есть, но блок собран из хардкод-заглушки SharedActivity._test_data («временный словарик… заглушка с сохранением в Shared Preference», «пока нет сервиса рекомендаций»). Выбор пишется только локально. — нужно решение: это полноценная фича (и на что влияет выбор — рекомендации?) или заглушку скрыть до появления сервиса. | core/assets/data/temp_sphere_activity/spheres_activitiy_TEMP.dart:3-25; edit_profile/edit_profile_screen.dart:557-589 |
| Б2 | FR5.2-6 | Поле «сфера деятельности» — персональная сфера деятельности клиента. | Значения поля «Сферы деятельности» в заглушке — это типы площадок (Репетиционные базы, Музыкальные классы, Танцевальные залы, Фотостудии), а не сферы деятельности клиента; описание поля вообще «Каталог стилей танцев». — нужно решение по корректной таксономии полей профиля клиента. | spheres_activitiy_TEMP.dart:32-77 |
| Б3 | FR5.2-1 | Меню действий: пункты «Изменить аватар», «Редактировать профиль», «Настройки», «Выйти из аккаунта» (в этом порядке); пункт назван «Изменить аватар». | Все 4 пункта присутствуют, но порядок иной (Редактировать профиль → Изменить/Загрузить аватар → Настройки → Выйти), а подпись пункта аватара динамическая: «Загрузить аватар» при пустом фото и «Изменить аватар» при наличии. BRD документирует только «Изменить аватар». — нужно решение, какой вариант канонический. | profile/widget/profile_title.dart:213-354 |
Рекомендация / варианты решения
- Назначение блока «Дополнительная информация» (Б1, Б2) — Вариант А (рекоменд.): до появления серверного сервиса скрыть/задизейблить блок или пометить «скоро», чтобы не собирать данные «в никуда» и не вводить пользователя в заблуждение. Вариант Б: признать блок полноценной фичей — тогда завести серверную модель (поля в профиле клиента), заменить
_test_dataреальным справочником и исправить таксономию (Б2). В любом варианте — зафиксировать в BRD, на что влияет выбор. - Меню действий (Б3) — Вариант А (рекоменд.): привести BRD в соответствие коду — порядок пунктов + динамическая подпись «Загрузить/Изменить аватар». Вариант Б: если порядок и подпись из BRD канонические — поправить код.
Программные
| № | Связано с | Что в BRD | Что в коде | Где в коде |
|---|---|---|---|---|
| П1 | FR5.2-6 | Интерфейс «применяет новый выбор к полю профиля». | Выбор сохраняется мгновенно по тапу в локальный spheresPinStorage.save(...) (SharedPreferences), не входит в модель User и не уходит на бэкенд; кнопка «Сохранить» шлёт changeUser(state.changedUser) без этих данных. Данные теряются при переустановке, не синхронизируются между устройствами, невидимы партнёру. Плюс UX-рассинхрон: доп. информация сохраняется сразу, остальная форма — по кнопке «Сохранить». — нужно решение по персистентности. | edit_profile/widget/sphere_picker.dart:113-127; edit_profile/edit_profile_screen.dart:60-66,606-617 |
| П2 | FR5.2-3 | При первом обращении к источнику интерфейс вызывает системное разрешение на доступ к фото/камере. | Системный диалог вызывается неявно самим image_picker.pickImage (первое обращение — ок). Но отказ / «запрещено навсегда» проглатывается: try/catch пишет debugPrint и возвращает null; пользователю не показывается ни ошибка, ни переход в настройки ОС — при отказе просто «ничего не происходит». | profile/widget/profile_title.dart:25-73 |
Рекомендация / варианты решения
- Персистентность доп. информации (П1) — Вариант А (рекоменд.): после появления серверного контракта сохранять выбор в профиль (модель
User+ gRPC) и включить в общий поток «Сохранить». Вариант Б (временно): если фича остаётся локальной — явно зафиксировать ограничение в BRD и убрать мгновенное авто-сохранение в пользу единой кнопки «Сохранить». До этого FR5.2-6 по сути не реализован (данные в профиль не попадают). - Отказ в разрешении (П2) — Вариант А (рекоменд.): обрабатывать
denied/permanentlyDenied(черезpermission_handler) — показывать пояснение и кнопку «Открыть настройки». Вариант Б: минимум — снекбар при отказе вместо тихого проглатывания. Поведение при отказе задокументировать в BRD.