Mobile App — Personas and Roles
Status: normative Owner: Frontend Platform Last updated: 2026-04-18 Companion: README.md · AUTH_AND_SESSION.md · SCREENS_AND_NAVIGATION.md · UI_UX_PATTERNS.md ·
../../common/THEME.md
1. Single App, Multiple Personas
Ghasi-eHealth ships one React Native mobile application — @ghasi/ehr-mobile — that serves four distinct personas through role-based navigation and feature gating. There are no separate consumer / caregiver / CHW apps.
| Persona | Primary user | Relationship to patient data |
|---|---|---|
| Patient | End user managing their own health | Self — direct access to own record |
| Caregiver | Family member or paid carer managing another person's care | Proxy — access granted by patient or legal representative |
| Guardian | Parent / legal guardian of a minor or dependent adult | Legal proxy — access derived from legal relationship + jurisdiction rules |
| CHW / Local health worker | Community health worker, outreach nurse | Programmatic — access to a household / catchment area defined by deployment |
A user may hold multiple personas simultaneously (e.g. a parent caring for a child while also managing their own health, or a CHW who is also a patient). The app surfaces a persona switcher when more than one active role is present.
2. Why one app
| Reason | Detail |
|---|---|
| Shared auth & identity | All personas authenticate against the same IAM; distinguishing them is a policy concern, not a packaging one |
| Shared design system | One theme, one icon set, one typography scale (see ../../common/THEME.md) |
| Shared offline / caching engine | One SQLite schema, one outbox, one sync scheduler reduces surface area and bug classes |
| Shared deep-link surface | Notifications and SMS links resolve to a single bundle id |
| Simpler release pipeline | One codebase, one store listing per platform, one build matrix |
| User mobility | Users routinely move between personas (a caregiver becomes a patient, a CHW also manages their own appointments) — a single app avoids double-login friction |
3. Persona Capabilities Matrix
Capability is the product of persona × tenant license × IAM role × access-policy. This matrix shows the shape of each persona; the server remains authoritative via 403/404.
| Capability | Patient | Caregiver | Guardian | CHW |
|---|---|---|---|---|
| View own record (appointments, results, meds) | ✅ | — | — | ✅ (for self if registered) |
| View proxy subject record | — | ✅ (per grant) | ✅ (per relationship) | — |
| Book appointments for self | ✅ | — | — | ✅ |
| Book appointments for proxy subject | — | ✅ | ✅ | ✅ (for household) |
| Message providers (secure messaging) | ✅ | ✅ | ✅ | ✅ (scoped) |
| Manage consents | ✅ | — | ✅ (as legal rep) | — |
| Receive results notifications | ✅ | ✅ | ✅ | ✅ (per assignment) |
| Household registry / census | — | — | — | ✅ |
| Household-level vitals capture | — | — | — | ✅ |
| Commodity dispensing (family planning, ORS, etc.) | — | — | — | ✅ (where licensed) |
| Immunisation recording at point of care | — | — | — | ✅ |
| Antenatal / postnatal visit capture | — | — | — | ✅ |
| GPS-tagged visit record | — | — | — | ✅ |
| Offline bulk data collection | — (limited) | — (limited) | — (limited) | ✅ (heavy) |
| Barcode / QR scan for patient ID or commodity | — | — | — | ✅ |
| Supervisor dashboard (team metrics) | — | — | — | ✅ (supervisors only) |
Capability = persona × license × role × policy. The matrix above is the upper bound for each persona. Actual availability per user resolves server-side.
4. Persona-Scoped Navigation
Navigation is data-driven by the user's resolved capability map (same principle as desktop — see REQ-DESK-FR-090…098). Persona surfaces differ in:
- Primary tabs (bottom tab bar on mobile)
- Landing screen after login
- Notification categories subscribed
- Offline caching priorities (what is pre-fetched and kept warm)
4.1 Patient — landing and tabs
[Home] [Appointments] [Results] [Messages] [More]
- Home: next appointment, latest results, active prescriptions, reminders
- More: consents, family members (linked proxies), settings, language
4.2 Caregiver — landing and tabs
[Overview] [People] [Appointments] [Messages] [More]
- Overview: aggregated dashboard across all subjects the caregiver manages
- People: list of subjects the caregiver has access to, with per-subject drill-down
- Appointments: merged calendar across all subjects with subject label per row
- Messages: threads scoped to each subject relationship
4.3 Guardian — landing and tabs
[Home] [Dependants] [Appointments] [Consents] [More]
- Similar to caregiver but with explicit Consents tab because legal guardians typically manage consent workflows
- Age-transition flows (dependant reaches age of majority) surfaced prominently
4.4 CHW — landing and tabs
[Today] [Households] [Tasks] [Capture] [More]
- Today: visit schedule, daily targets, supervisor messages
- Households: household list with filters by risk / next-visit-due / ward
- Tasks: queued tasks (vitals due, immunisation series due, follow-ups)
- Capture: quick-entry surface for common workflows — vitals, immunisation, commodity dispense, household survey
- More: training modules, sync status, supervisor contact, field device settings
5. Persona Switcher
When a signed-in user has more than one active persona, a header affordance surfaces a persona switcher:
- Tapping the avatar opens a sheet listing available personas with the subject context they unlock
- Switching personas:
- Replaces the tab bar with the persona's tab set
- Triggers a context reload (clears in-memory query caches scoped to the prior persona)
- Does not sign the user out — token and identity remain the same
- Records an audit event
mobile.persona.switched { from, to, userId }
- The app remembers the last-used persona and restores it on next launch
Single-persona users see no switcher — the UI is unchanged from today's patient-only experience.
6. Proxy Access Model (caregiver & guardian)
6.1 Grant lifecycle
Proxy access is grant-based and server-authoritative. The mobile app is a consumer, not the source of truth.
Patient (or legal rep) initiates grant
│
▼
Consent flow — scope, expiry, revocation terms
│
▼
consent-service issues ProxyGrant { grantId, subjectId, holderId, scope[], expiresAt }
│
▼
Push notification to holder's device(s)
│
▼
Grant appears in holder's "People" tab after next sync
6.2 Scope enumeration
Grants carry a scope — the set of actions the holder may perform on behalf of the subject:
view.appointmentsbook.appointmentsview.resultsview.medicationsmanage.consents(guardians only, jurisdiction-dependent)messaging.send
The mobile UI disables or hides actions outside the holder's grant scope. Server enforces via 403.
6.3 Age-transition handling (guardians)
When a dependant reaches the locally-configured age of majority:
- The guardian grant auto-expires at the jurisdictional threshold per tenant policy
- The dependant receives an onboarding notification to claim their own account
- Records remain visible to the former dependant; the former guardian loses access unless a fresh grant is issued
- Edge cases (dependants with ongoing capacity issues) are handled out-of-band via the platform admin / legal rep flow — the mobile app surfaces a banner directing the guardian to contact their provider
7. CHW-Specific Requirements
CHW workflows are materially different from consumer personas and drive additional capabilities in the same app bundle.
7.1 Offline-first weight
CHWs routinely work in connectivity gaps. The CHW persona receives heavier offline caching than consumer personas:
| Data | Consumer personas | CHW persona |
|---|---|---|
| Own/proxy record | On-demand fetch, cached after first view | — |
| Assigned households | — | Pre-fetched at login, kept warm |
| Terminology (ICD / LOINC / SNOMED subsets in use) | Minimal | Full subsets needed for field capture |
| Commodity catalog | — | Full catalog, refreshed daily when online |
| Form definitions (household survey, ANC visit, etc.) | — | Pre-fetched |
| Decision-support rules (IMCI, ANC risk triggers) | — | Pre-fetched, evaluated offline |
See OFFLINE_AND_CACHING.md for the cache policy per persona.
7.2 Device integration
| Capability | Implementation |
|---|---|
| Barcode / QR scan (patient ID wristbands, commodity packaging) | vision-camera + ML Kit barcode detection |
| GPS tagging on visits | expo-location with explicit permission prompts; coarse location only by default |
| Photo capture for wound, skin, documentation | vision-camera; stored encrypted at rest; uploaded when online |
| NFC tap (where deployment uses NFC ID cards) | react-native-nfc-manager — optional, feature-flagged |
| Print to Bluetooth thermal printer (receipts, medication labels) | react-native-thermal-receipt-printer — optional, feature-flagged |
None of these are loaded for consumer personas — the CHW feature bundle is lazy-loaded when the CHW persona is activated.
7.3 Supervisor-sub-persona
CHWs marked as supervisors (chw.supervisor role) see:
- Team roster with current location status (where policy permits)
- Aggregate metrics (visits done this week, outstanding tasks per CHW)
- Supervision visit checklist workflow
This is a role within the CHW persona, not a separate persona.
7.4 Privacy considerations
- CHW may see data about people who are not themselves app users — the household registry is structured so a household member's data is accessible only to CHWs assigned to that household (via
access-policy) - GPS data is a consent surface: each deployment chooses coarse vs. precise location, and can disable location entirely
- Photos capturing identifiable individuals must follow the tenant's patient photo policy — the UI surfaces the consent capture step before saving
8. Shared Contracts
Across all personas, the mobile app respects:
| Contract | Location |
|---|---|
| Auth (OIDC + PKCE, biometric unlock, session) | AUTH_AND_SESSION.md |
| API base URL, Kong routes, error shapes | API_CLIENT_AND_KONG.md |
| Theming (tokens, per-tenant override, RTL, dark mode) | ../../common/THEME.md |
| Offline / caching priority | OFFLINE_AND_CACHING.md |
| Push & deep links | PUSH_AND_DEEP_LINKS.md |
| i18n & RTL | I18N_AND_RTL.md |
| Observability & privacy | OBSERVABILITY_AND_PRIVACY.md |
Per-persona differences live in SCREENS_AND_NAVIGATION.md and OFFLINE_AND_CACHING.md. The stack, design system, and operational patterns are shared.
9. Licensing & Feature Flags
Personas and persona-specific features are gated in the same capability-map pipeline as the desktop client (cross-reference REQ-DESK-FR-090…098 in the desktop platform requirements).
| Gate | Source | Effect |
|---|---|---|
| Persona availability | config-resolver per tenant + user profile | Determines which tab sets a signed-in user may access |
| CHW module license | Tenant license SKU | CHW feature bundles (household registry, commodity dispensing) load only when licensed |
| Commodity dispensing sub-feature | Tenant feature flag | Toggleable independently of CHW module |
| Proxy access flows | Jurisdiction + tenant consent policy | Caregiver / guardian UI surfaces available when proxy grants are legally supported in the tenant's deployment |
| Biometric unlock | Device capability + tenant policy | Bypass PIN with Face ID / Touch ID / Android biometric when allowed |
Unlicensed capabilities are hidden from navigation; server enforces via 403/404 if a deep link is followed anyway.
10. Persona Acceptance Criteria (Gherkin)
Feature: Persona detection on login
Scenario: User with single persona lands directly
Given a user has only the "patient" persona
When they sign in
Then the app loads the patient home screen
And no persona switcher is visible
Scenario: User with multiple personas picks a persona
Given a user has both "caregiver" and "patient" personas
When they sign in for the first time
Then the app prompts them to choose a starting persona
And records the choice for next launch
Feature: Persona switch preserves session
Scenario: Switching persona does not re-authenticate
Given a signed-in user is in the caregiver persona
When they switch to the patient persona
Then their auth token is unchanged
And an audit event "mobile.persona.switched" is recorded
And the tab bar reflects the patient persona's tab set
Feature: CHW offline data capture
Scenario: CHW completes a household visit without connectivity
Given the device has no connectivity
When a CHW records a household survey
Then the survey is persisted locally with a clientMutationId
And the outbox reports a pending sync
When connectivity returns
Then the survey is submitted with idempotency headers
And server acknowledgement reconciles local state
Feature: Proxy access scope enforcement
Scenario: Caregiver with view-only grant cannot book
Given a caregiver has a proxy grant with scope ["view.appointments", "view.results"]
When they view the subject's appointments
Then the UI hides the "Book appointment" action
And if the caregiver somehow reaches the booking endpoint
Then the server returns 403
Feature: Guardian age-transition
Scenario: Dependant reaches age of majority
Given a guardian has an active grant over a dependant
When the dependant's age crosses the jurisdictional threshold
Then the grant is marked expired server-side
And on the guardian's next sync
Then the dependant disappears from the guardian's "People" tab
And the former dependant receives an onboarding push notification