# Sync API Base URL: `/api/sync` All endpoints require authentication. ## Overview The sync protocol uses checksums to efficiently synchronize noots between client and server. ## Endpoints ### POST / Full sync operation. **Request:** ```json { "noots": [ { "id": "uuid", "version": 2, "checksum": "sha256...", "activities": [...] } ], "knownNoots": [ {"id": "uuid-1", "checksum": "sha256..."}, {"id": "uuid-2", "checksum": "sha256..."} ] } ``` **Response (200):** ```json { "serverNoots": [ { "id": "uuid", "version": 3, "checksum": "sha256...", "activities": [...] } ], "deletedIds": ["uuid-3", "uuid-4"], "accepted": ["uuid-1"], "conflicts": [] } ``` ### Request Fields | Field | Description | |-------|-------------| | noots | Local noots with pending changes | | knownNoots | Checksums of all local noots | ### Response Fields | Field | Description | |-------|-------------| | serverNoots | Noots that differ from client | | deletedIds | Noots deleted on server | | accepted | Client noots accepted by server | | conflicts | Noots with version conflicts | --- ### GET /checksums Get server checksums for comparison. **Response (200):** ```json { "noots": [ {"id": "uuid-1", "checksum": "sha256..."}, {"id": "uuid-2", "checksum": "sha256..."} ] } ``` --- ### POST /fetch Fetch specific noots by ID. **Request:** ```json { "nootIds": ["uuid-1", "uuid-2", "uuid-3"] } ``` **Response (200):** ```json { "noots": [ { "id": "uuid-1", "version": 1, "activities": [...] } ] } ``` --- ## Sync Algorithm ### Client-Side 1. Get local checksums 2. Send to `/sync` with pending changes 3. Apply server changes 4. Mark conflicts for resolution ```dart // Simplified sync flow final localChecksums = nootPool.getChecksums(); final pendingNoots = nootPool.syncQueue .map((e) => e.noot.toJson()) .toList(); final result = await apiClient.sync( noots: pendingNoots, knownNoots: localChecksums, ); // Apply server changes nootPool.mergeFromServer( result.serverNoots, result.deletedIds, ); // Clear synced items nootPool.clearSyncQueue(); ``` ### Conflict Resolution **Strategy: Last-Write-Wins** - Higher `version` number takes precedence - If versions equal, server wins - Conflicts array returned for manual resolution --- ## Checksum Format SHA-256 hash of normalized JSON: ```dart String generateChecksum(Noot noot) { final normalized = jsonEncode({ 'activities': noot.activities.map((a) => a.toJson()).toList(), }); return 'sha256:${sha256.convert(utf8.encode(normalized))}'; } ```