core/offline_outbox_service library

Classes

OfflineOutboxService
Persisted, priority-drained outbox for syncing local changes to a remote authority once back online — built on RetryExecutor (FEAT-35) for transient-failure backoff and, when connectivity is supplied, driven automatically by ConnectivityCoordinator (FEAT-62)'s online transitions the same way that service drains its own internal task queue.
OutboxItem
One queued, not-yet-synced unit of work. payload is plain, caller-defined JSON data — same "never put a secret in it, it's persisted locally in plain JSON" caveat as RewardTransactionRecord.receiptMeta (FEAT-42).
SyncAck
The remote authority accepted the payload as-is.
SyncConflict
The remote authority's state for this OutboxItem.idempotencyKey has diverged from what was queued — remotePayload is its current value, handled per ConflictPolicy.
SyncOutcome
Result of one OutboxUploader call.

Enums

ConflictPolicy
What to do when OfflineOutboxService uploads an item and the remote authority reports its state has diverged from what was queued locally.
ManualResolution
What a caller decided for an item sitting in OfflineOutboxService.manualReviewItems.

Typedefs

ConflictMerger = Map<String, Object?> Function(Map<String, Object?> local, Map<String, Object?> remote)
A ConflictPolicy.merge resolution: given the payload that was queued locally and the authority's current payload for the same key, return the payload to re-upload. Must be pure/deterministic — same inputs, same output — since a crash between the merge and the retry may run it again.
OutboxUploader = Future<SyncOutcome> Function(Map<String, Object?> payload, String idempotencyKey)
Attempts to sync one item with whatever remote authority a consumer app wires up (a REST endpoint, a cloud function, ...) — this service knows nothing about the transport. Throwing (a network error, a timeout) is treated as transient and retried per OfflineOutboxService.retryPolicy; returning a SyncOutcome is the only way to report a definitive accept/conflict. idempotencyKey is passed on every attempt (including retries after a crash) specifically so the remote side can dedupe a request it already applied.