2026-06-29 01:38:00 -04:00
2026-06-17 15:44:12 -04:00
2026-06-17 15:44:12 -04:00
2026-06-29 01:38:00 -04:00
2026-06-29 01:38:00 -04:00
2026-06-29 01:35:00 -04:00
2026-06-29 01:35:00 -04:00
2026-06-29 01:35:00 -04:00
2026-06-17 15:44:12 -04:00
2026-06-17 15:44:12 -04:00

beenvoice Mobile

Expo companion for 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

Prerequisites

  • Bun 1.3+
  • beenvoice API running (setup)
  • Xcode + iOS Simulator (or device) for native dev build
  • Not Expo Go — widgets, SecureStore auth, and biometrics need expo-dev-client

Setup

cd beenvoice-app
bun install
cp .env.example .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

# 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):

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:

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

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:

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)
S
Description
beenvoice mobile app (Expo/React Native)
Readme MIT
1.6 MiB
Languages
TypeScript 93.7%
JavaScript 3.7%
Shell 2%
Swift 0.6%