Skip to content

Sync engine: push + pull + last-write-wins #126

@fboucher

Description

@fboucher

Parent PRD

#110

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

  1. Query all local records where IsPendingSync = true
  2. PATCH/POST each to the API
  3. On success, clear IsPendingSync = false
  4. Soft-deleted records pushed as deletes, then removed locally on success

SyncService — pull phase

  1. Call GET /api/posts?modifiedAfter={LastSyncTimestamp}
  2. Call GET /api/notes?modifiedAfter={LastSyncTimestamp}
  3. For each returned record, compare DateModified against local copy
  4. Keep whichever has the later DateModified (last-write-wins)
  5. Update LastSyncTimestamp = DateTime.UtcNow in Preferences after successful sync

Trigger points

  • App.OnResume (foreground sync when resuming app)
  • Connectivity.ConnectivityChanged event when transitioning to online

Tests (unit — mock dependencies)

  • Push phase: sends all IsPendingSync=true records; clears flag on success
  • Pull phase: remote newer → remote wins; local newer → local wins
  • LastSyncTimestamp updated after successful full sync
  • Use xUnit + FluentAssertions + Moq (already in codebase)

Acceptance Criteria

  • SyncService implemented with push and pull phases
  • Triggered on app resume and connectivity restored
  • Last-write-wins applied correctly on both sides
  • LastSyncTimestamp persisted in Preferences
  • Unit tests pass for push, pull, and conflict resolution

Stories from PRD

User stories 7, 8, 17, 18, 19

Metadata

Metadata

Assignees

No one assigned

    Labels

    apppending-epicFinished but waiting for epic branch to merge

    Projects

    Status
    pending
    Status
    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions