172 lines
8.2 KiB
Markdown
172 lines
8.2 KiB
Markdown
# HAN Chat Mobile
|
||
|
||
Мобильный клиент HAN Chat на Expo SDK 57. Текущая версия приложения — `1.0.1`,
|
||
native identity — Android `versionCode: 2` и iOS `buildNumber: 2`.
|
||
|
||
## Подготовка
|
||
|
||
1. Установить Node.js и npm.
|
||
2. Скопировать `.env.example` в `.env` и указать адреса API и Keycloak.
|
||
3. Установить зависимости:
|
||
|
||
```bash
|
||
npm install
|
||
```
|
||
|
||
4. Зарегистрировать `han-chat://auth/callback` как допустимый redirect URI клиента Keycloak.
|
||
|
||
## Локальные проверки
|
||
|
||
```bash
|
||
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
|
||
|
||
```powershell
|
||
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.
|
||
|
||
### Перед сборкой (рекомендуется)
|
||
|
||
```powershell
|
||
npm run typecheck
|
||
npm test
|
||
```
|
||
|
||
### Preview — APK на телефон
|
||
|
||
```powershell
|
||
npx eas-cli build --profile preview --platform android
|
||
```
|
||
|
||
После успеха откройте ссылку из вывода CLI (или `https://expo.dev/accounts/anzh/projects/han-chat/builds`) и скачайте APK.
|
||
|
||
### Preview RuStore — проверка soft/force update
|
||
|
||
```powershell
|
||
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-сборки
|
||
|
||
```powershell
|
||
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.
|
||
|
||
### Полезные команды
|
||
|
||
```powershell
|
||
# только отправить билд и сразу вернуть ссылку (не ждать окончания)
|
||
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/callback`
|
||
- `han-chat://auth/callback`
|
||
|
||
Для preview — те же пути на `https://dev-chat.han0107.ru`.
|