Offline Database & Synchronization Engine
To support rural outreach and services in buildings with poor internet connectivity, Kononia implements a complete offline-first database queue using the browser’s native IndexedDB API.
1. Queue Architecture (offlineDb.ts)
When network connectivity is lost, database write operations are intercepted and cached locally in an IndexedDB database named KononiaOfflineDB.
Table Coverage
The offline database queues write payloads for four core tables:
attendance_recordspastoral_casespastoral_followupsform_submissions
Queue Record Schema
Every cached record contains system-level metadata to track sync attempts:
| Field | Type | Description |
|---|---|---|
_localId | String (UUID) | Client-generated unique identifier serving as a temporary primary key. |
_table | String (Enum) | Destination database table where the record will be synced. |
_syncStatus | String (Enum) | Synchronization status (pending, syncing, or failed). |
_createdAt | String (ISO Timestamp) | Date and time when the record was initially saved offline. |
_errorMessage | String (Optional) | Detailed error message from the last failed sync attempt, if any. |
_retries | Number | Counter tracking the number of synchronization attempts made. |
payload | Object (JSON) | Actual data payload (fields and values) to insert into the database. |
2. Synchronization Lifecycle (syncManager.ts)
Once connectivity is restored, the client attempts to flush the queue.
Sync Triggers
- Online Event Listener: The application listens to the browser’s native
window.addEventListener("online")event to trigger syncs. - Background Sync API: If supported by the browser, the Service Worker registers a
kononia-syncevent, allowing updates to sync even if the user closes the app. - Manual Action: Servants can click a Sync Now button in the
<SyncStatusBanner>component at the bottom of the screen.
Transaction Flow
- Status Lock: The manager selects pending records and marks them
_syncStatus = "syncing"to prevent concurrent double-sends. The retry count is incremented by 1. - Database Insertion: The client attempts to insert the payload into the Supabase database.
- Queue Cleanup:
- Success: The temporary record is deleted from IndexedDB.
- Failure: The record status reverts to
'failed'and the error description is saved in_errorMessage.
- Max Retries Policy: If a record fails to sync 5 times, it is flagged with a permanent error (
"failed"with"Max retries exceeded"). The system stops retrying automatically to prevent API thrashing, keeping the record stored locally so the user can inspect or download it.