5.4 KiB
Synchronization and integrations
Offline-first model
The Companion writes user actions to an encrypted local SQLite database first, then appends an outbox operation in the same transaction. Reads render local state immediately. Server changes arrive through incremental pull and are merged into the local model.
Sync is incremental, batched, resumable, idempotent, deletion-aware, and safe across multiple devices. It never assumes continuous connectivity.
Protocol
Each mutation carries an operation ID, device ID, object ID, expected/base version, client timestamp, payload hash, and deletion state. The server records operation IDs and returns the prior result when retried. Server versions are monotonic per object.
Recommended flow:
sequenceDiagram
participant C as Companion
participant A as Go API
participant P as PocketBase
C->>A: push batch with idempotency keys
A->>A: authenticate, verify device, authorize, validate
A->>P: apply accepted mutations transactionally
P-->>A: versions and cursor
A-->>C: per-operation results
C->>A: pull changes after cursor
A-->>C: bounded changes plus next cursor
C->>C: merge and checkpoint transactionally
Do not delete outbox work until the acknowledgement is durably committed locally. Use exponential backoff with jitter and a retry ceiling; permanent validation/auth conflicts remain visible to the user.
Conflicts
- Immutable source samples deduplicate by source identity and version.
- User-edited records use optimistic concurrency. On divergent edits, preserve both candidate values or request an explicit choice rather than silently overwriting sensitive data.
- Deletion wins only when based on a version at least as new as the competing update; otherwise surface a conflict.
- Server-assigned ownership, security settings, and role changes never use client last-write-wins.
Scheduling and connectivity
Attempt sync at startup, on manual request, and after data entry/edit/delete, scale measurement, or photo capture when connectivity exists. Health Connect periodic choices are manual, 6h, 12h, or 24h, with Wi-Fi-only versus any-network preference.
Use Android WorkManager with battery/network constraints and acknowledge that schedules are approximate. Coalesce work, transfer compact batches, stop retry loops when the server is unavailable, and show last success/error without notifications.
Health Connect
Use the official Android Health Connect SDK through a maintained Flutter plugin only if it exposes required semantics; otherwise implement a small Kotlin bridge. Request only data categories actually used and guide users to manage permissions.
Support reading relevant heart rate, resting heart rate, sleep, activity, workout, distance, calories, weight, and body composition records when providers publish them. Background and historical read permissions are requested only with clear user-facing justification.
Store Health Connect change tokens/cursors locally and handle insertions, updates, and deletions. Preserve provider package/source metadata.
Writing scale data
With explicit user opt-in, write supported Xiaomi scale results to Health Connect. Use a stable clientRecordId derived from the local measurement ID and increment clientRecordVersion on correction. Re-syncing the same local record MUST update/idempotently reconcile rather than create duplicates.
Weight is measured. Impedance stays in EvolioHealth when no interoperable record exists. Fat, water, bone, basal metabolic rate, and similar outputs are clearly tagged as estimates/calculations with formula version. Only write supported record types and do not misrepresent estimated values as directly measured.
For edits/deletion, ask whether the action affects EvolioHealth only or also the record originally written by EvolioHealth to Health Connect. Never mutate third-party source records silently.
Kinomap
Assume users rely on a Kinomap subscription and Kinomap publishes workouts through Health Connect. Do not open a competing live BLE connection to the rowing machine. Import the Kinomap exercise as the primary session and associate temporally compatible Pixel Watch/Fitbit heart-rate series without destroying source separation.
Historical TCX/PWX/GPX import may be added later with explicit unit and provenance parsing.
Xiaomi Mi Body Composition Scale 2
The Companion connects directly via BLE. Implementation must be based on verified advertisements/services and test captures for the exact scale, not undocumented assumptions. It should obtain stable weight, impedance, measurement-stable/final flags, and available diagnostics.
Requirements:
- scan only while the user initiates or enables the measurement workflow;
- identify the intended scale and avoid accepting nearby devices accidentally;
- distinguish incomplete/unstable from final readings;
- prevent duplicate final measurements from repeated advertisements;
- assign the reading to the authenticated local profile with explicit confirmation when ambiguity exists;
- version and test composition formulas and label outputs as estimates;
- save locally before attempting Health Connect or server sync.
Sync observability
Users see last server sync, last Health Connect import, pending operation count, network policy, and sanitized failures. Administrators see service health and aggregate queue/error counts but not personal values. Logs carry request and operation IDs without payload content.