Summary
Add an auto-sync option to Formulus profile settings, so the active profile can periodically sync while Formulus is in the foreground, without noisy failure UX.
Depends on: Formulus multi-profile / multiple Synkronus settings support (same idea as ODE Desktop profiles) already being implemented. Do not start this until that lands.
Out of scope: ODE Desktop — Formulus only for now. No background/OS-scheduled sync in this issue.
Settings UI (profile page)
- Toggle (slider) to enable auto-sync — default off.
- When the toggle is on, reveal a panel with:
- Interval dropdown
- Status indicator (dot + label) — see below
- Short copy that auto-sync runs only while Formulus is active/foregrounded (e.g. while using the app / filling forms), not when backgrounded or killed
- When the toggle is off, hide that panel (interval control not shown; treat as disabled).
- Interval dropdown values: 30s, 2m, 5m, 15m, 1h, 24h — default 5m.
- Interval control is only meaningful when auto-sync is on (lives in the revealed panel).
Scheduling
- Foreground only: timer/logic active while the app is active; no background sync for this feature.
- Interval measured from last successful sync.
- On enable, app resume, or coming online: wait for the next interval (do not fire immediately).
- Active profile only — do not auto-sync inactive profiles even if they have the setting on.
- Profile switch: cancel any in-flight auto-sync, then switch.
- Debounce / locking: do not queue auto-sync. If a sync is already running (auto or manual), skip the scheduled tick. Share one sync lock with manual sync and the custom-app bridge
sync().
- If the user starts a manual sync, cancel an in-flight auto-sync; manual sync keeps today’s error/toast behavior.
- Auto-sync itself is silent on failure (no “sync failed” pop-ups).
Sync scope
- Same pipeline as manual sync except omit app-bundle update.
- Silent: do not drive the Sync screen / intrusive progress UI; profile status indicator is enough. For detail, user runs manual sync.
Connectivity & status indicator
Coloured dot on the profile UI (with label):
| State |
Dot |
Label / behavior |
| Auto-sync off |
Gray |
(panel hidden; no auto-sync status needed) |
| Auto-sync on, idle, last success OK |
Green |
Last sync relative time (see format) |
| Actively auto-syncing |
Green, smooth blink (“HAL 9000” style, green) |
Auto-syncing (no x/y) |
| Device offline |
Red |
Offline + last sync relative time |
Network up but Synkronus /health fails |
Red |
Connection failed (+ last sync relative time if useful) |
| Auto-sync on, online, last attempt failed (non-auth) |
Amber |
Reflect failure without a modal; keep last-success time if available |
| Auth / login failure |
Red |
Login failed (silent — no forced re-login prompt from auto-sync) |
Relative time format: rounded integer + unit — minutes / hours / days / months ago (e.g. 5 minutes ago, 2 hours ago).
Form entry concurrency
Allow auto-sync while Formplayer / forms are open unless implementation finds clear drawbacks (e.g. observation write contention with in-progress drafts). If conflicts appear, pause auto-sync during active form sessions and document that in the PR.
Acceptance criteria
Implementation notes
- Reuse existing sync services / progress where practical, but keep auto-sync UX on the profile panel.
- Prefer device connectivity plus
/health for the red label split.
- Watch battery/CPU on 30s interval while foregrounded; no background work in v1.
Summary
Add an auto-sync option to Formulus profile settings, so the active profile can periodically sync while Formulus is in the foreground, without noisy failure UX.
Depends on: Formulus multi-profile / multiple Synkronus settings support (same idea as ODE Desktop profiles) already being implemented. Do not start this until that lands.
Out of scope: ODE Desktop — Formulus only for now. No background/OS-scheduled sync in this issue.
Settings UI (profile page)
Scheduling
sync().Sync scope
Connectivity & status indicator
Coloured dot on the profile UI (with label):
Auto-syncing(no x/y)Offline+ last sync relative time/healthfailsConnection failed(+ last sync relative time if useful)Login failed(silent — no forced re-login prompt from auto-sync)Relative time format: rounded integer + unit — minutes / hours / days / months ago (e.g.
5 minutes ago,2 hours ago).Form entry concurrency
Allow auto-sync while Formplayer / forms are open unless implementation finds clear drawbacks (e.g. observation write contention with in-progress drafts). If conflicts appear, pause auto-sync during active form sessions and document that in the PR.
Acceptance criteria
sync(); manual cancels auto; auto skips if busy.Implementation notes
/healthfor the red label split.