Offline & Sync
Web vs mobile: Offline support is a mobile-native capability — PanelOne web requires connectivity. Mobile caches reads and queues writes for triage in the field; integration sync and OAuth always need the web app or network.
PanelOne Mobile is designed for MSP engineers who lose connectivity on client sites, in elevators, or during travel. The app caches operational data locally and queues mutations for later sync.
How It Works
Two systems power offline behavior:
| System | Purpose |
|---|---|
| Offline cache | JSON envelopes in app cache directory — read-only data |
| Write queue | Pending mutations with retry and dead-letter handling |
Both are scoped per device. Sign-out purges cache and queue entirely.
Cached Reads
When online, the app stores successful API responses in PanelOneMobileCache:
| Data | Cached |
|---|---|
| Dashboard stats & widgets | Yes |
| Client lists & detail | Yes |
| Device lists & detail | Yes |
| Alert lists & detail | Yes |
| Ticket lists & detail | Yes |
| More hub product lists | Yes |
| Org capabilities & directory | Yes |
Each cache entry includes an updatedAt timestamp. Offline views show last-known data with that freshness.
When offline, reads serve from cache first — no network request is attempted.
Write Queue
When you perform a mutation offline, the app enqueues a QueuedWrite:
| Field | Description |
|---|---|
| id | Unique queue entry ID |
| kind | Write type (see table below) |
| payload | Mutation data |
| clientMutationId | Idempotency key for server dedup |
| retries | Failure count |
| lastError | Last error message if failed |
Supported Write Kinds
| Kind | Action |
|---|---|
alert_acknowledge | Acknowledge an alert |
ticket_create | Create a new ticket |
ticket_status_update | Change ticket status |
ticket_field_update | Change priority, assignee, etc. |
ticket_comment | Add ticket comment |
psa_job_create / psa_job_update | PSA job mutations |
psa_lead_create / psa_lead_update / psa_lead_stage_update | Lead pipeline |
psa_quote_create / psa_quote_update | Quotes |
psa_job_task_create / psa_job_task_update / psa_job_task_delete | Job tasks |
psa_job_note_create | Job notes |
psa_timesheet_create | Timesheets |
psa_timer_start / psa_timer_stop | PSA timers |
The UI updates optimistically — you see changes immediately; the queue syncs in the background.
Queue Flush & Retry
When connectivity returns:
- Foreground — Queue flushes on next online API interaction.
- Background —
BGAppRefreshTask(offline-refresh) attempts flush when authenticated.
Retry Policy
| Setting | Value |
|---|---|
| Max retries | 3 per write |
| On permanent failure | Write moves to dead-letter queue (offline-write-dead-letter.json) |
| Idempotency | clientMutationId prevents duplicate server-side application |
If a write lands in the dead-letter queue, retry manually when online or contact support with the error from lastError.
What Works Offline
| Feature | Offline support |
|---|---|
| Browse cached lists | Yes |
| View cached detail | Yes |
| Acknowledge alerts | Queued |
| Create tickets | Queued |
| Update ticket status/fields | Queued |
| Add ticket comments | Queued |
| PSA writes | Queued |
| Global search | Cached entities only |
| Dashboard | Cached stats |
What Requires Connectivity
| Feature | Why |
|---|---|
| Remote device actions | Live vendor API calls |
| Patch scan / apply | RMM real-time |
| Document upload/download | Storage signed URLs |
| Integration OAuth | Browser auth flow |
| Marketplace install | Web wizard |
| Client create | Not available on mobile |
| Passkey registration | WebAuthn ceremony |
| Fresh data sync | Supabase fetch |
| Push token registration | APNs setup |
Sign-Out Purge
Signing out runs OfflineLocalDataPurger:
- Clears all cached JSON files.
- Clears active write queue.
- Clears dead-letter queue.
- Removes Keychain session.
This prevents operational data from persisting on shared devices.
Background Refresh
Each app registers a background refresh task declared in Info.plist:
- Task identifier:
offline-refresh - Runs only when an authenticated shell can provide session context
- Primary purpose: flush queued writes after reconnect
Background execution is best-effort — iOS schedules based on usage patterns.
Realtime Updates (Online)
When online, scoped realtime invalidation refreshes active tabs when Supabase tables change — without full app restart. Offline cache updates on the next successful fetch after invalidation.
Tips & Best Practices
- Triage offline confidently — Acknowledges and ticket updates queue safely.
- Verify critical actions when back online — Check alert and ticket state after reconnect.
- Don't rely on offline for device actions — Schedule reboots/scripts when connected.
- Sign out on shared iPads — Purge ensures no client data remains.
Related Guides
- Alerts — Offline acknowledge
- Tickets — Offline create and update
- Getting Started — Sign-out behavior