feat(paywall): gate relay + automations + remote workspaces, dither preview
Merged
SA
6mo ago+517+517+012345678901234567890123456789-279-279-012345678901234567890123456789
Summary
- UI gates for three Pro features that previously leaked to free users:
- Relay toggle in Settings → Security (on-toggle only; off stays ungated and keeps the new on/off confirm dialog from #3845).
- Automations sidebar entry is now visible to free users with paywall on click + direct-URL guard via a new
automations/layout.tsx. - Remote/cloud rows in the v2-workspaces list — open + add-to-sidebar gated. Local rows unaffected. The workspace page itself is intentionally not gated (avoid accidentally locking users out of local workspaces during weird states); server-side
host.checkAccessalready refuses unpaid tunnels.
- Server-side defense, zero new round-trips:
findOrgMembershipLEFT JOINssubscriptionsso plan checks ride the existing membership read. NewrequireActiveOrgMembershipWithSubscriptionsibling, used inautomation.create / setEnabled / runNow.host.checkAccessreturns{ allowed, paidPlan }(relay's 5-min LRU caches the combined boolean — no per-request API spam).dispatchAutomationjoins subscriptions intoresolveTargetHostand short-circuits unpaid runs with a recorded skip. - Paywall preview refresh: swaps
MeshGradientfor aDitheredBackground(shaders-reactDitheringshape="warp"type="4x4") ported from marketing. AddsAutomationsDemo+RemoteWorkspacesDemo, drops obsoleteCloudWorkspacesDemo/IntegrationsDemo. ReordersPRO_FEATURESto remote-workspaces → automations → team-collaboration → tasks → mobile-app, tightens the remote-workspaces copy so feature-switching no longer shifts the modal height.
Test plan
- Free org — sidebar visibility: Automations entry is visible. Click → paywall opens preselected to "automations". Cancel returns. Upgrade →
/settings/billing/plans. - Free org — relay toggle: flip Settings → Security toggle on → paywall (preselected "remote-workspaces"); switch stays off, no confirm dialog. Toggling off shows the existing confirm.
- Free org — direct URL: navigate to
/automationsand/automations/<id>→ paywall + redirect to/v2-workspaces. - Free org — workspaces list: clicking a remote-device or cloud row → paywall. Clicking the
+(add to sidebar) on those rows → paywall. Local rows still open + add instantly. - Free org — direct workspace URL: pasting a remote
/v2-workspace/<id>does not open the paywall (intentional). Page renders but host data fails to load (relay refuses tunnel). - Paid org: all flows work as today; no paywall, automations work, relay confirm appears as before.
- Server: with a free-org JWT,
host.checkAccessreturnspaidPlan: false;automation.createreturns 403; QStash dispatch for a free org records a skipped run before relay/host calls. - Query count: confirm
automation.createandhost.checkAccessissue the same number of round-trips before/after this change (subscription join rides the existing membership/access query). - Relay no-spam: tunnel up →
host.checkAccessfires at most once per 5 min per (token, hostId). - Visual: open paywall on each feature, switch between them, verify dither cross-fades smoothly and demo cards stay readable; modal height stays steady across selections.
-
bun run lint:fix && bun run typecheckclean.
Summary by cubic
Gates relay, automations, and remote workspaces behind Pro, updates the paywall preview with a dithered background, and filters unpaid automations before enqueue; dispatch still bails without writing runs. Standardizes active-subscription checks using ACTIVE_SUBSCRIPTION_STATUSES.
-
New Features
- UI gates: relay “on” toggle; Automations entry with click paywall + direct-route guard; remote/cloud workspace row open/add; local rows stay open; workspace page remains ungated.
- Paywall preview: swapped to a dithered background from
@paper-design/shaders-react; added Automations and Remote Workspaces demos; removed obsolete demos; modal height stays steady. - Constants/UI: gated IDs updated to
automationsandremote-workspaces; integrations settings open directly for all.
-
Refactors
- Membership helpers: added
findOrgMembershipWithSubscriptionandrequireActiveOrgMembershipWithSubscription(select newest active/trialing subscription). - Automations:
create,setEnabled(when enabling), andrunNowrequire a paid plan; the evaluate cron only includes paid orgs; dispatch short-circuits unpaid orgs withskipped_unpaidand no run row. - Host/relay:
host.checkAccessreturns{ allowed, paidPlan }; relay requires both and caches for 5 minutes per (token, hostId). - Billing: all subscription joins use
ACTIVE_SUBSCRIPTION_STATUSESfor consistent “active” checks.
- Membership helpers: added
Summary by CodeRabbit
Release Notes
-
New Features
- Automations: New premium feature enabling you to schedule and automatically execute workflows across your workspace
- Remote Workspaces: New premium feature allowing secure connections to and management of remote workspace machines
- Integrations now available on all subscription plans
-
Chores
- Updated paywall feature previews with new visual designs and improved presentation
- Removed Cloud Workspaces feature preview from paywall