Official URL migration preserves sessions, shortcuts prefs, and last clock-in client; auth screens match web with legal links; time clock and invoice editor/send flows are updated for the new domain and UI patterns. Co-authored-by: Cursor <cursoragent@cursor.com>
151 lines
5.2 KiB
Markdown
151 lines
5.2 KiB
Markdown
# beenvoice Mobile
|
|
|
|
Expo companion for [beenvoice-web](../beenvoice-web) — dashboard, time clock, invoices, clients, businesses, and settings. Shares the **same tRPC API** and **better-auth** sessions as the web app.
|
|
|
|
**Architecture (dense):** [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md)
|
|
|
|
## Prerequisites
|
|
|
|
- [Bun](https://bun.sh) 1.3+
|
|
- beenvoice API running ([setup](../beenvoice-web/README.md))
|
|
- Xcode + iOS Simulator (or device) for native dev build
|
|
- **Not Expo Go** — widgets, SecureStore auth, and biometrics need `expo-dev-client`
|
|
|
|
## Setup
|
|
|
|
```bash
|
|
cd beenvoice-app
|
|
bun install
|
|
cp .env.example .env
|
|
```
|
|
|
|
`.env`:
|
|
|
|
```env
|
|
# Simulator
|
|
EXPO_PUBLIC_API_URL=http://localhost:3000
|
|
|
|
# Physical iPhone — Mac LAN IP
|
|
EXPO_PUBLIC_API_URL=http://192.168.1.42:3000
|
|
```
|
|
|
|
Omit `EXPO_PUBLIC_API_URL` in production builds to default to `https://beenvoice.app`.
|
|
|
|
Server must enable `@better-auth/expo` in `beenvoice/src/lib/auth.ts` with `beenvoice://` in `trustedOrigins`.
|
|
|
|
## Run
|
|
|
|
```bash
|
|
# Terminal 1 — API
|
|
cd ../beenvoice-web && bun run dev
|
|
|
|
# Terminal 2 — mobile (builds native app if needed)
|
|
cd beenvoice-app && bun run ios
|
|
```
|
|
|
|
Metro uses port **8082** (avoids other Expo projects on 8081).
|
|
|
|
Metro only (app already installed):
|
|
|
|
```bash
|
|
bun run start -- --clear
|
|
```
|
|
|
|
Open the **beenvoice** dev build on the simulator — not Expo Go.
|
|
|
|
### After native changes
|
|
|
|
Icon (`assets/beenvoice.icon`), widgets, or new native modules:
|
|
|
|
```bash
|
|
bunx expo prebuild --platform ios --clean
|
|
bun run ios
|
|
```
|
|
|
|
## Features
|
|
|
|
| Area | Details |
|
|
|------|---------|
|
|
| **Auth** | Sign in, register, forgot/reset password; official or self-hosted server |
|
|
| **Multi-account** | Bitwarden-style switcher; per-account session in SecureStore |
|
|
| **Dashboard** | Revenue, pending, overdue, running timer, recent invoices |
|
|
| **Timer** | Clock in/out, client + invoice + rate; optional description (default "Clock In"); iOS Live Activity |
|
|
| **Entities** | Clients and businesses — list, create, edit |
|
|
| **Invoices** | List, filter, create, edit, status updates |
|
|
| **Settings** | Profile, accounts, theme, per-account app lock (PIN + Face ID), sign out |
|
|
| **App lock** | Per-account; locks on background return |
|
|
|
|
## Auth & accounts (summary)
|
|
|
|
- **Guest** auth storage: `beenvoice:guest` until first successful login
|
|
- **Per account**: `beenvoice:auth:{host::userId}` in SecureStore
|
|
- After login, `finalizeAuthenticatedAccount()` migrates session keys before activating the account (avoids double login)
|
|
- **Server picker**: Official (`beenvoice.app`) or custom URL on auth screens
|
|
|
|
Full flow: [docs/ARCHITECTURE.md#multi-account-model](./docs/ARCHITECTURE.md#multi-account-model)
|
|
|
|
## Deep links & Shortcuts
|
|
|
|
| URL | Action |
|
|
|-----|--------|
|
|
| `beenvoice://reset-password?token=…` | Reset password |
|
|
| `beenvoice://timer` | Open time clock |
|
|
| `beenvoice://shortcuts/clock-in` | Clock in (last client) |
|
|
| `beenvoice://shortcuts/clock-in?title=…` | Clock in with title |
|
|
| `beenvoice://shortcuts/clock-out` | Clock out running timer |
|
|
|
|
**iOS Shortcuts / Siri** (requires a **native dev client or TestFlight build** — not Expo Go; iOS **18+**):
|
|
|
|
- **Clock In** — starts the timer with your last client
|
|
- **Clock Out** — stops the running timer
|
|
- **Open Time Clock** — opens the timer tab
|
|
|
|
Shortcuts are **not pre-installed** in your Shortcuts library. To add one:
|
|
|
|
1. Install a fresh native build (`bunx expo prebuild --platform ios && bun run ios`, or a new EAS/TestFlight build).
|
|
2. Open beenvoice once while signed in.
|
|
3. Open **Shortcuts** → **+** → **Add Action** → search **beenvoice** (or “Clock In”).
|
|
4. Choose **Clock In**, **Clock Out**, or **Open Time Clock**.
|
|
5. Pick a client once on the Timer tab before the first clock-in shortcut.
|
|
|
|
You can also say “Hey Siri, clock in with beenvoice”. Settings → Shortcuts & Siri in the app has a setup guide and test links.
|
|
|
|
If beenvoice actions never appear when searching in Shortcuts, the installed build predates App Intents — rebuild and reinstall.
|
|
|
|
**Test deep links:**
|
|
|
|
```bash
|
|
xcrun simctl openurl booted "beenvoice://shortcuts/clock-in"
|
|
xcrun simctl openurl booted "beenvoice://shortcuts/clock-out"
|
|
xcrun simctl openurl booted "beenvoice://timer"
|
|
```
|
|
|
|
## Project layout
|
|
|
|
```
|
|
app/
|
|
_layout.tsx # Providers, auth guard
|
|
(auth)/ # sign-in, register, password flows
|
|
(app)/ # tab shell + nested stacks
|
|
components/ # UI, forms, chrome, time clock
|
|
contexts/ # Auth, Accounts, AppLock, Theme
|
|
lib/ # tRPC, auth storage, config, theming
|
|
widgets/ # iOS Live Activity (TimeClockActivity)
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
| Issue | Fix |
|
|
|-------|-----|
|
|
| `PlatformConstants` / runtime not ready | Stop other Metro on 8081/8082; rebuild with `prebuild --clean` |
|
|
| Expo Go | Use `bun run ios` dev build |
|
|
| API errors on device | `EXPO_PUBLIC_API_URL` = Mac LAN IP; server `BETTER_AUTH_URL` must match |
|
|
| Live Activity empty | Rebuild iOS; widget UI must live inside `"widget"` function |
|
|
| Login twice | Server + app versions with session migration (`lib/auth-storage.ts`) |
|
|
|
|
## Related
|
|
|
|
- [beenvoice-web README](../beenvoice-web/README.md)
|
|
- [beenvoice-web ARCHITECTURE](../beenvoice-web/docs/ARCHITECTURE.md)
|
|
- [Workspace root README](../README.md)
|