Architecting Offline-First Point-of-Sale: Integer Paisa Math and Transactional Sync Outboxes
How building a mission-critical native Android POS under intermittent connectivity led to zero float drift, atomic Room SQLite outboxes, and sub-second offline checkouts.
Key Architectural Takeaways
- ✓Never use IEEE-754 floating point numbers for financial calculations; enforce 64-bit Long integers representing fractional sub-units (paisa).
- ✓Local persistence must be the single source of truth; network synchronization should always occur asynchronously via an append-only transactional outbox.
- ✓CameraX barcode analysis should decouple frame analysis from the UI thread using coroutine channels to prevent dropped frames during checkout.
- ✓Sync protocols must employ client-generated UUID idempotency keys to guarantee exactly-once processing across intermittent network dropouts.
When designing point-of-sale (POS) systems for Indian retail, you must architect for a brutal operational reality: connectivity is intermittent, customer queues are relentless, and ledger accounting allows exactly zero margin for error. A software crash or a 3-second network freeze during evening peak hours destroys merchant trust instantly.
The IEEE-754 Financial Hazard: Floating Point Drift
To achieve complete byte-level financial correctness, we abolished Double and Float types from every domain entity, database schema, and in-memory cart accumulator. All monetary values are strictly modeled as 64-bit signed Long integers denominated in paisa (1 INR = 100 Paisa).
@JvmInline
value class MoneyPaisa(val paisa: Long) : Comparable<MoneyPaisa> {
operator fun plus(other: MoneyPaisa) = MoneyPaisa(this.paisa + other.paisa)
operator fun minus(other: MoneyPaisa) = MoneyPaisa(this.paisa - other.paisa)
operator fun times(qty: Int) = MoneyPaisa(this.paisa * qty)
fun toFormattedRupees(): String {
val rupees = paisa / 100
val remainder = Math.abs(paisa % 100)
return "₹%d.%02d".format(rupees, remainder)
}
override fun compareTo(other: MoneyPaisa): Int = this.paisa.compareTo(other.paisa)
}Local-First Storage Architecture with Room SQLite
In RetailOS, the local SQLite database running in Write-Ahead Logging (WAL) mode is the primary system of record. When the cashier hits "Complete Sale", the order, inventory decrement, customer credit entry, and thermal receipt payload are committed in a single atomic SQLite transaction within 4ms. The network is never in the critical path.
The Transactional Sync Outbox State Machine
Every local mutation generates an immutable event in the sync_outbox table within the same transaction. A dedicated background coroutine daemon continuously polls for PENDING outbox records, attempts dispatch to the cloud edge with exponential backoff and jitter, and marks records COMPLETED only upon receiving signed cloud acknowledgments. If the device reboots or loses power mid-sync, the atomic transaction ensures zero state divergence.
High-Throughput CameraX Barcode Pipeline
To replace expensive handheld hardware scanners, we implemented a zero-latency CameraX ML Kit barcode analyzer. By throttling frame analysis to a single active worker thread and feeding detected UPC/EAN codes into an in-memory Trie index of 10,000 local SKUs, product resolution completes in under 45ms without dropping Compose UI render frames.
Production Invariants and Edge Failure Recovery
- Zero-Float Mathematical Invariant: Every financial calculation is verified with property-based unit tests asserting zero rounding deviation over 1,000,000 simulated cart operations.
- Sub-Second Checkout Budget: Cash and Udhaar transactions complete in <200ms from scan to printed Bluetooth receipt.
- Idempotent Replication: Sync outbox payloads carry client-generated UUIDv4 keys, guaranteeing that retransmitted packets during intermittent 4G handoffs never duplicate ledger entries.
- Airgap Survival: The full inventory, billing, customer credit book, and thermal receipt pipeline remains 100% operational with the radio physically powered off for weeks.
Need similar mission-critical architecture for your venture?
Harvinder partners with founders and engineering leaders as Fractional CTO, conducts deep-dive architecture audits, and engineers production-grade distributed systems.