Offline-first & sync
Trakli is offline-first. The app does not wait for the network to let you work. It writes everything to a local database first, and reconciles with the backend when a connection is available. This page explains how that reconciliation works.
Local first
Section titled “Local first”Every change you make (a new transaction, an edited wallet, a deleted category) is written to the device’s local database immediately, and recorded in a queue of pending changes. The app stays responsive and fully usable with no connection.
Client-generated IDs
Section titled “Client-generated IDs”Because records can be created offline, the client assigns each one an identifier before the server has ever seen it. This client-generated ID has the form:
{device_uuid}:{entity_uuid}The first part identifies the device; the second is a unique ID for the record. Both parts are UUIDs. This lets a record exist and be referenced locally, then be matched to its server row once it syncs, without collisions across devices.
Two phases of sync
Section titled “Two phases of sync”Sync runs in two directions:
- Upload. The app sends its queue of pending changes to the server (creates and updates), in dependency order. Wallets, categories, parties, and groups sync before transactions, so a transaction never references something the server has not received yet.
- Download. The app asks the server for anything changed since it last synced, using a
synced_sincetimestamp, and applies those changes locally. This pull includes deletions, so a record removed on another device is removed here too.
synced_since
Section titled “synced_since”The download phase uses a query parameter, synced_since, an ISO 8601 timestamp. The server returns every record updated after that moment, including soft-deleted ones, so the client can mirror deletions as well as edits. The client stores the latest sync time and sends it on the next pull.
Conflict handling
Section titled “Conflict handling”When the same record is edited in two places, Trakli resolves it with last-write-wins. The upload applies your change; the next download brings down the server’s current version. The most recent write is what every device converges on.
Why it is built this way
Section titled “Why it is built this way”The result is an app that is fast and usable anywhere, and a backend that stays the single source of truth. You are never blocked by a missing connection, and your devices converge on the same data once they sync.