Mobile EMR Client

Comprehensive Technical Documentation & Offline Sync Reference

1. System Overview

The Mobile EMR Client is an offline-first companion application designed for clinic practitioners and community health workers conducting field care. It enables clinical data entry (such as patient registration, consultation logs, vitals, scheduling, and billing payments) in rural or poorly connected areas, queues transactions locally, and synchronizes automatically when network availability is restored.

Core Technical Stack

2. Local Database Schema & Drift Models

The mobile app maps a specific subset of the backend database entities inside database/app_database.dart using Drift tables.

Local Table Definitions

Sync Tracking Architecture

Drift models do not use incremental integer primary keys (e.g. id) for sync-sensitive data. Instead, they rely on UUIDv4 strings (defined as uuid primary keys in the SQLite tables) generated locally on creation. Each syncable table maintains three metadata attributes to track local state:

Field Name Type Function Description
uuid Text (36 char) Unique lookup key across client and server. Matches the backend Eloquent UUID fields.
isDirty Boolean Defaults to false. Set to true on record creation or local updates. Indicates mutation needs upload.
isDeleted Boolean Defaults to false. Set to true during soft deletes. Holds deletion status until synced.
updatedAt Text ISO-8601 timestamp tracking when the record was last modified on the client. Used for conflict resolution.

3. Offline Synchronization Protocol

The offline synchronization workflow (implemented in SyncService) is a robust, bidirectional state machine that coordinates with the backend's SyncController:

Phase 1: Query Local Mutations

The sync scheduler gathers all locally modified rows where isDirty = true or isDeleted = true from all five syncable tables.

Phase 2: API Payload Construction

Selected rows are mapped into JSON schema payloads. The payload embeds the locally stored last_sync_timestamp (tracking when the client last synchronized) alongside the mutation lists.

Phase 3: HTTP Sync Request & Conflict Resolution

The client calls the backend /api/sync endpoint. The backend server acts as the final arbitrator:

  • If the client sends an update for a record that has a newer updated_at timestamp on the server, the server rejects the client change (Server Wins).
  • Accepted updates overwrite the server's records. Soft-deleted items are processed accordingly.
Phase 4: Media Uploads Routing

For patients with new local avatar images (such as gallery pictures or camera captures), the client uploads the binary content to /api/patients/{uuid}/avatar. It maps the returned remote URL to the local patient record, ensuring offline placeholders are replaced by actual cloud asset paths.

Phase 5: Local Database Consolidation

The operation wraps the local updates in a single Drift database transaction:

  • Clears the isDirty flag on successfully synced elements.
  • Purges records where isDeleted was flagged locally.
  • Applies incoming server updates (new registrations, changed care plans) since the last sync.
  • Saves the new server_timestamp response as the updated sync reference.