mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 14:16:12 +00:00
fix(sync): expire delta cursors issued before a restore or a data wipe
A restore writes rows back with their original updatedAt, behind every paired client's watermarks, and removes rows without leaving tombstones. A client that kept its cursor would miss both on its next incremental pull. The same holds after the person deletes all their data. `users.sync_reset_at` (migration 0363) records when the record was last replaced: the restore stamps it as its last write and again right after the commit, the per-account and the admin wipe stamp it inside their transactions. Cursors now carry the time they were issued, and /api/sync/changes answers its existing `cursorExpired` to a cursor issued before the reset, or one without an issue time on an account that has one. The comparison is on the issue time, because after a restore a freshly drained cursor still carries old watermarks.
This commit is contained in:
1 parent
419ff04765
commit
eda87fd4a7
14 files changed
+375
-13
No files matched your search
@@ -0,0 +1,6 @@
|
||||
-- When an account's record was last replaced wholesale (a backup restore, or
|
||||
-- the person deleting all their data). `/api/sync/changes` expires every
|
||||
-- delta cursor issued before it, so a paired client re-initialises instead
|
||||
-- of catching up from a position the restore invalidated. Nullable: an
|
||||
-- account that was never restored or wiped has no reset to honour.
|
||||
ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "sync_reset_at" TIMESTAMP(3);
|
||||
@@ -503,6 +503,14 @@ model User {
|
||||
// instead of running ahead of one.
|
||||
lastSyncedAt DateTime? @map("last_synced_at")
|
||||
|
||||
// When the account's record was last replaced wholesale: a backup restore
|
||||
// committed, or the person deleted all their data. `/api/sync/changes`
|
||||
// answers `cursorExpired` to any cursor issued before it, because such a
|
||||
// cursor can no longer be caught up incrementally: a restore writes rows
|
||||
// back with their original `updatedAt` and removes rows without leaving a
|
||||
// tombstone, so the delta from an old cursor would miss both.
|
||||
syncResetAt DateTime? @map("sync_reset_at")
|
||||
|
||||
// v0.5.4 ios-coord — daily mood-reminder opt-in.
|
||||
//
|
||||
// When `true` the reminder worker dispatches a `MOOD_REMINDER`
|
||||
|
||||
Reference in new issue
Block a user