8.2 KiB
HAN Chat Mobile
Мобильный клиент HAN Chat на Expo SDK 57. Текущая версия приложения — 1.0.1,
native identity — Android versionCode: 2 и iOS buildNumber: 2.
Подготовка
-
Установить Node.js и npm.
-
Скопировать
.env.exampleв.envи указать адреса API и Keycloak. -
Установить зависимости:
npm install -
Зарегистрировать
han-chat://auth/callbackкак допустимый redirect URI клиента Keycloak.
Локальные проверки
npm run typecheck
npm test
Запуск приложения выполняется отдельно командой npm run android. Проект использует managed Expo workflow и не хранит каталоги android/ и ios/.
Store-only обновления
Приложение не загружает JS/asset OTA-обновления. Оно читает mobile_update из
GET /api/v1/public/app-config и отправляет пользователя в магазин своей сборки.
Канал фиксируется на этапе EAS build:
EXPO_PUBLIC_DISTRIBUTION_STORE=google_play;EXPO_PUBLIC_DISTRIBUTION_STORE=rustore;EXPO_PUBLIC_DISTRIBUTION_STORE=app_store.
Неизвестное или отсутствующее значение отключает механику. Поэтому профили
development и preview имеют значение disabled. Профиль
preview-rustore намеренно задаёт rustore, чтобы проверять update policy на
внутреннем APK через dev-backend.
Решение принимается только по целому native build:
- build ниже
minimum_build— обязательное (force) обновление; - build ниже
latest_build, но не ниже minimum — мягкое (soft) обновление; - build не ниже latest — обновление не показывается.
Soft-карточку можно закрыть; выбор запоминается в SecureStore отдельно для пары
канал + latest_build. Force-карточка блокирует Android Back и не имеет способов
закрытия. Проверка выполняется на холодном старте и при возврате в foreground,
параллельные проверки объединяются. Сетевая ошибка, невалидный build или
недоверенный URL работают fail-open и не блокируют интерфейс.
Допускаются только HTTPS-ссылки соответствующего магазина:
play.google.com/store/apps/details?id=ru.han.chat,
www.rustore.ru/catalog/app/ru.han.chat и App Store URL на apps.apple.com с Apple ID.
Сборка (EAS)
Профили заданы в eas.json. Env для билда берётся из профиля (eas.json → env), а не из локального .env.
| Профиль | Артефакт | API | EXPO_PUBLIC_APP_ENV |
|---|---|---|---|
preview |
APK (внутренняя установка) | dev-chat.han0107.ru |
update policy отключена |
preview-rustore |
APK (тест RuStore policy) | dev-chat.han0107.ru |
rustore |
google-play |
AAB (Google Play) | chat.han0107.ru |
google_play |
rustore |
AAB (RuStore) | chat.han0107.ru |
rustore |
app-store |
iOS App Store | chat.han0107.ru |
app_store |
development |
Dev Client | из окружения/локально | update policy отключена |
Один раз: вход в Expo
cd C:\Users\MI\Documents\Assistent\HAN_chat_specification\VM4_Expo-mobile
npx eas-cli login
npx eas-cli whoami
Проект уже привязан (owner: anzh, projectId в app.config.ts). Android keystore хранится remote на Expo.
Перед сборкой (рекомендуется)
npm run typecheck
npm test
Preview — APK на телефон
npx eas-cli build --profile preview --platform android
После успеха откройте ссылку из вывода CLI (или https://expo.dev/accounts/anzh/projects/han-chat/builds) и скачайте APK.
Preview RuStore — проверка soft/force update
npx eas-cli build:version:get --platform android --profile preview-rustore
npx eas-cli build --profile preview-rustore --platform android
Профиль использует dev API и встраивает канал rustore, но не увеличивает общий
remote Android versionCode (autoIncrement: false). Запишите build из
build:version:get или карточки завершённой сборки. Для build B настройте
политику RuStore на dev-backend:
- soft:
latest_build=B+1,minimum_build<=B; - force:
latest_build=B+1,minimum_build=B+1; - none:
latest_build<=B.
После изменения dev settings примените штатный seed-settings, подождите до
истечения cache TTL и перезапустите APK. Для повторной проверки soft на том же
latest_build очистите данные приложения или увеличьте latest_build, так как
«Позже» сохраняется в SecureStore без TTL.
APK имеет тот же package ru.han.chat и подпись EAS, поэтому может заменить
установленную store-сборку. Используйте отдельное тестовое устройство или заранее
учтите замену приложения и его локальных данных.
Store-сборки
npx eas-cli build --profile google-play --platform android
npx eas-cli build --profile rustore --platform android
npx eas-cli build --profile app-store --platform ios
Native build поднимается через appVersionSource: remote и platform-specific
autoIncrement. Google Play и RuStore используют общий Android application ID
ru.han.chat, поэтому их последовательные сборки увеличивают один remote
versionCode: например, первая получит 7, следующая — 8. Backend-пороги
магазинов поэтому заполняются независимо по фактически опубликованным
артефактам. Локальные versionCode: 2/buildNumber: 2 служат исходной native
identity, но при remote source фактическое значение сборки определяет EAS.
Полезные команды
# только отправить билд и сразу вернуть ссылку (не ждать окончания)
npx eas-cli build --profile google-play --platform android --no-wait
# статус конкретной сборки
npx eas-cli build:view <BUILD_ID>
# список последних сборок
npx eas-cli build:list --platform android --limit 5
# прочитать текущий remote versionCode/buildNumber
npx eas-cli build:version:get --platform android --profile google-play
npx eas-cli build:version:get --platform android --profile rustore
npx eas-cli build:version:get --platform ios --profile app-store
# скачать артефакт готовой сборки
npx eas-cli build:download --id <BUILD_ID>
# синхронизировать versionCode с Play Console (если нужно вручную)
npx eas-cli build:version:set
Полная процедура rollout, включения soft/force policy и отката:
../VM1_app/codebase/backend/deployment/RUNBOOK.mobile-updates.ru.md.
Keycloak redirect URI
Для боевого хоста в клиенте han-chat-frontend должны быть exact URI:
https://chat.han0107.ru/mobile/oidc/callbackhan-chat://auth/callback
Для preview — те же пути на https://dev-chat.han0107.ru.