Перейти к основному содержимому

Сквозные сценарии

Зачем нужно

Документ описывает основные пользовательские, админские и системные сценарии identity от начала до конца. Если сценарий не описан здесь или в дочерней спецификации, его нельзя считать согласованным.

Регистрация пользователя

  1. Пользователь вводит email или phone.
  2. Система проверяет, нет ли активного аккаунта с этим контактом.
  3. Пользователь задаёт пароль. Пароль обязателен всегда.
  4. Система создаёт user, user_credentials, первичный контакт и auth method password.
  5. Если включена верификация контакта, создаётся verification_code и отправляется через transport.
  6. После подтверждения контакта is_verified = true.
  7. Создаётся user_session, выдаются access и refresh tokens.
  8. Публикуются события identity.user.registered, identity.user.created, identity.login.succeeded.

Вход по паролю

  1. Пользователь вводит email/phone и пароль.
  2. Система создаёт или обновляет auth_flow_session.
  3. Проверяется rate limit по identifier, IP и user.
  4. Проверяется пароль.
  5. Если включён MFA или другой mandatory step, flow переходит на следующий шаг.
  6. После успешного завершения создаётся session и выдаются токены.
  7. Неудачные попытки пишутся в audit и участвуют в brute-force защите.

Вход по OTP

  1. Пользователь вводит email/phone.
  2. Система проверяет, разрешён ли OTP для этого identifier и tenant/platform settings.
  3. Создаётся verification_code с purpose login.
  4. Код отправляется через email/SMS transport.
  5. Пользователь вводит код.
  6. Система проверяет hash, срок жизни и attempts.
  7. После успешной проверки создаётся session.

OAuth-вход через внешнего провайдера

  1. Пользователь выбирает provider.
  2. Система создаёт provider authorization request.
  3. Provider возвращает callback.
  4. Система получает provider profile.
  5. Если external identity уже привязана, пользователь входит.
  6. Если email совпал и email_verified = true, identity может быть привязана автоматически.
  7. Если верификация provider недостаточна, система показывает экран подтверждения.
  8. Действие пишется в audit.

Refresh token rotation

  1. Клиент отправляет refresh token.
  2. Система ищет hash текущего token в active session.
  3. Если token валиден, старый hash помечается rotated, создаётся новый refresh token.
  4. Если старый refresh token использован повторно, вся token family отзывается.
  5. Пользовательские сессии получают событие security anomaly.

Logout

Logout текущей сессии

  1. Клиент вызывает logout.
  2. Текущая user_session получает revoked_at.
  3. Refresh token становится недействительным.
  4. Access token живёт до истечения срока или проверяется через session version, если включено.

Logout всех устройств

  1. Пользователь подтверждает действие.
  2. Все active sessions пользователя отзываются.
  3. В audit пишется security action.
  4. Пользователь получает уведомление.

Сброс пароля

  1. Пользователь вводит email/phone.
  2. Система всегда отвечает нейтрально, не раскрывая наличие аккаунта.
  3. Если аккаунт найден, создаётся verification_code purpose reset_password.
  4. Пользователь открывает ссылку или вводит код.
  5. Система проверяет код.
  6. Пользователь задаёт новый пароль.
  7. Все или выбранные sessions отзываются по policy.
  8. Пишется audit и отправляется уведомление.

Смена пароля из кабинета

  1. Пользователь вводит текущий пароль.
  2. Система проверяет re-auth requirement.
  3. Новый пароль валидируется по policy.
  4. password_hash обновляется.
  5. Старые sessions отзываются по policy.
  6. Пишется audit.

Преподавательская анкета и Learning Workspace

Самозаявленный преподаватель заполняет Educator Profile

  1. Пользователь входит в систему.
  2. Открывает educator_profile.
  3. Указывает рабочие контакты, предметы, классы и заявленную организацию.
  4. Система сохраняет анкету со статусом self_declared или under_review.
  5. Пользователь может открыть Learning Workspace, создать свои рабочие группы и работать со своими учениками в LMS.
  6. Identity не создаёт глобальную роль teacher и не выдаёт organization membership.
  7. Доступ к чужим группам, официальной статистике организации и официальному organization contour остаётся закрытым до отдельного membership/assignment/grant/product permission.

Проверка Educator Profile

  1. Администратор открывает список анкет на проверку.
  2. Проверяет контакты, предметы, классы, заявленную организацию и evidence.
  3. Проставляет trust status.
  4. Система пишет audit.
  5. Даже verified trust status не выдаёт права сам по себе.

Семейный доступ

Создание семьи

  1. Взрослый пользователь создаёт family group.
  2. Он получает роль adult.
  3. Добавляет ребёнка как student_profile.
  4. При необходимости привязывает existing user ребёнка или создаёт новый user для самостоятельного входа.
  5. Linked user ребёнка сохраняет обычные self-права в MVP.

Добавление взрослого

  1. Active adult создаёт приглашение.
  2. UI показывает предупреждение: новый adult получит доступ ко всем детям семьи, но не к данным других взрослых.
  3. Приглашённый пользователь принимает ссылку или код.
  4. Система создаёт user_family_group с role = adult.
  5. Audit фиксирует создание и принятие приглашения.

Родительский режим управления ребёнком

  1. Взрослый открывает профиль конкретного ребёнка.
  2. Система проверяет active adult membership и принадлежность student_profile этой семье.
  3. Взрослый читает прогресс, календарь, занятия, домашние задания и ключевые статусы ребёнка.
  4. Взрослый может редактировать семейно-управляемые поля ребёнка, покупать продукт для ребёнка, записывать ребёнка на программу и настраивать уведомления по ребёнку.
  5. Взрослый не получает доступ к прогрессу, календарю, профилю, покупкам, уведомлениям и учебному контексту другого взрослого.

Детский режим через delegated session

  1. Взрослый выбирает ребёнка.
  2. Система проверяет active adult membership и принадлежность student_profile семье.
  3. Создаётся delegated_session по обязательному studentProfileId.
  4. В downstream service передаётся actor context: actor_user_id, subject_student_profile_id, optional subject_user_id, family_group_id.
  5. Все действия пишутся в audit с обоими идентификаторами.
  6. delegated_session не создаёт сессию ребёнка на другом устройстве.

Авторизация ребёнка на устройстве

  1. На устройстве ребёнка начинается вход в linked user аккаунт ребёнка.
  2. Система показывает QR-код или короткий одноразовый код.
  3. Взрослый входит в свой аккаунт и подтверждает запрос.
  4. Система проверяет active adult membership и принадлежность student_profile этой семье.
  5. Если у ребёнка есть linked_user_id, на устройстве ребёнка создаётся user_session ребёнка.
  6. Audit фиксирует adult approver, studentProfileId, child user, устройство и срок действия.
  7. Взрослый не переходит в детский контекст.

Если student_profile не имеет linked_user_id, device authorization в MVP невозможна без предварительного создания или привязки user.

Родитель регистрирует ребёнка на олимпиаду

  1. Взрослый действует в родительском режиме.
  2. Система проверяет family membership и право управлять ребёнком.
  3. Competitions создаёт регистрацию ребёнка.
  4. Родительский режим остаётся родительским: взрослый не становится ребёнком.
  5. Когда начинается прохождение олимпиады, ребёнок открывает детский режим через linked user или явно разрешённый delegated/session flow.
  6. Audit фиксирует adult actor и child subject, если прохождение открыто через delegated session.

Организации

Пользователь создаёт новую организацию

  1. Пользователь входит в систему.
  2. Выбирает страну.
  3. Если страна — Россия, выбирает регион.
  4. Указывает населённый пункт.
  5. Вводит название организации.
  6. Система показывает organization_reference и уже созданные похожие organization.
  7. Пользователь выбирает существующую организацию или создаёт новую.
  8. Если похожесть высокая, новая организация получает duplicate_status = possible_duplicate.
  9. Создаётся organization и membership со статусом по выбранному flow.
  10. Если организация требует подтверждения владения, пользователь подаёт ownership claim.

Пользователь вступает в существующую организацию по заявке

  1. Пользователь находит организацию.
  2. Отправляет membership request.
  3. Владелец или администратор видит заявку.
  4. Владелец или администратор подтверждает или отклоняет заявку.
  5. При подтверждении membership становится active, назначается роль.
  6. Публикуется identity.organization_membership.activated.

Пользователь вступает по приглашению

  1. Владелец или администратор создаёт organization_invitation с delivery channel link, email, cabinet или sms.
  2. Пользователь получает ссылку, email/SMS или notification в кабинете.
  3. Пользователь принимает invitation.
  4. Система создаёт или активирует membership.
  5. Пользователь получает роль, указанную в invitation.
  6. Повторное принятие уже accepted invitation идемпотентно.

Пользователь запрашивает владение существующей организацией

  1. Пользователь находит organization со статусом unclaimed или спорным контекстом.
  2. Заполняет данные для проверки: ФИО, должность/связь, evidence links, комментарий.
  3. Создаётся organization_ownership_claim.
  4. Администратор «Систематики» рассматривает заявку.
  5. При одобрении создаётся или активируется membership.
  6. Membership получает owner role, organization получает owner_membership_id.
  7. При споре organization переводится в disputed.

Владелец передаёт владение

  1. Владелец выбирает active member или вводит email будущего владельца.
  2. Система создаёт organization_ownership_transfer.
  3. Получатель подтверждает переход.
  4. Система меняет owner_membership_id.
  5. Старый владелец получает новую роль по transfer policy.
  6. Действие фиксируется в audit.

Пользователь добавляет ученика организации

  1. Пользователь открывает список учеников организации.
  2. Система проверяет active membership и permission identity.organization-students.create.organization.
  3. Пользователь вводит ФИО, класс и букву класса.
  4. Система ищет дублей внутри организации.
  5. Если найден дубль, пользователь выбирает существующую запись или создаёт новую с duplicate_note.
  6. Создаётся organization_student.
  7. Событие identity.organization_student.created доступно competitions и management.

Правило: organization_student используется только для официального или подтверждённого организационного контура. Рабочий ученик преподавателя без официального organization flow создаётся как learning_group_participant в LMS, а не как organization_student.

Администратор «Систематики» склеивает организации

  1. Администратор открывает карточку возможного дубля.
  2. Выбирает primary organization и duplicate organization.
  3. Система показывает impact preview: участники, ученики, команды, grants, product refs.
  4. Администратор подтверждает merge.
  5. Связи переносятся или помечаются для downstream update.
  6. Duplicate organization получает status merged и merged_into_organization_id.
  7. Публикуется identity.organization.merged.

Назначение роли

  1. Администратор открывает карточку пользователя.
  2. Система показывает только роли, которые администратор имеет право назначать.
  3. Администратор выбирает роль и scope.
  4. Сервер проверяет permission identity.roles.assign.
  5. Создаётся user_role_assignment.
  6. Пишется audit и публикуется event.

OAuth Authorization Code + PKCE

  1. Client отправляет authorize request.
  2. Система проверяет client_id, redirect URI, response type, scopes и PKCE challenge.
  3. Если пользователь не вошёл, запускается auth flow.
  4. Если нужен consent, показывается consent screen.
  5. Система создаёт authorization code.
  6. Client обменивает code на tokens.
  7. Система проверяет PKCE verifier и выдаёт id/access/refresh tokens.

Плагинный сценарий auth method

  1. Администратор устанавливает plugin с типом auth_method.
  2. Manifest валидируется.
  3. Controller загружается в sandbox.
  4. Settings сохраняются в БД, secrets шифруются.
  5. Auth flow получает новый step.
  6. При входе plugin вызывается через контролируемый contract.

Нестандартные случаи

  • пользователь регистрируется с email, уже привязанным через OAuth;
  • provider отдаёт email без verified-флага;
  • refresh token используется повторно после rotation;
  • родитель потерял связь с ребёнком во время delegated session;
  • пользователь состоит в нескольких организациях;
  • самозаявленный преподаватель указал организацию, но не имеет active membership;
  • преподаватель пытается открыть чужую рабочую группу через одну только анкету;
  • рабочий ученик преподавателя ошибочно добавляется в organization_student без официального organization flow;
  • роль истекла, пока пользователь держит открытую админку;
  • plugin transport не отвечает при отправке OTP;
  • clock skew ломает проверку OAuth code или JWT;
  • пользователь удалён или заблокирован, но внешний сервис держит старый token.

Готовность

  • каждый сценарий имеет серверные проверки, audit и события;
  • успешные и неуспешные ветки описаны;
  • actor context не теряется в family/organization сценариях;
  • Learning Workspace не превращается в отдельный identity scope;
  • educator_profile не используется как источник прав;
  • OAuth flow соответствует OIDC/PKCE требованиям;
  • plugin flow не даёт обходить security policies.