SpatioViewMobile
Expo/React Native staff app. Despite the name, its native CoreAPI traffic
is 100% /api/v1/* — no ticketing involvement (see the workspace's own
CLAUDE.md). Covers shift/attendance, chat, approvals, tasks, devices,
assets, alerts, POS, gate access, and (as of 2026-09-02) staff-side
concierge voice calling.
Overview
Expo 57 + React Native, TypeScript. Current version (from app.config.js,
the file Expo actually reads — package.json's "version": "1.0.0" is
stale/unused): 0.0.6.
Build numbers are per-platform, independent counters — they don't need
to match each other. As of 2026-09-23's staging submission (commit
a4e502f, verified via eas build:list): Android versionCode 6
(build 9ad7781d-ab6f-4170-acfc-b9d9198959ef), iOS buildNumber 10
(build 519f86f2-bc40-4016-a27c-789c9134aa82) — same source commit, same
0.0.6 version, submitted the same minute. iOS's counter simply has a
longer history (more total build attempts, some superseded) than
Android's. Don't read a numeric mismatch between platforms as anything
out of sync; only compare a platform's number against its own previous
submission.
Three build variants, distinguished by EXPO_PUBLIC_APP_VARIANT:
| Variant | Bundle id suffix |
|---|---|
development |
.dev |
staging |
.stg |
production |
(none) |
Base bundle id: xyz.hamburghini.playtelly. The dev variant also enables
NSAllowsArbitraryLoads on iOS, needed for plain-HTTP calls to
CoreAPI/AuthAPI at a real LAN IP during local development.
Calling architecture
Staff-side concierge calling (src/screens/concierge/ConciergeCallScreen.tsx,
added 2026-09-02) is a deliberately separate screen from the older
staff-to-staff chat's own CallScreen.tsx (which stays a mock-data
placeholder, untouched). Voice-only — no camera/video button, matching the
guest side.
Speaker toggle (added 2026-09-04) uses react-native-incall-manager —
react-native-webrtc alone has no audio-output routing API at all. Unlike
the web guest app's setSinkId limitation, this works reliably on both
iOS and Android since it's a real native module, not a browser API.
InCallManager.start({media: 'audio'}) takes over the call's audio
session on join and .stop() releases it on leave/unmount.
Running locally
npx expo start # dev server
npm run ios # expo run:ios --device
npm run android # expo run:android
TestFlight / production builds
Uses EAS Build (eas.json — development/staging/production
profiles). See eas build --profile <profile> --platform ios|android and
eas submit — requires eas login with the project's Expo account
first; not something to run without those credentials.
See Changelog for real, dated feature history.