ADR-009: Sovereign Mobile Architecture Strategy: Kotlin Multiplatform (KMP) for GERCIA Care
Status
Section titled “Status”ACCEPTED 2026-10-04
Context
Section titled “Context”The initial mobile strategy for GERCIA Care (care.gercia.com.br) was prototyped using .NET MAUI Blazor Hybrid (dotnet/src/Clients/Gercia.Mobile). While this approach promised full C# code-sharing across the backend and mobile apps, evolving product requirements for Classe A/B human clinical workflows and regulatory compliance revealed critical technical bottlenecks:
-
Dual-Persona Workload Friction & WebView Overhead:
- GERCIA Care operates a mission-critical dual-persona architecture:
- Patient Mode: Longitudinal electronic health records (EHR), interactive compounding quotation timelines, real-time prescription tracking, and continuous smartwatch telemetry ingestion.
- Clinician Companion Mode: On-the-go patient triage, instant clinical appointment management, AI copilot consultation summaries, and hardware-backed biometric Push-to-Sign authorization for electronic prescriptions issued from the desktop Angular web portal.
- Running these high-frequency interfaces inside a mobile
WebView(Blazor Hybrid) creates DOM-to-native IPC bridge latency, suboptimal 60/120 fps scroll physics, increased battery drain, and elevated cold start latency (2.5–4.5 seconds on iOS and mid-range Android devices).
- GERCIA Care operates a mission-critical dual-persona architecture:
-
Deep OS Health Ecosystem Friction (HealthKit & Health Connect):
- Continuous biometric telemetry ingestion (heart rate variability, sleep stages, resting blood pressure, blood glucose, continuous step activity) requires tight background integration with Apple HealthKit (iOS) and Google Health Connect (Android).
- Cross-platform abstraction layers (.NET MAUI bindings) suffer from frequent synchronization lags behind new OS releases (iOS 18+ / Android 15), fragile native bridge maintenance, and complex background worker lifecycle constraints (
BGAppRefreshTaskandWorkManager).
-
Hardware-Backed Biometric Push-to-Sign (
ICP-BrasilCompliance):- Remote clinician prescription signing (
CFM Res. 2.314/2022andLei 14.510/2022) requires cryptographic key generation and digital signature execution directly anchored to physical device hardware:- Apple Secure Enclave via
LocalAuthenticationandCryptoKit(P-256 ECC private key generation withkSecAccessControlBiometryAny). - Android Keystore with StrongBox Keymaster via
BiometricPromptandKeyGenParameterSpec(PURPOSE_SIGN).
- Apple Secure Enclave via
- Implementing these hardware security module (HSM) invariants over MAUI dependency abstractions introduces unneeded fragility, security review overhead, and vendor lock-in.
- Remote clinician prescription signing (
Decision
Section titled “Decision”The GERCIA Platform officially transitions GERCIA Care from .NET MAUI to Kotlin Multiplatform (KMP) utilizing a Shared Kotlin Domain Engine coupled with 100% Native Declarative UIs: SwiftUI for iOS/watchOS and Jetpack Compose for Android.
flowchart TD
subgraph UI_TIER ["Native Declarative UI Tier (100% Platform Fidelity)"]
IOS_UI["<b>iOS & watchOS App</b><br>• 100% Native SwiftUI<br>• LocalAuthentication / FaceID<br>• Apple HealthKit Native Client<br>• CryptoKit / Secure Enclave"]
AND_UI["<b>Android App</b><br>• 100% Jetpack Compose & Material 3<br>• BiometricPrompt API<br>• Health Connect Native Client<br>• StrongBox Keymaster Keystore"]
end
subgraph SHARED_KMP ["Shared Kotlin Multiplatform Engine (apps/mobile/shared)"]
direction TB
KMP_STATE["<b>State & Presentation Layer</b><br>• KMP ViewModels & StateFlow<br>• MVI Architecture Pattern<br>• Reactive Event Pipeline"]
KMP_DOMAIN["<b>Domain Layer</b><br>• Health Longitudinal Telemetry Models<br>• Compounding Quotation Pipeline Rules<br>• Push-to-Sign Cryptographic Verification"]
KMP_DATA["<b>Offline-First Data Layer</b><br>• SQLDelight / Room KMP (Encrypted SQLCipher)<br>• Ktor Client (HTTP/3, TLS 1.3, SSL Pinning)<br>• kotlinx.serialization (JSON)<br>• Token Vault (Secure Storage Delegation)"]
end
subgraph OS_SUBSYSTEMS ["Native OS Subsystems"]
HK["Apple HealthKit / watchOS"]
SE["Apple Secure Enclave (P-256 ECC)"]
HC["Google Health Connect"]
SB["Android StrongBox HSM"]
end
subgraph BACKEND ["Cloud Native Backend (GCP & Cloudflare)"]
SERVER["api.gercia.com.br<br>(Cloud Run Minimal APIs)"]
PUSH["Firebase Cloud Messaging (FCM)<br>& Apple Push Notification Service (APNs)"]
end
IOS_UI --> KMP_STATE
AND_UI --> KMP_STATE
KMP_STATE --> KMP_DOMAIN
KMP_DOMAIN --> KMP_DATA
IOS_UI -- "Native Health Telemetry" --> HK
IOS_UI -- "Biometric HSM Signature" --> SE
AND_UI -- "Native Health Telemetry" --> HC
AND_UI -- "Biometric HSM Signature" --> SB
KMP_DATA -- "HTTPS / TLS 1.3 Pinning" --> SERVER
PUSH -- "High-Priority Silent Wakeup" --> IOS_UI
PUSH -- "High-Priority Silent Wakeup" --> AND_UI
Architectural Specifications:
Section titled “Architectural Specifications:”-
Shared Kotlin Core (
apps/mobile/shared):- Domain & State Logic: Encapsulates the entire multi-persona business logic, state machines (Patient Mode vs. Clinician Companion Mode), validation rules, and offline data synchronizers.
- Networking: Implements Ktor Client configured with HTTP/3, TLS 1.3 certificate pinning, automated JWT token refresh rotation (
Refresh Token Rotation), and structured error handling. - Persistence: Implements SQLDelight (or Room KMP) backed by SQLCipher for tamper-proof, zero-knowledge local caching of clinical telemetry and longitudinal records on disk.
- Concurrency: Leverages Kotlin Coroutines and Flow for structured, multi-threaded reactive pipelines seamlessly bridged to Swift
AsyncSequenceand Swift Concurrency (async/await).
-
iOS & watchOS Native Implementation (
apps/mobile/ios):- Presentation: Written entirely in SwiftUI, adhering strictly to Apple Human Interface Guidelines with zero third-party UI framework bloat.
- HealthKit Integration: Direct, unabstracted Swift interaction with
HKHealthStorefor real-time and background query synchronization of vitals (heart rate, blood glucose, sleep analysis, steps). - Push-to-Sign Biometrics: Utilizes
LocalAuthenticationandCryptoKitto generate hardware-protected P-256 elliptic curve keypairs stored in the Apple Secure Enclave. The private key never leaves the device’s hardware chip.
-
Android Native Implementation (
apps/mobile/android):- Presentation: Written entirely in Jetpack Compose with Material Design 3 dynamic color theming.
- Health Connect Integration: Direct integration with Android’s
HealthConnectClientusing official Jetpack libraries for consolidated read/write access to Android health data. - Push-to-Sign Biometrics: Utilizes
BiometricPromptand Android Keystore backed by StrongBox hardware (where available) to execute asymmetric signature operations requiring explicit user biometric presence.
-
Cryptographic Push-to-Sign Workflow:
sequenceDiagram
autonumber
actor Clinician as Clinician (At Desktop Web SPA)
participant Web as Angular Web SPA (app.gercia.com.br)
participant Server as Gercia.Server (Cloud Run)
participant APNs as APNs / FCM Push Gateway
participant Mobile as GERCIA Care (KMP iOS/Android)
participant HSM as Secure Enclave / StrongBox HSM
Clinician->>Web: Finalizes Digital Prescription / Lab Order
Web->>Server: POST /v1/prescriptions/{id}/request-signature
Server->>Server: Computes SHA-256 Digest & Generates Challenge Nonce
Server->>APNs: Sends High-Priority Sign Notification Payload
APNs->>Mobile: Wakes App / Displays "Authorize Prescription" Prompt
Mobile->>Clinician: Prompts Biometric Auth (FaceID / Fingerprint)
Clinician->>Mobile: Confirms Biometric Presence
Mobile->>HSM: Requests Cryptographic Sign(PrescriptionHash, Nonce)
HSM-->>Mobile: Returns Hardware ECDSA Signature
Mobile->>Server: POST /v1/signatures/verify (Signature, KeyId, Nonce)
Server->>Server: Validates Signature with Registered Public Key & Issues Audit Entry
Web->>Server: Polls Prescription Status (Short-Polling / SSE)
Server-->>Web: Prescription Sealed & Ready
Web-->>Clinician: Prescription Displays "Signed & Sealed" with ICP-Brasil QR Code
Consequences & Trade-offs
Section titled “Consequences & Trade-offs”Positive:
Section titled “Positive:”- Zero UI Abstraction Compromise: Native SwiftUI and Jetpack Compose deliver instantaneous 120Hz ProMotion/Smooth Display scrolling, instant cold starts (< 500ms), and zero UI bridge overhead.
- Direct Access to OS Capabilities: Eliminates third-party wrapper lag when integrating cutting-edge APIs from WWDC and Google I/O (e.g., Apple HealthKit, Health Connect, Live Activities, Dynamic Island, Android Home Screen Widgets).
- Maximum Security Assurance: Direct hardware anchoring of cryptographic keys in Apple Secure Enclave and Android StrongBox guarantees tamper-proof digital prescription signing compliant with Brazilian sanitary authorities (
ANVISA RDC 67/2007,CFM Res. 2.314/2022). - High Code Sharing: 70–80% of business logic, models, networking, cryptographic challenge handling, and offline caching are shared across platforms in pure Kotlin.
Trade-offs & Mitigations:
Section titled “Trade-offs & Mitigations:”- Two UI Codebases (SwiftUI + Compose):
- Trade-off: Requires proficiency in both SwiftUI and Jetpack Compose.
- Mitigation: Because both frameworks are modern declarative UI engines with nearly identical mental models, developers easily transfer knowledge. The heavy business and data layer is completely shared.
- Developer Environment Requirements:
- Trade-off: iOS builds require macOS and Xcode.
- Mitigation: In the monorepo, backend/Android developers can develop in JetBrains Rider or Android Studio on Windows/Linux; CI/CD builds for iOS continue to execute automatically via Codemagic cloud M1/M2 runners.
Decommissioning Plan
Section titled “Decommissioning Plan”- The legacy .NET MAUI project located at
dotnet/src/Clients/Gercia.Mobile/has been cleanly decommissioned and deleted from the monorepo, replaced byapps/mobile/. - All references to
Gercia.Mobile.csprojand thedotnet/src/Clients/folder insidedotnet/Gercia.slnxhave been permanently removed, unblocking developer workstations from needing .NET MAUI or Android workload installations.