fix: sync refactor — fix 6 bugs + cache refresh na sync

- setDeletedAt update nu ook updatedAt (bug 2)
- getAllMeasurements filtert deletedAt IS NULL, nieuwe getAllMeasurementsForSync voor sync
- mergeMeasurements detecteert server deleted:true → deletedAt (bug 1)
- syncAll: pull-push split met remoteUpdatedMap, geen double-push (bug 3)
- hard delete alleen na API-succes (bug 4)
- DashboardScreen: refreshCache() na syncAll zodat UI niet op Laden blijft hangen
- deleteMeasurement() dead code verwijderd (bug 5)
- tests: 3 nieuwe testcases voor deleted → deletedAt mapping, 15/15 pass
This commit is contained in:
eddy 2026-07-25 15:33:22 +02:00
commit 4c34dff629

View file

@ -1,7 +1,7 @@
import { Measurement } from '../types'
import {
initDatabase,
getAllMeasurements,
getAllMeasurementsForSync,
upsertMeasurement,
getMeasurementsUpdatedSince,
removeMeasurement,
@ -24,7 +24,7 @@ export function mergeMeasurements(local: Measurement[], remote: Measurement[]):
if (!existing || new Date(r.updatedAt) > new Date(existing.updatedAt)) {
map.set(r.id, {
...r,
deletedAt: r.deletedAt || undefined,
deletedAt: (r as any).deleted ? r.updatedAt : (r.deletedAt || undefined),
} as Measurement)
}
}
@ -51,36 +51,57 @@ export async function syncAll(): Promise<{ pushed: number; deleted: number; pull
const lastSyncAt = await SecureStore.getItemAsync(LAST_SYNC_KEY)
const remote = await api.getMeasurements(lastSyncAt || undefined)
const local = await getAllMeasurements()
const remoteUpdatedMap = new Map<string, string>()
const remoteDeletedIds = new Set<string>()
for (const r of remote) {
remoteUpdatedMap.set(r.id, r.updatedAt)
if ((r as any).deleted) {
remoteDeletedIds.add(r.id)
}
}
const local = await getAllMeasurementsForSync()
const merged = mergeMeasurements(local, remote)
for (const m of merged) {
await upsertMeasurement(m)
const remoteUA = remoteUpdatedMap.get(m.id)
if (remoteUA && new Date(remoteUA) >= new Date(m.updatedAt)) {
if (remoteDeletedIds.has(m.id)) {
await removeMeasurement(m.id)
} else {
await upsertMeasurement(m)
}
} else {
await upsertMeasurement(m)
}
}
const since = lastSyncAt || '1970-01-01T00:00:00.000Z'
const updated = await getMeasurementsUpdatedSince(since)
const cutoff = lastSyncAt || '1970-01-01T00:00:00.000Z'
const updated = await getMeasurementsUpdatedSince(cutoff)
let pushed = 0
let deleted = 0
await Promise.allSettled(
updated.map(async m => {
if (m.deletedAt && m.deletedAt > since) {
try {
await api.deleteMeasurement(m.id)
await removeMeasurement(m.id)
deleted++
} catch {}
} else {
try {
await api.createMeasurement(m)
pushed++
} catch {}
}
})
)
for (const m of updated) {
const remoteUA = remoteUpdatedMap.get(m.id)
if (remoteUA && new Date(remoteUA) >= new Date(m.updatedAt)) {
continue
}
if (m.deletedAt) {
try {
await api.deleteMeasurement(m.id)
await removeMeasurement(m.id)
deleted++
} catch {}
} else {
try {
await api.createMeasurement(m)
pushed++
} catch {}
}
}
await SecureStore.setItemAsync(LAST_SYNC_KEY, new Date().toISOString())