Skip to content

SyncNotify: no way to distinguish initial catch-up sync from live remote changes (notification flood on fresh login) #114

Description

@pvg13

Summary

SyncNotify::on_sync fires for every remote insert, with no way to tell an
initial catch-up sync (a device pulling existing rows on fresh login/first
open) apart from a live incremental change from a peer. Both arrive as
ChangeSource::Remote. The result downstream: logging in on a new/reset device
floods the user with notifications for the household's entire pre-existing
history ("Plan de la semana — hay novedades", one per existing row), even though
nothing actually just happened.

Repro (consumer side)

  • App with a SyncNotify policy on a household table (meal plan / shopping list).
  • Clear local state (or install on a new device) and log in to an account whose
    household already has data.
  • Initial sync applies all existing rows as Remote inserts → on_sync fires
    for each → a burst of "new activity" notifications for old data.

Why the consumer can't fully fix it

  • The policy CAN suppress self-authored rows (comparing a stored added_by
    user id to the current user) — we do this now. But rows authored by other
    household members during catch-up still notify, which is wrong: it's history,
    not new activity.
  • ChangeSource::Remote { peer_site } carries only the originating device site
    id. There's no signal for "this batch is initial hydration vs a live delta,"
    and no per-change timestamp/watermark the policy could compare against a
    session-start marker.

Request

Expose enough for a policy to distinguish initial catch-up from live changes.
Any one of:

  1. A variant/flag on ChangeSource (or SyncEvent), e.g.
    Remote { peer_site, initial_sync: bool }, set true while applying the
    backlog a peer sends on (re)join, false for live gossip deltas.
  2. A SyncEvent field for the change's logical clock / commit time, so the
    consumer can gate on "newer than the local session-start watermark."
  3. A builder/engine hook to suppress on_sync entirely during the initial
    hydration window (fire only for changes applied after steady state).

Option 1 is the smallest and most direct. Happy to test against the
Mediterranea household-plan / shopping-list notifications.

Context

Related to #113 (same SyncNotify path). The self-authored half is fixed
consumer-side; this initial-sync half needs the upstream signal.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions