Offline capabilities
What it is
Section titled “What it is”Syndik8 is offline-first. The app keeps a local copy of your syndicate data in an on-device SQLite database and uses it for almost everything the UI shows. Reads and writes work without an internet connection; writes queue and sync on reconnection.
The sync engine is PowerSync. The data flow is: your device ↔ PowerSync service ↔ Supabase Postgres. PowerSync replicates a filtered view of the Postgres tables to the local SQLite and pushes local writes back.
Who can use it
Section titled “Who can use it”Every member, on every supported platform. Offline behaviour is not opt-in and there is no per-user toggle.
Where to find it
Section titled “Where to find it”- The behaviour is part of every screen. You do not navigate to an “offline mode”.
- The traffic-light profile avatar in the navigation chrome is the live indicator:
| Colour | State |
|---|---|
| Green | Connected and receiving real-time updates. |
| Amber | Reconnecting. |
| Red | Offline — no PowerSync session and no network. |
Fields / options
Section titled “Fields / options”Tables synced to the device
Section titled “Tables synced to the device”Syndik8 syncs around twenty tables locally. These carry almost all of the day-to-day UI:
| Area | Synced tables | Writes |
|---|---|---|
| Core | syndicates, memberships, user_profiles | Offline |
| Assets | assets, asset_types, asset_billing_configs | Mixed — config writes go online via repository |
| Calendar | bookings, events | Offline |
| Usage and maintenance | usage_logs, maintenance_items, maintenance_templates, maintenance_logs, squawks | Offline |
| Finance — read-only projections | transactions, expenses, billing_schemes | Online-only writes. Members can see balances, expenses, and the configured rate schemes without a connection; changes to those tables go through the server. |
| Payments — read-only projections | mandates, member_funds, advance_notices | Online-only writes. Direct-debit mandate, member loan / goodwill / refund-as-credit, and “debit incoming” cards visible offline; setup and changes go through provider Edge Functions. |
| Notifications | notifications | Offline |
The authoritative list lives in internal-docs/ARCHITECTURE.md (“Synced Tables Reference”) and the client schema at lib/data/powersync/schema.dart.
Sync follows active membership. Each device only receives data for syndicates where the user’s membership status is active. The moment a member leaves or an admin removes them, the syndicate’s tables stop syncing to their device and the offline cache no longer refreshes — past entries already on the device remain until the next clean sync clears them.
Tables that are deliberately online-only
Section titled “Tables that are deliberately online-only”| Table | Why online-only |
|---|---|
settlements, reversals, disbursements, payment_events | Ledger sources of truth — money conflicts are unacceptable. |
invites | Depends on server-side auth checks. |
notification_preferences | Per-user setting read rarely. |
member_balances (view) | Computed from synced transactions — no row to sync. |
asset_scheme_rate_overrides | Read on demand. |
What works offline
Section titled “What works offline”| Capability | Behaviour |
|---|---|
| View synced data | Calendar, bookings, usage, maintenance, squawks, members, balances — all read from the local SQLite. |
| Maintenance check before booking | Computed locally from synced maintenance items, asset meter, and recent usage logs. ~10 ms typical; no network round-trip. |
| Create a booking | Saved locally; syncs as pending or confirmed on reconnection. Snackbar reads Booking created — will sync when you’re back online. |
| Approve, reject, confirm, or cancel a booking | Saved locally; syncs on reconnection. Snackbars carry the same “will sync” suffix offline. |
| Log usage | Stored locally with photo URLs pointing at uploaded evidence (the photo itself uploads when online). |
| Report a squawk | Stored locally; syncs on reconnection. |
| Read transactions and statements | Financial reads are offline-capable from the synced transactions table. |
| Submit an expense | Stored locally; syncs on reconnection. Receipt photo uploads when online. |
What requires a connection
Section titled “What requires a connection”These actions are gated by a button that disables when the device is offline. Tapping (or hovering on web) shows the reason snackbar listed below.
| Action | Reason snackbar | Why blocked |
|---|---|---|
| Create or revoke an invite | Invites need a connection — try again when you’re online. | Server-side auth flow. |
| Finalise a booking (single or bulk) | Settlements need a connection — try again when you’re online. | Calls the finalise_booking / bulk_finalise RPC, which writes the per-log charges, shortfall transactions, and flips the booking status. Money conflicts are unacceptable, so the action cannot be queued. |
| Approve or reject an expense | Approval needs a connection — try again when you’re online. | Writes an expenseCredit (or rejection) to the financial ledger. |
| Start payment provider setup (Stripe / UniPaaS) | Payment setup needs a connection — try again when you’re online. | Hits external Edge Functions that have no offline contract. |
| Update notification preferences | n/a — page itself fetches online | Read from / written to user_profiles.notification_preferences online. |
| Payment checkout | n/a | Web-only, opens the checkout URL in a new tab (see upgrade prompt). |
| Load a legal document not yet cached | n/a | Terms of Service and Privacy Policy are fetched from the server; a not-yet-cached copy is unavailable offline. |
Behaviour rules
Section titled “Behaviour rules”- Writes queue locally. A booking, usage log, or squawk created offline is written to the local SQLite immediately and appears in the UI. PowerSync pushes the change when the device reconnects.
- Last-write-wins for most conflicts. If two devices edit the same record offline and reconnect, the later write replaces the earlier one. There is no three-way merge.
- Overlapping bookings are rejected on the server. Two members who create overlapping
confirmedbookings offline will both see them locally; when sync runs, the one that reaches the server first is accepted and the other is rejected by the database exclusion constraint and surfaces as a sync error. - Tentative bookings do not conflict. Multiple
tentativebookings can coexist on the same slot — the database constraint coversconfirmedonly. - Photos upload separately. A usage-log photo is staged on the device and uploaded to Supabase Storage when online. The log itself appears immediately; the photo is available when it finishes uploading.
- The traffic-light indicator reacts in seconds. OS-level network callbacks flip the colour to red as soon as the device loses connectivity, rather than waiting for a WebSocket heartbeat timeout.
- First-sync-on-signin. On a fresh signin, PowerSync clears any prior local data and re-hydrates from scratch. Network outages during that first pass mean the UI is usable only for the tables that completed before the outage.
- Online-only buttons disable themselves and explain why. Booking finalisation, expense approve/reject, invite generation, and payment-provider setup all watch the connectivity stream. When the device is offline, the button is disabled; tapping it shows a short reason snackbar (e.g. Settlements need a connection). The button re-enables automatically when connectivity returns.
- PowerSync-backed write success messages adapt to connectivity. When you create or edit something while offline, the success snackbar appends — will sync when you’re back online on a second line so it’s clear the change is queued, not delivered.
- Maintenance check before booking is computed locally. When you open the booking dialog, Syndik8 evaluates the asset’s open maintenance items (hours-based and calendar-based) against the synced meter reading and recent usage logs in around 10 ms — no network call. The amber/red warning surfaces in the dialog whether the device is online or offline.
- Web sessions clear local data when the tab closes. The web build does not background-sync closed tabs. iOS and Android keep local data across app launches until sign-out.
For the reasoning behind offline-first, see Offline-first architecture.
See also
Section titled “See also”- iOS platform
- Android platform
- Web platform
- Conflict detection — the database-level exclusion constraint on confirmed bookings