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

CreateUserCommand

Назначение

Создание пользователя. Поддерживает два режима: создание через Keycloak (saga) или с готовыми UserIdentities (Bitrix24, AmmoCRM).

Цели

  • Создание пользователя в БД
  • Назначение ролей
  • Привязка identity providers (если переданы)
  • Запуск CreateEmployee Saga (если UserIdentities пусты — создание через Keycloak)
  • Публикация AfterUserCreated через Outbox

Command: CreateUserCommand

Входные данные

ПолеТипОбязательноеОписание
TenantIdGuidДаИдентификатор тенанта
EmailstringДаEmail
PhoneNumberstring?НетТелефон
NameFullNameДаФИО
UserIdentitiesIReadOnlyCollection<ProviderIdPairDomainModel>?НетProvider + ProviderUserId. Если пусто — пользователь создаётся через Keycloak (saga)
RoleIdsIReadOnlyCollection<long>ДаИдентификаторы ролей
IdempotencyKeyGuidДаКлюч идемпотентности

ProviderIdPairDomainModel

ПолеТипОписание
ProviderIdentityProviderKeycloak, Bitrix24, AmmoCRM
ProviderUserIdstringID пользователя у провайдера

Result: CreateUserCommandResult

ПолеТипОписание
UserIdGuidИдентификатор созданного пользователя

Валидация

  • Тенант должен существовать
  • UserIdentities не должны содержать Keycloak (для Keycloak используется saga)
  • Email уникален глобально (не только в рамках TenantId)
  • Каждый (Provider, ProviderUserId) уникален глобально
  • Все RoleIds должны существовать
  • При пустых UserIdentities создаётся saga CreateEmployee (CreateKeycloakUser → UpdateUserKeycloakId)

Бизнес-логика

  1. Проверить существование тенанта.
  2. Если UserIdentities содержит Keycloak — ошибка.
  3. Начать транзакцию (Serializable).
  4. Проверить уникальность Email (FindBy Email).
  5. SetTenantContext(request.TenantId).
  6. Для каждого UserIdentity проверить уникальность (Provider, ProviderUserId).
  7. ValidateAndGetRoleEntities — проверить, что все RoleIds существуют.
  8. Создать UserEntity (Status = Pending).
  9. Если UserIdentities не пусты — создать UserIdentityEntity для каждого.
  10. Создать UserRoleReferenceEntity для каждой роли.
  11. Создать CreateEmployeeSaga (CreateKeycloakUser, UpdateUserKeycloakId) в SagaOutbox.
  12. Publish AfterUserCreatedNotification.
  13. Commit.
  14. Вернуть UserId.

События

  • AfterUserCreatedNotification — публикуется после commit. Handler формирует AfterUserCreatedEvent и записывает в Outbox.
  • CreateEmployee Saga — создаётся в Outbox, выполняется асинхронно (CreateKeycloakUser, UpdateUserKeycloakId).