# Идентификация пользователя в Android

Android SDK поддерживает два режима идентификации: автоматический и управляемый приложением.

## Стандарт CUID на основе телефона (`phone_hash`)

Рекомендуемый идентификатор пользователя для `LoginEvent` и `SignUpEvent` - SHA-256 хеш нормализованного мобильного телефона.

Правила формирования:

- перед хешированием номер очищается от всех символов, кроме цифр;
- для РФ и КЗ номер приводится к формату `7XXXXXXXXXX`;
- для других стран используется международный формат без `+` и разделителей;
- хеш считается по строке в UTF-8;
- результат передается в lowercase hex;
- в `cuidType` передается строка `"phone_hash"`.

Один и тот же идентификатор рекомендуется использовать во всех каналах: web, server-side API, offline import и mobile SDK.

## Автоматическая идентификация

Это поведение SDK по умолчанию. Если сервер вернул `uid` и `ses`, SDK сохраняет и переиспользует их. `uid` сохраняется в постоянном хранилище, `ses` — только в памяти процесса. При `Options(isReturnUserInfo = true)` SDK запрашивает объект `user`; без него идентификаторы обновятся только если сервер всё равно вернул `user`.

Это означает:

- неавторизованный пользователь идентифицируется SDK автоматически;
- `uid` и `ses` не нужно передавать вручную, если вы используете SDK-managed режим;
- после логина рекомендуется отправить `LoginEvent`, чтобы связать анонимный и авторизованный профили.

## Ограничение setUser

Если приложение уже управляет идентификатором пользователя и сессии, можно задать их явно.

Пример:

```kotlin
GravitySDK.instance.setUser(
    userId = "user-from-my-system-42",
    sessionId = "session-from-my-system-xyz",
)
```

`userId` записывается в `user.custom`, `sessionId` — в `user.ses`. Это внешний ID приложения, а не подмена `user.uid`.

**Ограничение 1.0.4:** установленный пользователь передаётся только в `/visit` и `/event`. Публичные методы загрузки контента вызывают repository без `customerUser`, поэтому `/choose` продолжает использовать сохранённые SDK `uid`/`ses`. Для единой идентификации просмотров, событий и контента используйте автоматический режим с `LoginEvent`.

## Выход и смена аккаунта

В публичном API нет `logout`, `resetUser` или `setUser(null)`. Повторная инициализация SDK не очищает singleton repository и его кэш идентификаторов. Если нужен полный сброс профиля при смене аккаунта, согласуйте сценарий интеграции.

## Вход в систему (`LoginEvent`)

```kotlin
val loginEvent = LoginEvent(
    cuid = sha256Hex(normalizePhone(rawPhoneNumber)),
    cuidType = "phone_hash",
)
```

Поле `hashedEmail` опционально. Если email не является обязательным в вашем процессе регистрации или логина, его можно не передавать.

Для `LoginEvent` рекомендуется использовать единый идентификатор `phone_hash`. Если проект использует другой `cuid`, он должен быть согласован и одинаково использоваться во всех каналах интеграции.
Отправляйте login/signup после успешной авторизации, с тем же CUID, что в других каналах. [Как отправлять события](./events.md).
