Направление работ: AdmLk
Код раздела: 1.1
Раздел: Вход
Статус: черновик
Ответственный: Панкова Л.А. Версия: 0.1
Обновлено: 15.07.26


1. Назначение

Раздел описывает вход пользователя в сервисную зону МАРТ по email или телефону и паролю.

Интерфейс должен проверить учетные данные, показать ошибку при неуспешном входе или открыть сервисную зону при наличии доступа.

2. Ключевые понятия

Вход в сервисную зону — сценарий доступа пользователя в AdmLk по учетным данным аккаунта.

Учетные данные — email или телефон и пароль пользователя.

Сервисная зона — зона управления системой и глобальными настройками.

3. Scope

Входит

S1. Форма входа.

S2. Отправка учетных данных.

S3. Ошибки входа и отсутствия доступа.

Не входит

  • Back 1.1.2 — вход в систему.
  • Back 1.2 — проверка доступа к сервисной зоне.
  • AdmLk 1.2 — главная страница после входа.
  • AdmLk 3.7 — сотрудники и доступ к сервисной зоне.

4. BR

Указаны в Back 1.1.2 «Вход в систему» и Back 1.2 «Организация доступа к системе».

5. Функциональные требования

IDСценарийФункциональное требованиеBRВесСтатус
FR1.1-1S1. Пользователь открывает входИнтерфейс показывает поля «Email или телефон» и «Пароль», а также кнопку «Продолжить».1Реализовано
FR1.1-2S1. Пользователь заполняет формуИнтерфейс принимает email или телефон, маскирует пароль и позволяет показать или скрыть пароль.1Реализовано
FR1.1-3S2. Пользователь отправляет данныеИнтерфейс активирует «Продолжить» после заполнения обязательных полей и отправляет учетные данные на проверку.1Частично \ #OQ1.1-8
FR1.1-4S2. Вход выполнен успешноИнтерфейс открывает сервисную зону, если учетные данные верны и у пользователя есть доступ.1Частично \ #OQ1.1-6
FR1.1-5S3. Данные неверныеИнтерфейс показывает ошибку «Неверный логин или пароль» и позволяет исправить учетные данные.1Частично \ #OQ1.1-5
FR1.1-6S3. Доступ отсутствуетИнтерфейс показывает ошибку «Вход не выполнен. Отсутствует доступ» и кнопку «Войти в другой аккаунт».1Не реализовано \ #OQ1.1-2
FR1.1-7S3. Пользователь выбирает другой аккаунтИнтерфейс возвращает пользователя к форме входа для ввода других учетных данных.2Не реализовано \ #OQ1.1-3

6. Открытые вопросы

IDИсточникВопросКомуСтатусРекомендацииИтоговое решение
#OQ1.1-1Figma / Back \ Код вне BRDДолжен ли AdmLk поддерживать восстановление пароля со страницы входа или сценарий вынесен за рамки текущего раздела? По коду: уже реализовано — на форме есть кнопка «Забыл пароль» → /auth/password-recovery, присутствует полный сценарий восстановления. \ LoginForm.vue:51-58; features/auth-password-recovery; AuthService.ts:85-112Бизнес (Герман)OpenВопрос из стадии A снят наполовину: код отвечает «поддерживается». Осталось продуктовое решение. (А, рекоменд.) закрыть вопрос как «поддерживается» и добавить требование на «Забыл пароль» в scope 1.1; (Б) если восстановление не должно жить в сервисном кабинете — скрыть кнопку и явно вынести за скоуп.Артем: по коду еще нормально не реализовано. Весь раздел в любом случае нужно будет переписывать, перенося наработки Кости. Восстановление пароля я бы оставил.
#OQ1.1-2Код FR1.1-6Требование говорит: при отсутствии доступа показать «Вход не выполнен. Отсутствует доступ» и кнопку «Войти в другой аккаунт». В коде сценария нет вообще: при успехе всегда редирект на /, при любой ошибке — только «Неверный логин или пароль»; состояние «нет доступа» не различается. \ useAuthLogin.ts:16-33 (поиск по «Отсутствует доступ»/«Войти в другой» — совпадений нет)Бизнес/РазработкаOpenТребование веса 1 не реализовано; «нет доступа» неотличим от «неверный пароль». Механика упирается в контракт: согласовать с Back: 1.2, возвращает ли бэкенд отдельный код отказа по доступу. (А, рекоменд.) бэкенд даёт код отказа → фронт показывает экран «Отсутствует доступ» + «Войти в другой аккаунт»; (Б) если отказ по доступу на этом этапе невозможен — зафиксировать в BRD, что FR1.1-6/FR1.1-7 вне текущей реализации, и снять вес 1. Связать с OQ1.1-3, OQ1.1-5.Артем: весь вход был сделан еще до моего прихода, его в любом случае переписывать, так что я бы на него не ориентировался. Зачем нужна отдельная кнопка “Войти в другой аккаунт” я не понимаю - по сути мы еще ни в один не вошли. Выглядит, как лишний отвлекающий визуальный мусор. Я бы оставил только предупреждение “Вход не выполнен. Отсутствует доступ”
#OQ1.1-3Код FR1.1-7Требование говорит: «Войти в другой аккаунт» возвращает пользователя к форме входа. В коде кнопки и перехода нет — зависит от отсутствующего экрана отказа (см. OQ1.1-2); отдельный механизм выхода существует, но с экраном отказа не связан. \ features/auth-logout/model (поиск по «Войти в другой» — совпадений нет)Бизнес/РазработкаOpenПроизводная от OQ1.1-2 — без экрана отказа кнопке негде жить. Рекомендация: при реализации переиспользовать features/auth-logout (кнопка = выход + возврат к форме). Решается вместе с OQ1.1-2.Артем: см. предыдущий пункт. Если сделать отдельное отображение кнопки, которое будет возвращать обратно, то это абсолютно бессмысленное принуждение пользователя кликать на кнопку после каждой неудачной попытки. По мне, сообщения с ошибкой достаточно.
#OQ1.1-4Код вне BRDЧто нашли: на форме входа есть кнопка «Регистрация» → /auth/registration, а весь вход построен на партнёрском сценарии (эндпоинт LoginPartner). В BRD 1.1 саморегистрация не описана. \ LoginForm.vue:42-49; server/api/auth/login.post.ts:25Бизнес (Герман)OpenЭкран входа переиспользован из партнёрского кабинета. Решение бизнеса: нужна ли кнопка «Регистрация» в сервисной зоне (доступ туда выдаётся через AdmLk 3.7 / Back 8.1, а не самозаписью). (А, рекоменд.) убрать кнопку и вынести саморегистрацию за скоуп; (Б) если нужна — внести требованием. Контракт партнёрского входа — отдельный вопрос OQ1.1-9.Артем: реализация раздела черновая. Считаю, что кнопку стоит убрать.
#OQ1.1-5Код FR1.1-5Требование говорит: показать «Неверный логин или пароль» и дать исправить данные. В коде текст верен для неверных данных, но захардкожен на ЛЮБУЮ ошибку: сервер маппит все не-OK ответы в это сообщение, а форма игнорирует реальный текст ошибки — сеть, сбой сервера и «нет доступа» тоже показываются как «Неверный логин или пароль». \ LoginForm.vue:79-84; server/api/auth/login.post.ts:39-46РазработкаЗакрывает PMХардкод текста на любую ошибку — дефект, продуктового выбора нет (какой текст для отказа по доступу — решается в OQ1.1-2). Закрываю сам: пробрасывать реальный код/текст ошибки от бэкенда, «Неверный логин или пароль» показывать только для invalid-credentials, для сети/сервера — отдельный текст → тикет в Bitrix. Это же открывает механику для OQ1.1-2.Артем: реализация раздела черновая. Нужно переделать
#OQ1.1-6Код FR1.1-4Требование говорит: после верного входа открыть сервисную зону. В коде редирект на / есть, но auth_token ставится httpOnly, а проверки isAuthenticated/isTokenValid читают его через document.cookie — на клиенте всегда false, из-за чего глобальный middleware дёргает refresh-token на каждом переходе. \ login.post.ts:58,64; account.session.ts:21-27; AuthService.ts:159-163; auth.global.ts:34-49Разработка (Влад)OpenВход работает, но механика сессии на клиенте сломана — лишний refresh на каждом переходе. Выбор архитектурный. Вопрос к Владу: (А, рекоменд.) определять авторизацию по состоянию сессии / ответу /api/auth/account, а не по httpOnly-куке (её из JS не видно), либо добавить лёгкую не-httpOnly куку-флаг; (Б) оставить как есть, приняв refresh на каждом переходе как цену (хуже по производительности).Артем: реализация раздела черновая. Нужно переделать
#OQ1.1-7Код вне BRDЧто нашли: две точки входа на одну форму — /auth/authorization и /login (через отдельный widget на тот же LoginForm); в middleware публичен только /auth/authorization, а /login — нет, поэтому неавторизованного с /login редиректит прочь. Плюс два почти одинаковых middleware. \ pages/login.vue:1-7; widgets/auth-login/ui/AuthLoginWidget.vue:1-8; auth.global.ts:20-29; middleware/auth.ts:20-25РазработкаЗакрывает PMДубль маршрута с нерабочим поведением (/login недоступен неавторизованному — то есть тем, кому он и нужен), продуктового вопроса нет. Закрываю сам: оставить один маршрут /auth/authorization, удалить /login + widget (или сделать редирект), свести два middleware к одному → тикет в Bitrix.Артем: реализация раздела черновая. Нужно переделать
#OQ1.1-8Код FR1.1-3Требование говорит: активировать «Продолжить» после заполнения обязательных полей. В коде кнопка активна не по «заполненности», а по валидному формату email/телефона и паролю ≥ 4 символов; порог 4 расходится с PASSWORD_MIN_LENGTH=8 и схемой min(1) — три разных значения в одном проекте. \ LoginForm.vue:87-112; error-messages.ts:18; auth.schema.ts:28РазработкаЗакрывает PMГейт строже требования + рассинхрон порогов (4 / 8 / 1). Длину пароля на входе проверяет бэкенд, навязывать её форме незачем. Закрываю сам: гейтить кнопку по непустым полям, длину/сложность на входе не проверять; пороги, если нужны, вынести в конфиг и устранить рассинхрон → тикет в Bitrix.Артем: реализация раздела черновая. Нужно переделать
#OQ1.1-9Код вне BRDЧто нашли: вход сервисной зоны идёт через IdentityService/LoginPartner, тело запроса — fullPhoneNumber. То есть сервисный кабинет логинится партнёрским методом. \ server/api/auth/login.post.ts:20-25; AuthService.ts:16-24Разработка (Влад)OpenВопрос к Владу + Back: 1.1.2: верный ли это метод/контракт identity для сервисного кабинета. (А) подтвердить, что LoginPartner применим и для сервисной зоны; (Б) завести отдельный service-login контракт. Связано с OQ1.1-4 (экран переиспользован из партнёрского кабинета) и с OQ1.1-2 (где живёт отказ по доступу).Артем: считаю, что лучше добавить сервисный метод

Вопросы по сверке с кодом

BRD 1.1 v0.1 · musbooking.weblk.adminpanel · commit c376579/main · 2026-07-10 · якорь features/auth-login (+ pages/auth/authorization.vue, entities/account, shared/api/AuthService.ts, server/api/auth) Сводка: вопросов 9 (бизнесовых 4 / программных 5) · подтверждено без вопросов 2 (FR1.1-1, FR1.1-2) · отрезано находок обратного прохода 4 (фильтр кириллицы/пробелов в пароле, дропдаун кодов стран и международный формат телефона, выход из системы, перехватчик обновления токена) Под особым вниманием: FR1.1-6 / FR1.1-7 — сценарий «отсутствует доступ» в коде не реализован; FR1.1-4 — хранение токена/сессии на клиенте работает не так, как ожидается.

Бизнесовые

Связано сЧто в BRDЧто в кодеГде в коде
Б1FR1.1-6При отсутствии доступа показать «Вход не выполнен. Отсутствует доступ» и кнопку «Войти в другой аккаунт»Сценария нет: при успехе всегда редирект на /, при любой ошибке — только «Неверный логин или пароль»; состояние «нет доступа» не различается — нужно решение по UX отказа в доступеuseAuthLogin.ts:16-33; grep по «Отсутствует доступ»/«Войти в другой» — совпадений нет
Б2FR1.1-7«Войти в другой аккаунт» возвращает пользователя к форме входаКнопки и перехода нет (зависит от Б1); отдельный механизм выхода есть, но с экраном отказа не связанfeatures/auth-logout/model; grep по «Войти в другой» — совпадений нет
Б3OQ1.1-1Открытый вопрос: поддерживать ли восстановление пароля со страницы входаУже реализовано: на форме есть кнопка «Забыл пароль» → /auth/password-recovery, присутствует полный сценарий восстановления — нужно решение, оставляем ли в скоупе AdmLk 1.1LoginForm.vue:51-58; features/auth-password-recovery; AuthService.ts:85-112
Б4вне BRDНа форме входа есть кнопка «Регистрация» → /auth/registration, а весь вход построен на партнёрском сценарии (эндпоинт LoginPartner) — нужно решение, входит ли саморегистрация / партнёрский вход в сервисный кабинетLoginForm.vue:42-49; server/api/auth/login.post.ts:25

Рекомендация / варианты решения

  • Сценарий отсутствия доступа (Б1, Б2; механика — П1) — сейчас «нет доступа» неотличим от «неверный пароль». Вариант А (рекоменд.): бэкенд (Back 1.2) возвращает отдельный код отказа, фронт показывает экран «Отсутствует доступ» + «Войти в другой аккаунт» (кнопка = выход + возврат к форме, переиспользовать features/auth-logout). Вариант Б: если для сервисного кабинета отказ по доступу на этом этапе невозможен — зафиксировать в BRD, что FR1.1-6 / FR1.1-7 вне текущей реализации, и снять вес 1.
  • Восстановление пароля (Б3) — код уже поддерживает. Вариант А (рекоменд.): закрыть OQ1.1-1 как «поддерживается» и добавить требование на «Забыл пароль». Вариант Б: если восстановление не должно жить в сервисном кабинете — скрыть кнопку и явно вынести за скоуп.
  • Саморегистрация и партнёрский вход (Б4; контракт — П5) — экран входа переиспользован из партнёрского кабинета. Согласовать с продуктом: нужна ли кнопка «Регистрация» в сервисной зоне и корректен ли партнёрский identity-флоу; при отказе — убрать кнопку и уточнить контракт входа.

Программные

Связано сЧто в BRDЧто в кодеГде в коде
П1FR1.1-5Показать «Неверный логин или пароль» и дать исправить данныеТекст верен для неверных данных, но захардкожен на ЛЮБУЮ ошибку: сервер маппит все не-OK ответы в это сообщение, а форма игнорирует реальный текст ошибки — сеть/сервер/«нет доступа» тоже показываются как «Неверный логин или пароль»LoginForm.vue:79-84; server/api/auth/login.post.ts:39-46
П2FR1.1-4После верного входа открыть сервисную зонуРедирект на / есть, но auth_token ставится httpOnly, а isAuthenticated / isTokenValid читают его через document.cookie — на клиенте всегда false, из-за чего глобальный middleware дёргает refresh-token на каждом переходеlogin.post.ts:58,64; account.session.ts:21-27; AuthService.ts:159-163; auth.global.ts:34-49
П3вне BRDДве точки входа на одну форму: /auth/authorization (pages/auth) и /login (pages/login.vuewidgets/auth-login → тот же LoginForm); в middleware публичен только /auth/authorization, /login — нет, неавторизованного с /login редиректит прочь. Плюс два почти одинаковых middlewarepages/login.vue:1-7; widgets/auth-login/ui/AuthLoginWidget.vue:1-8; auth.global.ts:20-29; middleware/auth.ts:20-25
П4FR1.1-3Активировать «Продолжить» после заполнения обязательных полейКнопка активна не по «заполненности», а по валидному формату email/телефона и паролю ≥ 4 символов; порог 4 расходится с PASSWORD_MIN_LENGTH=8 и схемой min(1)LoginForm.vue:87-112; error-messages.ts:18; auth.schema.ts:28
П5вне BRDВход сервисной зоны идёт через IdentityService/LoginPartner, тело запроса — fullPhoneNumber; подтвердить, что это верный метод/контракт identity для сервисного кабинета (Back 1.1.2)server/api/auth/login.post.ts:20-25; AuthService.ts:16-24

Рекомендация / варианты решения

  • Разделение ошибок входа (П1; закрывает механику Б1) — Вариант А (рекоменд.): пробрасывать реальный код/текст ошибки от бэкенда и показывать «Неверный логин или пароль» только для invalid-credentials, «Отсутствует доступ» — для отказа по доступу, отдельный текст — для сети/сервера. Вариант Б (минимум): не хардкодить текст, а показывать фактический session.error.
  • Хранение токена/сессии на клиенте (П2) — Вариант А (рекоменд.): определять авторизацию по состоянию сессии / ответу /api/auth/account, а не по httpOnly-куке (её из JS не видно) — либо добавить лёгкую не-httpOnly куку-флаг. Вариант Б: оставить как есть, осознанно приняв refresh на каждом переходе как цену (хуже по производительности).
  • Дубли точек входа и middleware (П3) — Вариант А (рекоменд.): оставить один маршрут (/auth/authorization), удалить /login + widget или сделать из него редирект, свести два middleware к одному. Вариант Б: если /login нужен — добавить его в список публичных маршрутов.
  • Порог валидации кнопки (П4) — логину лучше не навязывать длину пароля (её проверяет бэкенд). Вариант А (рекоменд.): гейтить кнопку по непустым полям, длину/сложность на входе не проверять. Вариант Б: если формат-валидация нужна — вынести пороги в конфиг и устранить рассинхрон 4 / 8 / 1.
  • Контракт метода входа (П5) — подтвердить с бэкендом (Back 1.1.2), что LoginPartner — правильный метод для сервисной зоны; при необходимости завести отдельный service-login контракт.

0 items under this folder.