Files
westfarn 9e1449f0db
Deploy Beta / unit-tests (push) Successful in 12s
Unit Tests / test (push) Successful in 11s
Deploy Beta / deploy-beta (push) Successful in 2m23s
Add public account-deletion page for Google Play (#103) (#110)
## Summary
- Closes [#103](#103).
- Adds public SPA route `/account-deletion/` (no auth) with Hesychia / `ai.hesychia.chat` branding, in-app deletion steps, soft-delete data retention copy, and a contact path (30-day SLA) for users who cannot sign in.
- Documents Play Console **Account deletion URL** in `ANDROID.md` and `android/README.md` (`https://hesychia.ai/account-deletion/`, legacy host, HashRouter form).

## Notes
- Retention copy matches backend soft-delete (v1): no claim of full erasure / hard purge yet.
- Play Console field still needs to be set out-of-band after deploy.

## Test plan
- [ ] Open `/account-deletion/` signed out — page loads (no redirect to sign-in)
- [ ] Confirm steps match Account → Delete my account + email confirm
- [ ] Confirm retention sections are accurate vs soft-delete
- [ ] `npm run test:ci -- --testPathPattern=AccountDeletionPage`
- [ ] After beta deploy, set Play Console Account deletion URL to the public HTTPS URLReviewed-on: #110
2026-08-04 10:53:48 -07:00

152 lines
5.2 KiB
Markdown

# Android (Capacitor)
Ship the CRA web build as an Android app via [Capacitor](https://capacitorjs.com/).
One codebase: `llm-fe/` → web + Android + iOS WebView.
**Build & Play deploy steps:** [`android/README.md`](android/README.md).
**iOS sibling:** [`IOS.md`](IOS.md) / [`ios/README.md`](ios/README.md).
Prerequisites for blockers already merged: JWT-only auth (#22), WebSocket lifecycle (#23), HashRouter (#24).
## Prerequisites
- **Node.js 20** (matches CI; Capacitor **7.x**)
- **JDK 17+** (OpenJDK fine)
- **Android Studio** (Ladybug+) with Android SDK Platform **35**, build-tools, and an emulator or device
- Set `ANDROID_HOME` (or open the project once in Android Studio so `local.properties` is generated)
## One-time / day-to-day
```bash
cd llm-fe
npm ci
npm run build:mobile # loads .env.mobile → CRA build → cap sync android
npm run android:open # opens android/ in Android Studio
```
Or sync only after an existing `build/`:
```bash
npm run android:sync
```
## Environment
| File | Purpose |
|------|---------|
| `.env.mobile` | Endpoints baked into the **mobile** bundle (`build:mobile`) |
| `.env.production` | Web prod deploys (`build` / `build:prod`) |
| `.env.beta` | Web beta deploys |
Default `.env.mobile` matches production (`chatbackend.aimloperations.com`). Point it at beta to flip the shell without touching web deploys. Optional gitignored override: `.env.mobile.local`.
### RevenueCat IAP (#100)
Native billing uses `@revenuecat/purchases-capacitor` (Capacitor 7 → package **11.x**). Web keeps Stripe Checkout / Customer Portal.
Set public SDK keys in `.env.mobile` (empty placeholders OK until store apps ship):
| Variable | Purpose |
|----------|---------|
| `REACT_APP_REVENUECAT_APPLE_API_KEY` | iOS public SDK key |
| `REACT_APP_REVENUECAT_GOOGLE_API_KEY` | Android public SDK key |
| `REACT_APP_REVENUECAT_OFFERING_ID` | Optional offering pin (else current) |
After install / key changes: `npm run build:mobile` (runs `cap sync`). More detail: [`MONETIZATION.md`](MONETIZATION.md).
## Versioning
In `android/app/build.gradle`:
- **versionName** — user-visible string; keep aligned with `package.json` `version` (currently `0.1.0`)
- **versionCode** — integer; **must increase** for every Play Store upload
Bump both before each store release.
## Icons / splash
Source art lives in `llm-fe/assets/`:
- `icon.png` / `splash.png` / `splash-dark.png` — Capacitor inputs (Hesychia meander mark)
- `logo-source.png` — cropped square master
- `logo-mark-transparent.png` — circular mark with transparent corners (web / in-app)
In-app UI also imports `src/llm-fe/assets/brand/hesychia-mark.png`.
Regenerate Android densities after changing source art:
```bash
npm run assets:generate
```
Same command also regenerates iOS `Assets.xcassets` (see [`IOS.md`](IOS.md)).
## Signing (upload keystore)
**Never commit keystores.** Store outside the repo (e.g. host secrets / password manager).
```bash
keytool -genkey -v -keystore ~/Documents/secrets/aiml-chat-upload.jks \
-keyalg RSA -keysize 2048 -validity 10000 \
-alias aiml-chat-upload
```
Create `llm-fe/android/keystore.properties` (gitignored):
```properties
storeFile=/absolute/path/to/aiml-chat-upload.jks
storePassword=...
keyAlias=aiml-chat-upload
keyPassword=...
```
Release App Bundle:
```bash
cd llm-fe/android
./gradlew bundleRelease
# → app/build/outputs/bundle/release/app-release.aab
```
Debug APK (no signing props needed):
```bash
./gradlew assembleDebug
```
## Manual QA checklist
On emulator **and** physical device:
- [ ] Login / logout / password reset flows
- [ ] Chat streaming + markdown / code blocks
- [ ] Charts (`recharts`)
- [ ] Dark / light theme
- [ ] Hardware back: navigates history, exits at root
- [ ] Keyboard does not cover compose input; notch/safe-area OK
- [ ] Background → resume keeps or reconnects WebSocket
- [ ] Airplane mode → restore reconnects
## Play Store (internal testing first)
Out of band ops (not automated here):
1. Google Play developer account
2. Privacy policy URL (product site / legal)
3. **Account deletion URL** (Data safety / Account deletion) → public page:
- Canonical: `https://hesychia.ai/account-deletion/`
- Legacy host until DNS cutover: `https://chat.aimloperations.com/account-deletion/`
- Capacitor HashRouter: `/#/account-deletion/`
4. Data safety form (JWT auth, chat content, analytics if Tianji runs in WebView)
5. Screenshots for phone (+ tablet if targeting)
6. Upload `.aab` to **internal testing** track before production
In-app delete remains Account → **Delete my account** (`DELETE /api/user/`). The public URL
above is for Play reviewers and users who never open the app (#103).
## Related issues
- [#20](https://git.aimloperations.com/ai_ml_operations/chat_web_app/issues/20) — this Android wrap
- [#21](https://git.aimloperations.com/ai_ml_operations/chat_web_app/issues/21) — iOS (reuses this scaffolding)
- [#22](https://git.aimloperations.com/ai_ml_operations/chat_web_app/issues/22) / [#23](https://git.aimloperations.com/ai_ml_operations/chat_web_app/issues/23) / [#24](https://git.aimloperations.com/ai_ml_operations/chat_web_app/issues/24) — auth / WS / routing
- [#103](https://git.aimloperations.com/ai_ml_operations/chat_web_app/issues/103) — Play public account-deletion URL