The iOS app shares the same database, same RLS policies, and same data model as the web app. Any database migrations created for the web automatically apply to iOS since both platforms use the same Supabase project.
Stack
- UI: SwiftUI, iOS 18+
- Architecture: MVVM + Repository pattern
- Backend: Supabase (same project as web app)
- Auth: Supabase Auth with Keychain token storage
Architecture pattern
Critical rules
- Only Repositories import
PostgREST— Views and ViewModels must never import it - All ViewModels are
@MainActor— never useDispatchQueue.main.async - Use
@EnvironmentObjectinjection, not.sharedsingletons - Pass
accessTokenandfacilityIdas init params
Project structure
Feature parity matrix
| Feature | Web | iOS |
|---|---|---|
| Case management | Full CRUD | View + milestone recording |
| Room status board | Full | Full |
| Surgeon home dashboard | Full | Full |
| Device rep tray tracking | Full | Full (differentiator) |
| ORbit Score | Client-side calculation | Planned (via surgeon_scorecards) |
| Analytics dashboards | 6 views | Not started |
| Block scheduling | Full | Not started |
| Admin features | Full | Not planned for mobile |
Shared principles
The iOS app follows the same platform-wide principles as the web app:- Same database, same RLS — identical Row-Level Security policies
- Milestone v2.0 —
facility_milestone_idis the FK, nevermilestone_type_id - Median over average — all analytics use median, not mean
- Soft deletes — filter
is_active = trueon soft-delete tables - Facility scoping — every query filters by
facility_id
Auth flow
UserDefaults to Keychain for security.
Critical development rules
- Only Repositories import
PostgREST— Views and ViewModels must never import it directly - All ViewModels are
@MainActor— never useDispatchQueue.main.async - Use
@EnvironmentObjectinjection, not.sharedsingletons - Pass
accessTokenandfacilityIdas init params to repositories
FAQ
Can I test iOS against the same database as web?
Can I test iOS against the same database as web?
Yes. Both apps use the same Supabase project. Point the iOS app’s configuration to your Supabase URL and anon key. RLS ensures data isolation per facility.
Why is ORbit Score 'Planned' for iOS?
Why is ORbit Score 'Planned' for iOS?
The scoring engine currently runs client-side in TypeScript. The iOS plan is to read from the
surgeon_scorecards table (pre-cached results) rather than re-implementing the scoring algorithm in Swift.