Back to all work

Offline-First Mobile · Healthcare

Smart Care Mobile

Android healthcare delivery for remote Bangladesh clinics where internet doesn't exist. Everything works offline — forms, sync, access control.

KotlinJetpack ComposeSQLiteWorkManagerKoinLaravel
Smart Care Mobile screenshot 1
Smart Care Mobile screenshot 2
Smart Care Mobile screenshot 3
Smart Care Mobile screenshot 4

Overview

Smart Care Mobile is a native Android healthcare delivery system built for remote clinics across Bangladesh where reliable internet simply doesn't exist. The app powers offline-first data collection, dynamic form rendering, and bidirectional synchronization — all from a single Kotlin codebase spanning 294 files.

Healthcare workers use it daily to register households, conduct health screenings, and submit data that syncs when connectivity is available. The form engine renders entirely from database configuration, meaning new survey instruments deploy without touching a single line of code.

The system serves 1,000+ remote households across a multi-level geographic hierarchy, with role-based access control enforced from national level down to individual wards.

Hard Problems

Challenge

Database-driven form system with complex cross-field validation, conditional visibility, and placeholder resolution — at scale across dozens of survey instruments.

Solution

Custom FieldConfigEngine that parses SQL-like condition strings, resolves cross-field placeholders at render time, and validates against database-stored rules. Forms generate entirely at runtime from configuration tables.

Challenge

Bidirectional data sync over unreliable networks for 1,000+ households with conflict resolution and no data loss.

Solution

ZipSyncOrchestrator that batches records into compressed ZIP payloads, handles partial uploads with retry logic, and resolves conflicts using server-authoritative timestamps with local change tracking.

Challenge

6-level geographic access control (national → division → district → upazila → union → ward) with dynamic table resolution.

Solution

LocPathResolver pattern that dynamically resolves table names and access boundaries based on authenticated user's position in the hierarchy. Single query path regardless of access level.

Key Decisions

DecisionChoseOverBecause
Database layerRaw SQLiteRoom ORMNeeded direct SQL control for dynamic form queries, custom cursor mapping, and zero annotation processing overhead across 294 files.
Dependency injectionKoinHilt/DaggerFaster build times, lightweight Kotlin-first API, no annotation processing — critical for a 294-file codebase.
Architecture patternSSOT with centralized resolversDistributed logicEliminated code duplication across 294 files. Every data transformation has exactly one source of truth.

Tech Stack

languages

KotlinSQL

frameworks

Jetpack ComposeMaterial3RetrofitOkHttpKoin

data

SQLite (raw)WorkManagerKotlin Serialization

tools

Coroutines/FlowZIP4JEncrypted SharedPreferencesMaestroMockK