From 0f3237f1251a7574323dc05026518ba511e37641 Mon Sep 17 00:00:00 2001 From: bonamin Date: Mon, 28 Sep 2026 13:32:34 +0300 Subject: [PATCH] docs: pack README - native Android app section (build, signing, versioning, distribution) and rule CS-9 Co-Authored-By: Claude Opus 5.5 --- docs/README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/docs/README.md b/docs/README.md index 8227c78..641a795 100644 --- a/docs/README.md +++ b/docs/README.md @@ -38,6 +38,8 @@ The manager calls the API **same-origin, with relative paths**. The waiter app r | `local_backend/roles.py`, `routers/deps.py` | Roles, permission checks, auth dependencies | | `local_backend/routers/ws.py` | Real-time event stream (seq + cursor replay) | | `waiter_pwa/src/config/server.js` | **Where the backend is**: active venue, `apiBase()`, `wsUrl()`, `assetUrl()`, `storageKey()`, `dbName()`, `deliveryMode()` | +| `waiter_pwa/android/`, `capacitor.config.json` | Native Android app (Capacitor 8). See "Native Android app" below | +| `waiter_pwa/src/native/pairing.js`, `src/pages/VenuesPage.jsx` | Pairing with a venue (QR / typed address) and the venue switcher | | `waiter_pwa/src/api/client.js` | axios instance: auth header, 401 → logout, network error → offline | | `waiter_pwa/src/context/SSEContext.jsx` | Real-time lifecycle, event → store/cache updates, visibility refresh | | `waiter_pwa/src/db/posdb`, `src/services/offlineOrders` | Offline cache and queued orders | @@ -100,6 +102,30 @@ docker compose -f docker-compose.yml -f docker-compose.dev.yml build docker push registry.bonamin.gr/pos-backend: # + pos-waiter, pos-manager ``` +## Native Android app (waiter_pwa) + +The same waiter code, bundled into an APK with Capacitor 8. It is sideloaded, not on Play Store yet. + +```powershell +cd waiter_pwa +npm run apk:debug # releases/xenia-waiter--debug.apk (WebView debuggable via chrome://inspect) +npm run apk:release # releases/xenia-waiter-.apk, signed, AND copied to public/downloads/ +``` + +- **Signing key:** `%USERPROFILE%\.xenia\xenia-release.jks` + `keystore.properties`. It lives **outside the repo; back it up.** A lost key means no phone can install updates (uninstall and reinstall on every phone). Cert SHA-256 `98:A2:60:25:…:61:7A`. +- **Versioning:** bump **both** `versionCode` and `versionName` in `android/app/build.gradle` for every APK handed out. Android refuses an update whose versionCode isn't higher. +- **Distribution:** `apk:release` copies the APK into `public/downloads/`, so the next web build (and Docker image) serves it at `http:///downloads/xenia-waiter.apk`. The browser-mode install banner links there. **Order: `apk:release` → `docker compose … build`.** +- **Native specifics:** + - `androidScheme: http` (origin `http://localhost`) + - cleartext allowed via `network_security_config.xml` + - no service worker (`vite build --mode native` → `dist-native/`) + - back button handled in `src/native/backButton.js` + - first run shows only the pairing screen +- `android/local.properties` (SDK path) is gitignored. Recreate it on a new machine: `sdk.dir=C:/Users//AppData/Local/Android/Sdk`. + +**CS-9. Anything a native build needs must survive `npx cap sync`.** +`android/app/src/main/assets/public` and the generated configs are rebuilt on every sync, so never edit them. Native changes go in `android/app/src/main/**` (manifest, res, java) or `capacitor.config.json`. + ## Testing There is no automated test suite yet. Before committing: - the backend starts cleanly against an **existing** `pos.db` (this catches missing migrations)