State & Data Flow
State Management
Two Zustand stores in lib/store.ts:
useAuthStore
| Field | Type | Description |
|---|---|---|
user | User | null | Current authenticated user |
isAuthenticated | boolean | Whether a user is signed in |
setUser(user) | action | Set user and isAuthenticated |
logout() | action | Clear user state |
Written by: Login screen, logout action Read by: Profile screen, Place Detail (review gate)
useMapStore
| Field | Type | Description |
|---|---|---|
region | { latitude, longitude, latitudeDelta, longitudeDelta } | Current map viewport |
selectedPlaceId | string | null | Currently selected marker |
categories | string[] | Active category filter IDs |
acsAttrs | string[] | Active accessibility attribute filters |
setRegion(region) | action | Update viewport |
setSelectedPlaceId(id) | action | Select a marker |
setCategories(ids) | action | Update category filters |
setAcsAttrs(attrs) | action | Update ACS filters |
Written by: Map screen (region changes, marker selection), Search Modal (filters, search result selection)
Read by: usePlaces (region, categories, acsAttrs), Map screen (selectedPlaceId for marker highlighting)
Data Flow
How places get from the database to the screen:
tRPC Integration
The mobile client connects to the same tRPC API the web app uses via lib/api.ts.
Platform-aware base URL (getBaseUrl()):
- Web:
http://localhost:3000 - Native (dev): Uses
Constants.expoConfig.hostUrito extract the LAN IP, e.g.http://192.168.1.x:3000 - Production:
https://enaccessmaps.com
Client setup:
export const api = createTRPCReact<AppRouter>();
export function createTRPCClient() {
return api.createClient({
links: [
httpBatchLink({
url: `${BASE_URL}/api/trpc`,
async headers() {
return {};
},
}),
],
});
}
The AppRouter type is imported from @enaccess/shared, which re-exports it from the main app's tRPC router definition. This gives the mobile client full type safety on all procedure calls.
Key procedures used:
place.searchPlacesByBounds— spatial search by map boundsplace.searchGooglePlaces— text search via Google Places APIcategory.getAll— fetch all place categories
The TRPCProvider (lib/trpc-provider.tsx) wraps the app with both the tRPC provider and QueryClientProvider from TanStack Query.
Authentication Flow
Session management (lib/auth.ts):
- Tokens stored in
expo-secure-store(encrypted native storage) getStoredSession()/storeSession()for session tokengetStoredUser()/storeUser()for cached user dataclearSession()removes both on logout