-
Notifications
You must be signed in to change notification settings - Fork 3
Sync engine: push + pull + last-write-wins #126
Copy link
Copy link
Open
Description
Parent PRD
Depends on
#125 (offline write queue), #121 (delta API endpoints with modifiedAfter)
Summary
Implement SyncService — triggered on App.OnResume and Connectivity.ConnectivityChanged (online transition). Push queued local changes to the API, then pull any remote changes since last sync. Apply last-write-wins conflict resolution using DateModified.
SyncService — push phase
- Query all local records where
IsPendingSync = true - PATCH/POST each to the API
- On success, clear
IsPendingSync = false - Soft-deleted records pushed as deletes, then removed locally on success
SyncService — pull phase
- Call
GET /api/posts?modifiedAfter={LastSyncTimestamp} - Call
GET /api/notes?modifiedAfter={LastSyncTimestamp} - For each returned record, compare
DateModifiedagainst local copy - Keep whichever has the later
DateModified(last-write-wins) - Update
LastSyncTimestamp = DateTime.UtcNowinPreferencesafter successful sync
Trigger points
App.OnResume(foreground sync when resuming app)Connectivity.ConnectivityChangedevent when transitioning to online
Tests (unit — mock dependencies)
- Push phase: sends all
IsPendingSync=truerecords; clears flag on success - Pull phase: remote newer → remote wins; local newer → local wins
LastSyncTimestampupdated after successful full sync- Use xUnit + FluentAssertions + Moq (already in codebase)
Acceptance Criteria
-
SyncServiceimplemented with push and pull phases - Triggered on app resume and connectivity restored
- Last-write-wins applied correctly on both sides
-
LastSyncTimestamppersisted inPreferences - Unit tests pass for push, pull, and conflict resolution
Stories from PRD
User stories 7, 8, 17, 18, 19
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Projects
Status
Backlog
Status
No status