Skip to main content

Syncing (Duo)

In cloud mode the plan belongs to a household, and users are linked to it. A second person joins with an invite code.

Sharing model

  • One household = one shared state (jsonb).
  • Members are linked through a membership table.
  • Access is enforced by Row Level Security — only a member can read and change their household's state.
  • The state is end-to-end encrypted; the household's encryption key is shared with the invited partner via key exchange, so neither we nor third parties can read it.

Save with merge

The state is written as a whole, with optimistic concurrency control:

  1. The app remembers the updated_at marker of the state it last fetched.
  2. On save, it sends that marker. If someone wrote in the meantime, the markers diverge → a conflict is detected.
  3. The app then fetches the fresh state and merges: month-keyed maps (entries, snapshots) are combined, and the remaining fields are taken from the newer side by updated_at. This way "two people filling in different months" doesn't lose data.

Fetching and refreshing

The state is fetched when you enter the household and when you return to the tab/window, keeping both people in sync.

Leaving and deleting

  • Leave the household — revokes this account's access; when the last member leaves, the household (and its state) is removed so no orphaned data is left.
  • Delete account — removes any household where you're the only member (GDPR).