Старый
POST /auth/state удалён (404).Источник правды API (Scribe)
После мержа и выката бэкенда на staging документация REST — Scribe.
Эндпоинты в Scribe: Check account state before login, Check account state before register, Login user, Register user (и связанные register SMS).
Раздаточный md для фронта не заменяет Scribe: в md — флоу и чеклист; схемы и примеры 200/401/422 — со staging docs.
Ломающие изменения относительно старого плана / старого фронта
- 1.Один URL больше не используется. Было
POST /api/v1/auth/state. Стало:- •экран
/login→POST /api/v1/auth/state/login - •экран
/register→POST /api/v1/auth/state/register
Сценарий задаётся URL. - 2.
data.status→data.state. Типы, свитчи, Zod/TS, разбор JSON — читатьstate. То же для ответа регистрации продавца без токена (sms_requiredнаPOST /auth/register/user): там тожеstate, неstatus. - 3.
role_mismatch— единственное отличие двух методов. Значениеstateодно и то же. Меняютсяmessage,next_actionиactions:- •
/auth/state/register— можно регистрировать новую роль (next_action=register); - •
/auth/state/login— не логинить (next_action=contact_support).
Остальныеstateна login и register ведут себя одинаково. - 4.Регистрацию слать только если проверка была
/auth/state/registerиstate∈ {account_not_found,role_mismatch}.
1. Зачем эндпоинты
Перед логином или регистрацией фронт спрашивает: что делать со связкой роль + телефон + email (+ ИНН). Бэкенд не логинит и не регистрирует.
Ветвиться по:
- •
data.state - •какой URL вызывали (login vs register) — обязательно для
role_mismatch
Показывать
data.message как есть. Кнопки — data.actions, главная = data.next_action.2. Когда вызывать
- •
/register— после валидации формы, доPOST /auth/register/userилиPOST /auth/register/organization→POST /auth/state/register - •
/login— после роли / телефона / email, доPOST /auth/login→POST /auth/state/login
3. Запрос
Заголовки:
Accept: application/json, Content-Type: application/json, Accept-Language: ru.Тело одинаковое для обоих URL:
- •
role(обязательно) —private-person|private-broker|estate-agent|estate-representative|builder|director|supervisor|mentor|realtor|lawyer|administrator - •
phone(обязательно, до 25 символов) - •
email(обязательно) - •
inn(необязательно, до 12 символов)
ИНН: роли, которые заводят компанию —
builder, estate-representative. Остальные с ИНН вступают в существующую.422 — битые
role / email / длина phone/inn. Ошибка формы, не бизнес-state. Поля починить, ответ state не интерпретировать.4. Ответ 200 (/auth/state/*)
Оболочка:
JSON
{ "success": true, "data": { "state": "account_not_found", "next_action": "register", "message": "Учётная запись не найдена — пройдите регистрацию.", "actions": [{ "code": "register", "label": "Пройти регистрацию" }] }, "error": null, "message": "Success" }
Правила:
- •Показать
data.message. - •Первая кнопка =
data.next_action=data.actions[0].code.labelне хардкодить. - •«Изменить данные» — локально на форме, бэкенд не присылает.
POST /auth/login при 401 кладёт тот же payload в data (state, next_action, message, actions). Для продавца без SMS ещё reason: phone_not_confirmed при state: sms_required.5. Flow

Mermaid
flowchart TD form[Форма логина или регистрации] which{Какой экран?} loginCall["POST /auth/state/login"] registerCall["POST /auth/state/register"] v422[422: починить поля] loginState{data.state} registerState{data.state} form --> which which -->|/login| loginCall which -->|/register| registerCall loginCall -->|422| v422 registerCall -->|422| v422 loginCall -->|200| loginState registerCall -->|200| registerState loginState -->|account_not_found| goRegLogin["Увести на /register"] loginState -->|role_mismatch| mailLogin["mailto поддержки, не логинить"] loginState -->|account_active / employee_already_exists| doLogin["POST /auth/login"] loginState -->|credentials_mismatch| goReset["/login/reset"] loginState -->|sms_required| goSms[Модалка SMS] loginState -->|pending_admin| wait[Сообщение, ждать] loginState -->|blocked / deleted / company / org_inactive| mailLogin registerState -->|account_not_found| doReg["POST /auth/register/user или organization"] registerState -->|role_mismatch| doRegNewRole["Регистрация новой роли"] registerState -->|остальное| panel["Панель, next_action, не слать register"]
Ключевое отличие — какой URL вызвали:
- •
/auth/state/register+role_mismatch→ можно регистрировать новую роль (next_action=register). - •
/auth/state/login+role_mismatch→ не логинить (next_action=contact_support).
Регистрацию (
/auth/register/user | organization) разрешаем только при:- •
account_not_foundпосле/auth/state/register - •
role_mismatchпосле/auth/state/register
Иначе на
/register register-эндпоинты не вызывать.6. Состояния: что делать фронту
Страницы:
/login, /register, /login/reset, SMS-модалка, mailto:ette.site@gmail.com.Тексты
message и actions[].label — с бэкенда / из Scribe, не копировать в хардкод навечно.Актуальные русские формулировки (бэкенд
AuthStateService::definition):- •
account_active— «Такая учётная запись уже есть — войдите или восстановите пароль.» - •
employee_already_exists— «Такой сотрудник уже добавлен — войдите или восстановите пароль.» - •
pending_admin— «Заявка уже отправлена и ждёт подтверждения администратора.» - •
account_deleted— «Учётная запись удалена — для восстановления обратитесь в поддержку ETTE.» - •
account_blocked— «Учётная запись заблокирована — обратитесь в поддержку ETTE.» - •
company_already_registered— «Компания с этим ИНН уже зарегистрирована — обратитесь в поддержку ETTE.» - •
organization_inactive— «Доступ организации временно ограничен — обратитесь в поддержку ETTE.» - •
role_mismatch+ register — «Учётная запись найдена — продолжаем регистрацию новой роли.» - •
role_mismatch+ login — «Для этой роли учётная запись не найдена — обратитесь в поддержку ETTE.» - •
credentials_mismatch— «Введённые данные не совпадают — восстановите пароль или обратитесь в поддержку.» - •
account_not_found— «Учётная запись не найдена — пройдите регистрацию.» - •
sms_required— «Введите код из SMS для подтверждения телефона.»
Коды кнопок:
login → /login; register → submit на /register или переход /register; reset_password → /login/reset; enter_sms → модалка; wait_for_admin → закрыть панель; contact_support / restore_account → mailto.7. cURL (Postman)
База staging:
https://staging-api.ette.ru/api/v1. Локально: http://localhost:8099/api/v1.Import → Raw text.
Регистрация:
Bash
curl --request POST 'https://staging-api.ette.ru/api/v1/auth/state/register' \ --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --header 'Accept-Language: ru' \ --data '{ "role": "private-person", "phone": "+79120000001", "email": "new-user@example.com" }'
Ожидание на новых данных:
state=account_not_found, next_action=register.Вход — тот же JSON на
.../auth/state/login. На новых данных тоже account_not_found (на логине это «идите регистрироваться»).422: битая
role / без email.Остальные
state нуждаются в записи в БД; шаблоны с {{phone}} / {{email}} / {{inn}} — в спеке .cursor/specs/2026-09-10-auth-state-design.md.8. Чеклист фронта
- •Вызовы: login-экран →
/auth/state/login, register-экран →/auth/state/register. УдалитьPOST /auth/state. - •Везде
data.state, неdata.status(включая ответsms_requiredс/auth/register/user). - •Для
role_mismatchсмотреть, какой метод вызывали: register — слать регистрацию новой роли; login — не логинить, взять кнопку изactions. - •Register API только после
/auth/state/registerиaccount_not_found|role_mismatch. - •Кнопки и подписи из
actions. - •Сверить примеры с staging docs после выката.
- •Обновить
ette_frontend/docs/(отдельным шагом после кода).