Skip to content

Hosted plans

The hosted service enforces Free, Silver, and Gold capabilities in its control plane. Local budgeting remains available on every plan. Synced user data stays in Store5 and moves between devices only through WebRTC data channels.

CapabilityHosted FreeHosted SilverHosted GoldSelf-hosted
Registered devices in a finance space2UnlimitedUnlimitedOperator controlled
TURN for WebRTCNo hosted TURNHosted TURNHosted TURNOperator configured
Live bank account readingNoDeferred; unavailableDeferred; unavailableDeferred; unavailable
Finance spaces an account may belong to11UnlimitedOperator controlled

Self-hosted is a deployment edition, not a RevenueCat subscription. Its server uses authMode=none, does not query hosted billing, and does not enforce hosted quotas. Live bank connections are deferred in every edition.

Free receives STUN and can connect directly. Direct WebRTC sometimes works across networks without TURN, so Free must not be described as technically restricted to one local network. Silver and Gold may receive time-limited TURN credentials when configured; /api/tier reports TURN available only when both entitlement and server configuration are present. TURN is part of WebRTC, not an entity-sync API.

Each device has a Cloud relay switch in Settings. It starts off, including after logout or local reset. The ICE endpoint only returns TURN credentials when the device explicitly requests relay and the space has a paid entitlement. The client also discards relay candidates advertised by peers while the switch is off, and reconnects peers when it changes. STUN and direct WebRTC remain available with the switch off. Self-hosted devices can make the same choice when their operator configures TURN.

The space's effective sync plan is the highest active plan among its members. A Silver or Gold member sponsors device slots and TURN for that space. Each account's own plan controls how many spaces it may join. The hosted_spaces migration stores roles and memberships, while user_profiles.household_id remains the legacy active-space pointer. Invitations and Gold switching use isolated local data and the implemented client UI.

Space owners and admins can manage registered devices. Side-business spaces have their own Store5 data, with a linked transfer creating matching entries in both spaces when money moves between them.

The hosted device list shows all registrations in the active finance space and labels the account that registered each new device as yours, another member's, or unknown for legacy registrations. Legacy registrations remain unknown until an owner or admin removes them and the device registers again; a peer cannot claim an old device ID merely by reconnecting. Connection badges are computed locally from open WebRTC data channels on the device viewing the list; "not connected" does not mean unregistered or offline. The server does not record P2P connection status. The owner metadata migration must be applied before deploying the server version that uses it.

When a device is removed, updated clients connected to the signaling server close their existing WebRTC connection to that device. The removed client closes its channels when signaling rejects it and stops automatic reconnection until sync is explicitly restarted. Local data is preserved. Older clients and clients that miss the removal notification may retain a connection; this is not a guarantee of immediate remote cutoff.

Settings exposes the device list, relay switch, and subscription controls in the native SwiftUI iOS app and the shared Android, web, and desktop UI. Removing a registration is available to a space owner or admin. The displayed connection status always describes the device currently showing Settings.

RevenueCat setup

  1. Create Silver and Gold entitlements in one RevenueCat project and attach the iOS, Android, and web products to them. Use the Supabase user ID as the identified RevenueCat App User ID on every surface.
  2. Set the server API v2 project ID, secret key, and both entitlement IDs using the variables in .env.example. The secret API key needs customer_information:customers:read permission. If none are set, all hosted accounts are Free; partially configured RevenueCat variables fail server startup.
  3. Configure public iOS/Android SDK keys and offering IDs for native purchases. Configure production Web Purchase Links for browser and desktop checkout. Purchases are offered only to durable signed-in accounts. Native subscribers can open RevenueCat's management URL; web purchasers receive a customer portal link in their billing email. The browser and desktop app checks for entitlement activation after opening checkout.
  4. Apply the versioned supabase/migrations/ migrations to the hosted Supabase project before deploying the server code. They make space metadata server-owned, backfill membership and roles, and register devices atomically. The hosted signaling server fails closed when required metadata is unavailable.
  5. Configure TURN if Silver/Gold internet relay is offered. The server returns TURN only to a household with an active paid entitlement. The client now keeps the returned username and credential and fetches ICE configuration before beginning peer discovery.

The server reads current active entitlements from RevenueCat's API with a 30-second per-account cache. A 404 customer is Free. Other RevenueCat failures deny paid access until the service recovers. The app refreshes plan state after a purchase or restore; a user can also refresh it in Settings.

Current implementation limits

  • Settings includes space creation/selection, email-bound invitation codes, acceptance/decline, invitation revocation, owner/admin roles, removal, and last-owner protection. Free/Silver can hold one membership; Gold can hold multiple. A downgraded account can select its one active space without deleting local books.
  • Every Store5 entity query, receipt file, change-log version, and bookkeeping entry is space-scoped. Switching stops the old WebRTC runtime and retires its repository writers before exposing the next graph. Versioned local migration preserves existing books.
  • Gold linked transfers write paired postings atomically in the local database. Retry uses a stable transfer ID; paired edit/delete controls are in Finance spaces. Ordinary transaction editors cannot mutate one leg. Each space synchronizes only its own posting, and an inactive space catches up when opened over WebRTC. Both spaces must be locally synchronized to edit a complete pair. Currency conversion is not supported.
  • Live bank connections are deferred. Canada and the United States remain the intended regions. Direct client HTTPS ingestion is approved, but bank data must stay off Shilling servers, including transient forwarding. The proposed Plaid proxy is rejected. Device sync stays WebRTC; no live bank data is fetched, and live banking is not an available paid-plan feature.
  • Store products, RevenueCat keys, Web Purchase Links, and Supabase schema must be configured in the hosted environment before paid checkout works.