Cloud Sync & Multi-User
WyzBooks offers two ways for multiple computers to share accounting data: Multi-User Mode for local networks (NAS, shared folders) and Cloud Sync for remote collaboration over the internet. Both use the same three-way merge algorithm for conflict resolution. They are mutually exclusive — enabling one disables the other. Both are configured in Settings → Advanced.
Multi-User Mode (NAS)
Multi-User Mode enables file locking and live sync when a shared .wyzbooks file is open. Multiple computers can safely edit the same company file on a NAS or network drive without data loss.
- Enabling — Go to Settings → Advanced and check Multi-User Mode (enabled by default). Then open a .wyzbooks file from a shared location (File → Open). The sidebar footer shows a green status indicator with the filename when shared mode is active.
- File Locking — Each save acquires an atomic directory-based lock on the shared file. If another host is writing, the save waits (up to 8 seconds) rather than corrupting data.
- Live Sync — The app polls the shared file every 1.5 seconds. When another host saves changes, your data updates automatically — no manual reload needed.
- Three-Way Merge — When both hosts edit different records, all changes are preserved. When both edit the same record, the last save wins at the record level (not the file level). Merging covers all 9 data collections: accounts, contacts, invoices, payments, journals, bank transactions, items, terms, and bills.
- Deletion — Deletions always take effect. If one host deletes a record, it is removed for all hosts on the next sync.
- Sync Highlights — When another host adds a record, it appears with a green highlight that fades over 2 seconds. Modified records highlight yellow. The view auto-scrolls to show the highlighted row.
- Integrity — Each save writes a SHA-256 checksum to the file. On every sync, the checksum is verified. A backup (.bak) is created before each write. Use the Check File button in Settings → Advanced to manually validate file integrity.
Open a .wyzbooks file (File → Open) to activate shared mode. Multi-User Mode works with any network-accessible location — NAS, shared folder, or USB drive.
Cloud Sync
Cloud Sync connects your WyzBooks desktop app to a remote WyzBooks API server, enabling near-real-time data synchronization between multiple computers over the internet. Changes push automatically on save, and incoming changes arrive instantly via a persistent server connection.
Prerequisites
- Remote server — A Linux server running the WyzBooks API (Express on Node.js) behind Apache or Nginx with TLS.
- API key — A shared secret key configured on the server and entered in the app. All connected instances use the same key.
- Network access — The app must be able to reach the server URL over HTTPS. No inbound ports are required on the client.
Connecting
Go to Settings → Advanced → Cloud Sync. Enter the server URL (must start with http:// or https://) and the API key.
- Test — Click Test to verify the URL and key are correct without syncing data. A lightweight health check is sent to the server.
- Connect Mode — Choose one of three modes before connecting: Normal (merge local and server data — default), Push First (overwrite the server with your local data — use when this machine is the source of truth), or Pull First (replace local data with server data — use when the server is the source of truth).
- Connect — Click Connect to establish the sync connection. Behavior depends on the selected mode.
How Sync Works
- Push — When you save any change (create, edit, or delete a record), the app computes a delta against the last-synced state and sends only the changed records to the server.
- Receive — The app maintains a persistent SSE (Server-Sent Events) connection to the server. When another client pushes changes, the server broadcasts them instantly. Your app applies the changes and briefly highlights new or modified rows. The client polls for changes every 30 seconds as a fallback when SSE events may have been missed.
- Reconnect protection — Three concurrent mechanisms protect against stuck connections: (1) When your Mac wakes from sleep, the app immediately tears down the stale SSE stream and starts a fresh one — no waiting for timeouts. (2) A 25-second socket timeout detects dead TCP connections (the server sends heartbeats every 15 seconds, so 25 seconds of silence means the connection is dead). (3) A 45-second stale-guard timer catches connections that are technically alive but have stopped delivering data. All three run in parallel — any one is sufficient to recover.
- Connect merge — On connect, the app fetches server changes and applies them on top of local data. Server records overwrite local for any record the server has changed. This ensures edits from other clients are always picked up. The sync version is persisted across restarts for efficient incremental sync.
- Conflict resolution — If two clients edit different records simultaneously, both changes are preserved. If two clients edit the same record at the same time (true conflict), a modal appears showing both versions side by side for each conflicting record. You can choose "Keep Local" or "Accept Server" per record, or use the bulk buttons to apply the same choice to all. The conflict resolution modal has a 60-second timeout. If no user action is taken, the modal automatically dismisses and a red error banner appears: "Sync conflict resolution timed out after 60 seconds. Your choices were not applied — please retry your save." The banner clears after 15 seconds. Your local data is unchanged — simply edit and save again to retry the sync. If there are no true conflicts (only non-overlapping additions), the merge happens silently.
- Event log — All data changes are stored as an append-only event log. Each event records what changed (which record, which fields, upsert or delete) with a monotonic event ID. The current state of your data (the 9 collections) is a projection derived from the event log. This unified format is shared across standalone, multi-user, and cloud sync modes — switching modes is seamless because the underlying storage is identical.
- Versioning — The server maintains a monotonic event ID counter (replacing the older sync version system). Each push increments the counter. Clients track which event they last saw, and on reconnect any missed changes are delivered automatically.
Cloud Messaging
When Cloud Sync is connected and messaging is enabled, users can send short text messages to all other connected instances. Messages appear on the Dashboard and are signaled via a badge in the sidebar footer.
- Compose bar — A compose bar appears in the Dashboard header when connected. It contains a text input (350px wide), a Send button, and a sent/failed status indicator.
- Receiving — Incoming messages appear as blue notification cards on the Dashboard. Each card shows the sender name, timestamp, message text, and a dismiss button. Messages persist until manually dismissed.
- Sidebar badge — The sidebar footer shows a message count badge (e.g. "3 messages") on ALL pages, not just the Dashboard. When a new message arrives, the badge flashes yellow for 3 seconds, then settles to blue. Click the badge to navigate to the Dashboard.
- Echo — By default, your own sent messages are not shown back to you. Enable "Show my own sent messages" (messaging-echo) to see them.
- Dock badge — The macOS dock icon shows a red badge with the unread message count. Clears as messages are dismissed. Disable via "Show dock icon badge" in Settings or
dock-badge = falsein the[cloud-sync]INI section. - Settings — In Settings → Advanced, the Cloud Messaging checkbox enables or disables messaging. The "Show my own sent messages" checkbox controls echo. The "Show dock icon badge" checkbox controls the dock badge. A Clear Message Queue button removes all current messages and clears the dock badge.
Push & Pull
In addition to real-time delta sync, Cloud Sync provides manual Push and Pull operations for full data and settings transfers. These are useful for initial setup, recovery, or syncing configuration between machines.
- Transfer row — A unified Transfer row in Settings → Advanced provides shared Data and Settings checkboxes, plus Pull and Push buttons. Check the boxes for what you want to transfer, then click the direction.
- Data push — Sends a full replace of your local data to the server. This is not a delta merge — it overwrites the server's data entirely.
- Data pull — Downloads the server's data and writes it to your local event store. Any internal sync metadata is stripped automatically.
- Settings push — Pushes 35 syncable preferences to the server, including business info, invoice/register defaults, tab state, compact view, theme scope, sidebar layout, appearance cards, and dock badge settings. Also syncs INI theme sections and custom presets. Per-machine settings (cloud sync credentials, API port, multi-user mode) are excluded.
- Settings pull — Downloads synced preferences and INI sections from the server and writes them to local files.
- Tabs — Tab state is synced via manual push/pull only — it is not included in real-time sync.
- Confirm dialogs — Destructive operations (push overwrites server, pull overwrites local) require confirmation before proceeding.
- Timestamps — Completion messages include timestamps so you can verify when the last transfer occurred.
Divergence Detection
The Check Sync button lets you compare your local data against the server to detect whether they have diverged.
- Record comparison — Comparison fetches server data and compares each record by ID. The _rev field is stripped before comparison to ensure only actual data differences are detected.
- In sync — When all records match, a green "In sync" message is shown along with per-collection record counts.
- Diverged — When records differ, a red "Diverged" message is shown with per-collection local and server counts, and record-level diffs showing modified, local-only, and server-only records with their changed field names.
- Record limit — Up to 20 differing records are shown per collection, with an overflow indicator when more exist.
- Auto-check — Divergence detection runs automatically after every Pull operation.
- Periodic checker — When connected, the app automatically checks for divergence every 5 minutes by fetching server data and comparing records. If divergence is detected, a yellow warning banner appears at the top of the Dashboard with Push, Pull, and Dismiss buttons. This catches drift caused by network issues, server restarts, or other anomalies.
- Data persistence — All data received via cloud sync (SSE, polling, or initial connect merge) is automatically written to the local data file. This ensures that synced data survives app quit and relaunch without diverging from the server.
Auto-Reconnect
When you connect, your server URL and API key are saved in preferences. On next app launch, Cloud Sync reconnects automatically. You can also configure auto-connect via the INI file (see below).
- Exponential backoff — If the server becomes unreachable, auto-connect retries with 800ms initial delay, then exponential backoff (2s, 4s, 8s, 16s, max 30s). The system gives up after 2 minutes of failed attempts. HTTP keep-alive is used for faster connection reuse across sequential requests during connect.
- Status indicators — During reconnection attempts, the sidebar footer and dashboard badge show a yellow "Connecting..." indicator.
- Cloud badge popup — Click the cloud sync badge on any page to open a status popup showing connection state, server URL, and sync version. When disconnected, the popup includes a Connect button to manually reconnect.
- Offline queuing — Changes made while offline are queued and pushed when the connection is restored. Failed push attempts retain items in the queue for retry rather than silently dropping them.
- Continue Offline — During the "Connecting to Cloud Sync" overlay, a Continue Offline button lets you cancel the connection attempt and work in local-only mode. Cloud Sync will not auto-reconnect until you manually click Connect in the Cloud Sync popup or restart the app. After cancellation, status updates are suppressed for a 2-second window to prevent stale connection messages from appearing.
Offline Behavior
The app works fully offline. All data is stored locally. Cloud Sync is additive — it pushes and receives changes but never replaces local storage.
If a push fails (server down, network error), the change is queued. When the connection is restored, queued changes replay in order.
Choosing Between Them
- Multi-User Mode — Best for offices where all computers can access the same NAS or shared folder. No server setup required. Uses file polling (1.5s interval). Data stays entirely on your local network.
- Cloud Sync — Best for remote teams or multiple locations. Requires a server running the WyzBooks API. Uses real-time SSE for instant updates. Data travels over the internet (HTTPS).
Connecting Cloud Sync automatically disables Multi-User Mode. They cannot be active at the same time. When you toggle either mode, a confirmation dialog explains what will happen — no data is lost during mode switching because all three modes share the same unified event-log storage format.
Backup & Restore
WyzBooks automatically backs up your data file daily and provides tools for manual backup and restore. The backup system works identically in all three modes (standalone, multi-user, cloud sync).
- Auto daily backup — On every app launch (and every 24 hours while running), WyzBooks copies your data file to
~/Library/Application Support/WyzBooks/data/backups/with a date-stamped filename. Backups older than 30 days are automatically removed. Configure via the[backup]section inwyzbooks.ini. - Backup & Restore UI — In Settings → Advanced, the Backup & Restore card shows available backups sorted by date with file sizes. Click Backup Now to create an immediate backup. Click Restore on any backup to replace your current data. A confirmation dialog warns you before restoring, and a safety copy is saved before replacement.
- Per-write safety copy — Every time WyzBooks writes to the data file, it first copies the current version to a
.bakfile. This provides millisecond-level recovery from the most recent write. - Server recovery — If the cloud sync server is lost, any desktop client can restore it. Connect with Push First mode — this replaces the entire server state with your local data, including the full event history. The server is never the single point of failure.
Five independent backup layers protect your data: (1) per-write .bak copy, (2) daily auto-backup with 30-day retention, (3) server-side backups via wbctl, (4) manual Save As exports, and (5) macOS Time Machine (the data directory is backed up by default). Any single layer is sufficient for full recovery.
Data Integrity
WyzBooks verifies your data integrity automatically and provides recovery mechanisms for corrupted files.
- Startup validation — On every app launch, WyzBooks verifies that the stored data projection matches what the event log produces. If they diverge, the projection is automatically rebuilt. No user action needed.
- Corruption recovery — If the data file is corrupted, the app falls back to the
.baksafety copy. If the.bakis also corrupted, the daily auto-backup provides an additional recovery point. - Checksum verification — Multi-user shared files include a SHA-256 checksum in the file metadata. On every poll (1.5 seconds), the checksum is verified before applying changes.
- Event log compaction — To prevent the event log from growing indefinitely, WyzBooks automatically compacts old events. On the desktop, compaction runs daily, keeping the most recent 1,000 events. On the API server, compaction triggers when the event count exceeds 2,000. Compaction is lossless — the current data state is identical before and after.
Disaster Recovery
WyzBooks is designed so that no single device failure can cause data loss.
- Server dies — Every desktop client has a complete copy. Set up a fresh server and connect from any client with Push First.
- Client dies — Relaunch (or install on a new Mac) and connect with Pull First.
- Server + client die — Any surviving client can restore the server via Push First.
- All devices die — Restore from any device's daily auto-backup (30-day retention) or from Time Machine.
- Offline resilience — If the server goes down, every client keeps working normally. Local edits continue without interruption. When the server returns, the client pushes accumulated changes automatically on reconnect.
INI Configuration
Cloud Sync and Multi-User Mode can be controlled via ~/.wyzbooks/wyzbooks.ini with two levels of control:
- enabled — Master kill switch. When set to
false, overrides saved preferences and completely disables the feature. The Settings checkbox becomes disabled. Default:true - auto-connect — Controls startup behavior only. When
true(withserver-urlandapi-keyset), the app auto-connects on launch. Whenfalse, the user can still manually connect in Settings. This is separate from theenabledswitch.
[cloud-sync]
enabled = true
server-url = https://sync.example.com
api-key = your-api-key-here
auto-connect = true
messaging = true
messaging-echo = false
[multi-user]
enabled = true
To disable cloud sync entirely from the INI file (overriding any saved preferences), set enabled = false in [cloud-sync]. To disable multi-user mode, set enabled = false in [multi-user]. See INI Options for all available keys.
Security
- API key storage — The API key is stored in plain text in your preferences file and in wyzbooks.ini. It is not included in settings exports (stripped for security). Treat it like a password.
- Transport — Always use HTTPS for production servers. The API key is sent in the X-API-Key header on every request.
- Server access — The API server binds to localhost only. External access goes through Apache or Nginx with TLS termination.