feat(paywall): gate relay + automations + remote workspaces, dither preview

Merged
SA
6mo ago
+517-279

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.checkAccess already refuses unpaid tunnels.
  • Server-side defense, zero new round-trips: findOrgMembership LEFT JOINs subscriptions so plan checks ride the existing membership read. New requireActiveOrgMembershipWithSubscription sibling, used in automation.create / setEnabled / runNow. host.checkAccess returns { allowed, paidPlan } (relay's 5-min LRU caches the combined boolean — no per-request API spam). dispatchAutomation joins subscriptions into resolveTargetHost and short-circuits unpaid runs with a recorded skip.
  • Paywall preview refresh: swaps MeshGradient for a DitheredBackground (shaders-react Dithering shape="warp" type="4x4") ported from marketing. Adds AutomationsDemo + RemoteWorkspacesDemo, drops obsolete CloudWorkspacesDemo/IntegrationsDemo. Reorders PRO_FEATURES to 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 /automations and /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.checkAccess returns paidPlan: false; automation.create returns 403; QStash dispatch for a free org records a skipped run before relay/host calls.
  • Query count: confirm automation.create and host.checkAccess issue the same number of round-trips before/after this change (subscription join rides the existing membership/access query).
  • Relay no-spam: tunnel up → host.checkAccess fires 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 typecheck clean.

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 automations and remote-workspaces; integrations settings open directly for all.
  • Refactors

    • Membership helpers: added findOrgMembershipWithSubscription and requireActiveOrgMembershipWithSubscription (select newest active/trialing subscription).
    • Automations: create, setEnabled (when enabling), and runNow require a paid plan; the evaluate cron only includes paid orgs; dispatch short-circuits unpaid orgs with skipped_unpaid and no run row.
    • Host/relay: host.checkAccess returns { allowed, paidPlan }; relay requires both and caches for 5 minutes per (token, hostId).
    • Billing: all subscription joins use ACTIVE_SUBSCRIPTION_STATUSES for consistent “active” checks.

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