# Biz Connect — Mobile & Desktop clients Native clients for Biz Connect. **The web app is the single source of truth for the UI**; each native client is a thin shell that loads that UI and adds the capabilities a browser can't provide (background push, native screen capture, OS input injection, store presence). Decisions (set by the user 2026-06-30): - **Build mobile and desktop in parallel.** - **Desktop = both pieces:** the remote-control **host** (existing `agent/`) *and* a **technician desktop client** (`desktop/` — Connect in a window). - **Mobile = Capacitor wrap** of the existing web UI (one codebase), not a native rewrite. Backend is already client-ready (see [ARCHITECTURE.md](ARCHITECTURE.md) Phase 2): `/api/v1`, `Authorization: Bearer` + refresh tokens, API keys, per-tenant webhooks. The one remaining backend gap is **APNs/FCM push** for native mobile (needs Apple/Google credentials). --- ## Components | Dir | Client | Tech | What it adds over the browser | |-----|--------|------|-------------------------------| | `mobile/` | iOS + Android app | **Capacitor** loading the Connect UI | Native push (FCM/APNs), camera/mic perms, store distribution, screen capture (ReplayKit / MediaProjection) | | `desktop/` | Technician client | **Electron** loading the Connect UI | Native full-screen capture for screen-share; windowed app; later: tray, auto-update | | `agent/` | Remote-control **host** (customer) | **Electron + nut-js** *(exists, v0.2.0)* | Screen capture + **OS input injection** so a technician can control the machine | All three authenticate through the same `/api/v1` access layer (Bearer token for mobile/desktop, the existing consent/enroll flow for the agent). --- ## Why "wrap the web UI" (not rewrite) The Connect UI is already an installable PWA built from server-rendered single-file HTML. Pointing a native webview at the server origin means **every relative `/api` and `/ws` URL keeps working unchanged** — zero web-code changes — while native plugins augment it through the JS bridge. One codebase, three shells. Trade-off: a server-URL shell needs network at launch (fine for a remote-support tool) and some stores scrutinise "just a website". We mitigate by shipping real native capabilities (push, screen capture, deep links), and can later switch to **bundled** web assets + an absolute API base if offline-launch or store policy requires it. --- ## Phased plan ### Phase A — Shells that load the live app ← start here - [ ] `desktop/` Electron client: `loadURL(server)`, `setDisplayMediaRequestHandler` so screen-share works natively, external links → browser, persisted session. - [ ] `mobile/` Capacitor project: `server.url` → Connect, app icons/splash, status bar. - [ ] Inject `window.__NATIVE__ = 'desktop' | 'ios' | 'android'` so the web UI can adapt (e.g. hide the PWA "install" prompt, enable native push instead of Web Push). ### Phase B — Native capabilities - [x] **Push backend:** device-token registration (`POST /api/v1/devices`, `/api/v1/devices/remove`) + native senders folded into the single `push.sendToUser` path — **FCM v1** (Android) and **APNs** token-based over HTTP/2 (iOS), each config-gated and a no-op until creds are set. Web Push (VAPID) unchanged. Dead tokens are pruned on 404/410/UNREGISTERED. (db `device_tokens`, repo `deviceTokens`, `push.js`.) *Mobile app still needs the Capacitor push plugin wired + FCM/APNs creds to deliver end-to-end.* - [x] **Capacitor push plugin wired** in the web UI (`setupNativePush` in home.html): inside the app it requests permission, registers, and `POST`s the FCM/APNs token to `/api/v1/devices`; notification taps deep-link via `selectChat`; logout unregisters the token. Web Push is skipped when running natively. Inert in a normal browser. *Activates once the Capacitor Android/iOS app is built and FCM/APNs creds are set.* - [ ] **Mobile screen capture** for "Share Screen" from a phone (ReplayKit / MediaProjection plugin). - [ ] **Deep links / universal links** so a session/meeting link opens the app. ### Phase C — Packaging & distribution *(needs external accounts)* - [ ] Desktop installers via **electron-builder** (Win NSIS + Mac dmg); **code-signing** (Win EV cert, Apple Developer ID + notarization). - [ ] Mobile store builds: **Apple Developer** ($99/yr) + **Google Play** ($25 once); signing keys; store listings & privacy disclosures. - [ ] Agent host installer (signed) for customers. - [ ] Auto-update channels. --- ## Build & run ### Desktop (technician client) ```bash cd desktop npm install SERVER_URL=https://remote.bizgaze.com npm start # or http://localhost:8090 in dev npm run dist # build installers (needs electron-builder + certs) ``` ### Mobile (Capacitor) ```bash cd mobile npm install npx cap add android # needs Android Studio + SDK npx cap add ios # needs macOS + Xcode npx cap sync npx cap open android # build/run from Android Studio npx cap open ios # build/run from Xcode ``` Set the server origin in `capacitor.config.json` (`server.url`). ### Agent host (existing) ```bash cd agent npm install SERVER_URL=https://remote.bizgaze.com AGENT_ENROLL_TOKEN= npm start ``` --- ## What's gated on you (external, can't be done from code alone) - **Apple Developer** + **Google Play** accounts (mobile store builds & push). - **Code-signing certificates** (Windows EV, Apple Developer ID) for trusted installers. - **FCM/APNs credentials** for native push. Everything else — the shells, the device/push backend, native plugin wiring — is built here.