Documentation
IntroductionArchitectureMonorepo & ToolingRunning Locally
Screen Flow MapUser JourneysPersonas & RolesWeb ScreensClient Portal
Convex OverviewData ModelFunctions ReferenceAuth & SessionsRoles & PermissionsJobs & Providers
Web Design SystemAdmin Console DesignPatterns & Conventions
Web AppiOS AppMarketing Website
Testing & HarnessCI Pipeline

iOS App

iOS App

apps/ios — the native customer companion: book a stay, pre-check-in, follow the pet live, pay, and message the front desk. Universal SwiftUI for iPhone/iPad targeting iOS 26, with macOS planned. It is the native twin of the Client Portal.

SwiftUI (iOS 26 · strict concurrency · @MainActor)
Home
Visits · Book
Pets
Inbox
Account · Billing
@Environment(AppStore.self)
AppStore (@Observable) — single source of truth
intent methods map 1:1 to Convex mutations:
completeCheckIn → visits.checkIn · bookVisit → orders.create + visits.create · recordPayment → payments.charge
Today: MockData.snapshot()
seeded demo world · simulated live care-event stream (25s) · enums use exact backend raw values
Roadmap: Convex client
live careEvents subscription replaces the simulation · ids already opaque Strings
iOS architecture — the @Observable AppStore is the backend seam; swapping in Convex touches nothing above it

Stack & posture

  • Swift 6.2 with strict concurrency (SWIFT_STRICT_CONCURRENCY: complete) and @MainActor default actor isolation.
  • SwiftUI + Observation: one @Observable final class AppStore (Sources/Services/AppStore.swift) is the single source of truth, injected via .environment(store).
  • xcodegen: xcodegen generate produces the (uncommitted) Pawdentity.xcodeproj from project.yml. Two targets: Pawdentity (app, bundle id com.pawdentity.client) and PawdentityUITests. Code signing disabled for simulator/CI builds.

Shell & navigation

  • PawdentityApp (@main) builds the store; RootView branches on store.isSignedIn between SignInView and MainTabView.
  • MainTabView uses .tabViewStyle(.sidebarAdaptable) — a tab bar on iPhone, sidebar on iPad, macOS-ready. Five tabs: Home, Visits, Pets, Inbox (unread badge from store.unreadMessageCount), Account.

Screens

FeatureViewsWhat it does
HomeHomeViewlive "in house" hero card, check-in prompt, vaccine/agreement/balance alerts, latest photos, upcoming visits
Check-inCheckInFlowView, ExpressPassViewmulti-step pre-check-in + a QR express pass scanned at the front desk
VisitsVisitsView, VisitDetailView, BookVisitFlowViewbooking flow: service → pets → dates → add-ons → review with deposit
PetsPetsView, PetDetailViewprofiles, vaccine tracking, notes, gallery, history
InboxInboxViewtwo-way threads with unread badges
AccountAccountView, BillingViewsinvoices/receipts, pay balance, payment methods, agreements, notification prefs

The mock store mirrors the Convex schema

This is the app's defining architectural decision. Models in Sources/Models/Models.swift are explicitly customer-facing projections of packages/backend/convex/schema.ts:

  • IDs are opaque Strings so real Convex document ids slot in unchanged.
  • Enums use the exact backend raw values: VisitStatus (planned, due_in, in_house, overdue, completed, cancelled, no_show), PaymentStatus (deposit_due, deposit_met, …), CareEventType, ServiceKind, Species.
  • Money is integer cents (Int.asCurrency), matching the backend convention.
  • Structs: Facility, Client, Pet/Vaccine, PetPhoto, Visit, CareEvent, Order/OrderItem, PaymentMethod/PaymentReceipt, MessageThread/Message, Agreement, ServiceProduct/AddOn.

AppStore hydrates from MockData.snapshot() — a seeded demo world anchored to "now", including a simulated live care-event stream (an event every 25s while a pet is in house, standing in for a Convex subscription on careEvents) and staff auto-replies to messages after 4s.

Every intent method is annotated with the Convex mutation it maps 1:1 to: completeCheckIn → visits.checkIn, bookVisit → orders.create + visits.create, recordPayment → payments.charge, sendMessage → messages.send, signAgreement → signatures.create. Swapping in a Convex HTTP/WebSocket client changes AppStore internals only.

Demo & testing

DEBUG-only launch args (Sources/App/DemoLaunch.swift):

ArgEffect
-demo-signed-inskip sign-in
-demo-tab <0-4>open Home/Visits/Pets/Inbox/Account
-demo-checkinopen Home with the check-in flow presented

PawdentityUITests/DemoJourneyTests.swift scripts a paced end-to-end walkthrough (sign-in → live stay timeline → full check-in including drawing on the signature-pad element and "Simulate Front Desk Scan" → book → pet profile → message → pay), designed to run under xcrun simctl io … recordVideo for demo capture.

Roadmap

Convex client replacing the mock store · Live Activities & widgets · push notifications · Apple Pay (PassKit) + a Wallet pass for the express QR · a macOS target reusing the adaptive shell.