Cloud sync (Profile)
Desktop-app-only feature. The web SPA doesn't show these panels.
Profile → Cloud sync is your window into the machine's bidirectional sync with the cloud. The header shows which cloud you're signed in to and when the last sync ran, with a Sync now button and a sign-out action; below it, three sub-tabs:
- Projects — which projects are downloaded for offline use
- Pending — unsynced local work, reviewable per row
- Activity — what synced when, with what result
Backed by the afri_sync module — see
Offline sync for the architecture.
Accounts on the desktop: device-only or cloud
Sign-up (the /auth/signup page) works even with no connection. On
the desktop you make an explicit account-type choice — it is
never a silent default:
- Device-only — everything stays on this computer. You get a personal workspace (you're its Owner) and the app is immediately usable: create projects, import data, label — fully offline. No email leaves the device (the address is auto-verified locally), and nothing is sent to any server.
- Cloud — your account is created on AfriAnnotate's cloud and mirrored to the device. This requires ticking a consent box first: a cloud account stores your email, name, and your annotation work on shared projects on AfriAnnotate's servers. Creating one needs a connection — while offline, the cloud option is disabled and device-only is the only path.
The same consent gate is universal: every cloud signup (web,
mobile, or desktop-choosing-cloud) must explicitly consent before
any account row is written, and the consent is recorded as a
user.signup_consent audit event.
A device-only account isn't a trap — you can link it to the cloud later, on your terms.
Linking a device-only account to the cloud
When you're signed in with a device-only account, the Cloud sync tab shows a "Link this account to AfriAnnotate cloud" card. Linking is consent-first by design:
- The card states exactly what gets sent: your email address, your name, your password (to create the cloud account), and — going forward — your annotation work on shared projects. Projects you keep device-only are not uploaded.
- The consent checkbox starts unchecked, and the server refuses to make any cloud call before consent is present.
- You re-enter your password — it's verified against the local account first, proving the person linking owns it.
- Link to cloud:
- Email free on the cloud → a cloud account is created with the same credentials.
- Email already registered on the cloud → the desktop signs in with the same credentials and merges by email. A password mismatch is surfaced as an error — never guessed around or overwritten.
- On success you get a receipt: the cloud records a
user.account_linkedaudit event and emails the account address a confirmation stating when the link happened, from which device, and what was consented to — with an "if this wasn't you" pointer. - A background pull brings your cloud projects in, and the app reloads into the linked world.
Linking needs a connection; offline it fails fast with a clear message and nothing changes.
Projects tab
A checklist of every project you could take offline — across all your cloud organizations — each with its cloud-side offline policy, whether it's downloaded on this device, its local task count, and any pending pushes. Toggling a project here is the same Download for offline control as the cloud badge on the project cards; see Selective sync for what downloading and evicting actually do.
Pending tab
A staging-area view of every local change that hasn't reached the cloud: unpushed annotations and drafts (including deletes waiting to be sent as tombstones). Each row shows the operation (New / Edit / Delete), the project and task, a one-line summary of the annotation content, when it was last edited, and any sync error.
Per-row actions:
- Push — upload just this change, without waiting for the next full sync.
- Revert — for a row that exists on the cloud: discard the local edit and restore the cloud version.
- Discard — for a local-only row that was never pushed: drop it.
Rows held with "cloud copy changed since last sync — resolve in Sync review" are conflicts — resolve them in the Sync modal (below) rather than here.
Empty when everything's in sync.
Activity tab
The recent sync runs, newest first: direction (pull or push), rows
processed and failed, a per-type breakdown (users / projects / tasks
/ annotations / drafts), a note saying what triggered the run
(auto, download, post-link, sync-modal-apply, …) and the
error if one occurred.
This is the first place to look when offline work seems missing or a project isn't syncing — the error column tells you whether the desktop hit an auth failure, a conflict hold, or a network issue.
The Sync modal — deliberate sync
Whenever you have unpushed work, the menubar shows a "N to push" pill; clicking it (or Sync now) opens the Sync modal — an explicit handshake before anything moves.
The entry screen lists your projects with their sync state: Downloaded or Online only, N to push, ⚠ N conflicts, Up to date or Changes on cloud (a genuine two-sided check against the cloud, not a guess). Per project you get:
- Push / Pull — move that project's queue now, one direction at a time
- Review — a row-by-row preview: changes that only touched one side flow through as compact line items; true conflicts (both sides changed since the last sync) get a side-by-side Local/Cloud diff and a per-row choice of Local, Cloud, Both, or Skip. Nothing is applied until every conflict has a resolution.
- Manual — a per-project toggle that takes the project out of automatic sync entirely: nothing moves until you press Push or Pull here. For work where you want to deliberately curate which side's version wins.
Conflicts only exist because the desktop holds colliding pushes instead of overwriting the cloud — see conflict holding.
User profile analytics
The Profile → Analytics tab shows your personal labelling analytics:
- Tasks labelled in the last 7 / 30 / 90 days
- Median lead time per task
- Skip rate
- Agreement score (where computed)
- Per-project breakdown
Useful for self-awareness ("am I getting faster?") and for managers who ask "how productive is this annotator on this project?" — managers see the same data at Organization → Metrics → Contributors.
What's next
- Offline sync architecture → — what happens under the hood
- Account → — the rest of the Profile page (name, password, email, PATs)
- Data security → — the per- project policies that govern what gets synced where