Назначение
Привязка существующего пользователя к identity provider (Keycloak, Bitrix24, AmmoCRM).
Цели
- Добавить связь UserIdentityEntity между пользователем и провайдером
- Обеспечить уникальность (Provider, ProviderUserId) глобально
- Не допустить дублирования связи пользователь–провайдер
Command: LinkUserIdentityCommand
Входные данные
| Поле | Тип | Обязательное | Описание |
|---|
| TenantId | Guid | Да | Идентификатор тенанта |
| UserId | Guid | Да | Идентификатор пользователя |
| Provider | IdentityProvider | Да | Keycloak, Bitrix24, AmmoCRM |
| ProviderUserId | string | Да | ID пользователя у провайдера |
| IdempotencyKey | Guid | Да | Ключ идемпотентности |
Result: LinkUserIdentityCommandResult
| Поле | Тип | Описание |
|---|
| UserIdentityId | Guid | Идентификатор созданной связи |
Валидация
- Пользователь должен существовать и принадлежать указанному TenantId
- (Provider, ProviderUserId) должны быть глобально уникальны — ошибка «Пользователь с таким ProviderUserId уже существует»
- У пользователя ещё не должно быть связи с этим Provider — ошибка «У пользователя уже есть связь с этим провайдером»
Бизнес-логика
- Acquire distributed lock
LinkUserIdentity_{Provider}_{ProviderUserId} (1 минута).
- Начать транзакцию (Serializable).
- Проверить существование пользователя и TenantId.
- Проверить, что (Provider, ProviderUserId) не заняты другим пользователем.
- Проверить, что у пользователя нет связи с этим Provider.
- Создать UserIdentityEntity.
- Publish AfterUserUpdatedNotification.
- Commit.
- Вернуть UserIdentityId.
События