Shared reference for Web/iOS/Android: canonical keys, default flags, the GET/PUT sync_flags API, and the pull/push rules each client implements. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2.9 KiB
2.9 KiB
Settings sync contract (Web / iOS / Android)
Per-setting, cross-device synchronisation of user settings. The server is the sole authority for which settings sync; clients must not duplicate that logic. This document is the shared contract all three clients implement identically.
Canonical keys & default flags
Source of truth: DEFAULT_SYNC in backend/routers/settings_router.py. Keys use
the server's snake_case field names.
| Key | Kind | Default sync |
|---|---|---|
default_view |
enum | ON |
week_start_day |
enum | ON |
dim_past_events |
bool | ON |
hour_height |
enum(int) | ON |
primary_color accent_color today_color text_color line_color bg_color month_divider_color month_label_color |
color hex | ON |
default_event_duration_minutes |
enum(int) | ON |
default_reminder_minutes |
enum(int, null=off) | ON |
language |
enum | OFF |
share_calendar_icon |
icon key | OFF |
cache_months |
enum(int) | OFF |
month_view_paged |
bool | OFF |
Settings not in this list are never synced by this mechanism:
- Account-wide settings (
private_event_visibility,group_visible_calendar_id,directory_hidden) — one value per account, always identical everywhere; they keep their existing dedicated endpoints/UI, not a sync toggle. - Platform-exclusive device prefs (e.g. iOS
liquid_glass) — stay device-local. - Identity/security, calendar/account management, admin.
API
GET /api/settings/returns every value plussync_flags: a fully-resolved{key: bool}map covering exactly the keys above (stored overrides on top ofDEFAULT_SYNC). Clients read this map verbatim — no client-side defaults.PUT /api/settings/accepts a partialsync_flagsmap (merged account-wide, unknown keys ignored, untouched flags preserved) and partial value fields (exclude_unset;text_color/line_color/bg_color/… treated as nullable-reset perNULLABLE_OVERRIDES).
Client rules
Each client keeps a local copy of every syncable value (UserDefaults / DataStore-SharedPreferences / localStorage) so that "not synced" works per device.
- On login / launch / foreground:
GET /api/settings/→ values +sync_flags. - Pull: for each syncable key, if
sync_flags[key]is ON, adopt the server value into the local copy; if OFF, keep the local value. - Push (debounced, read-modify-write): start from the current server snapshot,
overwrite only keys whose flag is ON with the local value,
PUT. Never push a key whose flag is OFF. - Toggle a flag ON: set the flag true and push this device's current local value (it becomes the shared value). OFF: set false; keep the local value.
- Global "share everything": set all syncable flags true and push all local values. Global off: set all false.
The flag map itself is always account-wide and always fetched fresh; it is what a client consults to decide what to send/receive.