Skip to content

[codex] ungate automations#4734

Merged
saddlepaddle merged 1 commit into
mainfrom
solid-jackfruit
May 19, 2026
Merged

[codex] ungate automations#4734
saddlepaddle merged 1 commit into
mainfrom
solid-jackfruit

Conversation

@saddlepaddle
Copy link
Copy Markdown
Collaborator

@saddlepaddle saddlepaddle commented May 19, 2026

Summary

  • remove the desktop Automations paywall route guard and sidebar navigation gate
  • remove Automations from Pro paywall feature constants and upsell content
  • remove backend Pro-plan checks from automation creation, resume, run-now, scheduled evaluation, and dispatch

Why

Automations should be available to all authenticated users instead of being gated behind Pro.

Validation

  • bun run lint
  • bun run typecheck (Turbo crashed before executing TypeScript with a macOS system-configuration panic)
  • bun run typecheck in packages/trpc
  • bun run typecheck in apps/api
  • bun run typecheck in apps/desktop
  • searched for remaining Automations paywall/Pro-plan symbols

Open in Stage

Summary by cubic

Ungated Automations for all authenticated users across the app and backend. Removed Pro checks in desktop, API, TRPC, and dispatch, and updated docs, SDK, and pricing to reflect free availability.

  • Refactors
    • Desktop: removed Automations route guard and sidebar gating; replaced Automations paywall demo with Slack Integration preview; added Slack Integration to PRO_FEATURES; took Automations out of GATED_FEATURES, PRO_FEATURES, and FEATURE_ID_MAP; updated plan comparison to show Automations on Free.
    • API evaluate route: dropped subscription filters; now selects enabled, due automations by time only.
    • TRPC automation router: removed paid-plan enforcement for create/enable/run-now; org membership required only; removed skipped_unpaid handling.
    • Dispatch: removed subscription joins and unpaid-skip path; resolveTargetHost returns host only and still checks online status.
    • Docs/Marketing/SDK: removed Pro requirement from Automations docs; pricing (app + marketing) shows Free availability; SDK comment no longer mentions Pro.

Written for commit cd3fbaf. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • New Features

    • Added a Slack integration preview/demo in the feature preview.
  • New Features / Access

    • Automations are accessible to all org members (no paid plan required); Automations section opens directly.
  • Documentation

    • Automations docs and SDK JSDoc updated to reflect free-tier availability.
  • UI / Marketing

    • Paywall gating and Automations demo removed; pricing/plan comparisons updated to show Automations (and remote workspaces) included on the free tier.

Review Change Stack

@capy-ai
Copy link
Copy Markdown

capy-ai Bot commented May 19, 2026

Capy auto-review is paused for this organization because the monthly auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

📝 Walkthrough

Walkthrough

Subscription-based gating for automations is removed across the stack: DB selection, tRPC mutations, dispatch host resolution, and frontend paywall/demo/docs/pricing were updated to no longer require paid subscriptions.

Changes

Automations feature ungating

Layer / File(s) Summary
Feature gate config & demo components
apps/desktop/src/renderer/components/Paywall/constants.ts, apps/desktop/src/renderer/components/Paywall/.../SlackIntegrationDemo/*, apps/desktop/src/renderer/components/Paywall/components/FeaturePreview/FeaturePreview.tsx
Removes "automations" from gated feature registries and demo mapping; adds "slack-integration" feature and SlackIntegrationDemo component and exports.
Frontend routes, sidebar, docs, pricing, SDK docs
apps/desktop/src/renderer/routes/.../automations/layout.tsx, apps/desktop/src/renderer/.../DashboardSidebarHeader.tsx, apps/desktop/src/renderer/routes/_authenticated/settings/billing/plans/page.tsx, apps/docs/content/docs/automations.mdx, apps/marketing/src/app/pricing/constants.ts, packages/sdk/src/resources/automations.ts
Ungates Automations layout and sidebar navigation; updates pricing/comparison rows and documentation frontmatter; removes Pro-only wording in SDK JSDoc.
tRPC authorization and mutations
packages/trpc/src/router/automation/automation.ts
Replaces subscription-aware membership checks with requireActiveOrgMembership, removes requirePaidSubscription, and stops converting dispatch skipped_unpaid to forbidden errors.
Dispatch and host resolution
packages/trpc/src/router/automation/dispatch.ts
resolveTargetHost returns only v2Hosts rows (or null); subscription joins and paid-plan evaluation removed; DispatchOutcome no longer includes skipped_unpaid.
Automation evaluation query
apps/api/src/app/api/automations/evaluate/route.ts
Query simplified to enqueue automations where enabled = true and nextRunAt <= now, removing subscription-based eligibility filter.

Sequence Diagram

sequenceDiagram
  participant Client
  participant automationRouter as automationRouter
  participant requireActiveOrgMembership as requireActiveOrgMembership
  participant dispatchAutomation as dispatchAutomation
  Client->>automationRouter: create / setEnabled / runNow
  automationRouter->>requireActiveOrgMembership: verify membership
  requireActiveOrgMembership-->>automationRouter: membership confirmed
  automationRouter->>dispatchAutomation: dispatch (when applicable)
  dispatchAutomation-->>automationRouter: outcome (no skipped_unpaid)
  automationRouter-->>Client: response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

Hi, I'm a rabbit, nibbling code with delight,
I hopped through paywalls and cleared out the night,
Automations now wake where they once couldn't run,
Frontend and backend aligned — hop! task done! 🐇✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title '[codex] ungate automations' clearly and concisely summarizes the main change: removing Pro-plan gating for the Automations feature across the codebase.
Description check ✅ Passed The pull request description comprehensively covers the changes: it provides a clear summary, explains the motivation, lists validation steps, and includes detailed refactoring notes. All key sections from the template are addressed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch solid-jackfruit

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@stage-review
Copy link
Copy Markdown

stage-review Bot commented May 19, 2026

Ready to review this PR? Stage has broken it down into 6 individual chapters for you:

Title
1 Remove automation paywall checks from TRPC router
2 Remove subscription checks from automation dispatch
3 Ungate automation evaluation in API layer
4 Remove desktop paywall and route guards
5 Replace Automations demo with Slack Integration
6 Update pricing tables and documentation
Open in Stage

Chapters generated by Stage for commit cd3fbaf on May 19, 2026 9:23pm UTC.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 19, 2026

Greptile Summary

This PR removes all Pro-plan gates from the Automations feature, making it available to every authenticated user. The changes span the full stack: cron scheduler, tRPC mutations, desktop route guard, and sidebar navigation.

  • Backend (evaluate + dispatch): The cron evaluate route drops the EXISTS subscription subquery, so all enabled/due automations are now scheduled regardless of plan. resolveTargetHost removes the subscriptions join and paidPlan flag; DispatchOutcome drops the skipped_unpaid variant, and runNow removes its corresponding FORBIDDEN throw — all three changes are internally consistent.
  • tRPC mutations: create, setEnabled, and runNow switch from requireActiveOrgMembershipWithSubscription + requirePaidSubscription to plain requireActiveOrgMembership, matching the new access model.
  • Desktop UI: The /automations layout no longer redirects free-tier users, and the sidebar header navigates directly to /automations without wrapping in gateFeature. GATED_FEATURES.AUTOMATIONS is fully removed from the paywall constants; remaining GATED_FEATURES and gateFeature usages (Tasks) are unaffected.

Confidence Score: 5/5

Safe to merge — all paywall removal points are consistent across the cron scheduler, dispatch pipeline, tRPC mutations, and desktop UI with no dangling references.

Every layer of the paywall (frontend route guard, sidebar gate, tRPC subscription checks, cron subscription filter, and dispatch defense-in-depth) is removed in a coordinated, internally consistent way. The skipped_unpaid outcome variant is eliminated from both the type definition and all call sites. The third caller of dispatchAutomation (dispatch/[id]/route.ts) never pattern-matched on skipped_unpaid and is unaffected. No dangling references to GATED_FEATURES.AUTOMATIONS remain after the constants change.

No files require special attention.

Important Files Changed

Filename Overview
apps/api/src/app/api/automations/evaluate/route.ts Removes the EXISTS subquery that filtered out automations from non-paid orgs; the cron scheduler now dispatches all enabled, due automations regardless of subscription status.
apps/desktop/src/renderer/components/Paywall/constants.ts Removes AUTOMATIONS from GATED_FEATURES, PRO_FEATURES, and FEATURE_ID_MAP; no dangling references remain since GATED_FEATURES.TASKS still anchors the other usages.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/automations/layout.tsx Removes the paywall useEffect guard that redirected free-tier users away from /automations; the layout now simply renders the outlet for all authenticated users.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarHeader/DashboardSidebarHeader.tsx Removes gateFeature(GATED_FEATURES.AUTOMATIONS, ...) wrapper from the automations nav handler; GATED_FEATURES and gateFeature are still legitimately imported for the Tasks gate.
packages/trpc/src/router/automation/automation.ts Replaces requireActiveOrgMembershipWithSubscription + requirePaidSubscription with plain requireActiveOrgMembership on create, setEnabled, and runNow; also removes the skipped_unpaid outcome handler from runNow, consistent with its removal from DispatchOutcome.
packages/trpc/src/router/automation/dispatch.ts Removes subscription join and paidPlan guard from resolveTargetHost and drops the skipped_unpaid variant from DispatchOutcome; the only caller outside this package (dispatch/[id]/route.ts) serialises the outcome as JSON and never pattern-matched on skipped_unpaid, so no breakage.

Sequence Diagram

sequenceDiagram
    participant QStash
    participant EvaluateRoute as evaluate/route.ts
    participant DispatchRoute as dispatch/[id]/route.ts
    participant DispatchFn as dispatchAutomation()
    participant DB as Database

    QStash->>EvaluateRoute: POST (signed)
    EvaluateRoute->>DB: "SELECT automations WHERE enabled=true AND nextRunAt<=now"
    Note over EvaluateRoute,DB: (subscription check removed)
    DB-->>EvaluateRoute: due automations
    EvaluateRoute->>QStash: batchJSON dispatch jobs
    EvaluateRoute->>DB: advance nextRunAt for each

    QStash->>DispatchRoute: POST automationId + scheduledFor
    DispatchRoute->>DB: fetch automation
    DispatchRoute->>DispatchFn: dispatchAutomation()
    DispatchFn->>DB: resolveTargetHost (host only, no subscription join)
    alt host found and online
        DispatchFn->>DB: insert automationRuns (dispatching)
        DispatchFn-->>DispatchRoute: dispatched
    else host offline or missing
        DispatchFn->>DB: insert automationRuns (skipped_offline)
        DispatchFn-->>DispatchRoute: skipped_offline
    end
    DispatchRoute-->>QStash: 200 ok outcome
Loading

Reviews (1): Last reviewed commit: "ungate automations" | Re-trigger Greptile

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 6 files

Re-trigger cubic

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 19, 2026

🚀 Preview Deployment

🔗 Preview Links

Service Status Link
Neon Database (Neon) View Branch
Vercel API (Vercel) Open Preview
Vercel Web (Vercel) Open Preview
Vercel Marketing (Vercel) Open Preview
Vercel Admin (Vercel) Open Preview
Vercel Docs (Vercel) Open Preview

Preview updates automatically with new commits

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/trpc/src/router/automation/dispatch.ts (1)

172-198: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix host ordering to select the most recently updated online host.

Line 197 uses orderBy(v2Hosts.updatedAt) without desc(). In Drizzle ORM, orderBy(column) defaults to ascending order, so with limit(1), the fallback path selects the oldest online host instead of the most recently updated one. This causes untargeted automations to dispatch to stale machines.

Suggested fix
-import { and, eq } from "drizzle-orm";
+import { and, desc, eq } from "drizzle-orm";
...
-		.orderBy(v2Hosts.updatedAt)
+		.orderBy(desc(v2Hosts.updatedAt))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/trpc/src/router/automation/dispatch.ts` around lines 172 - 198, The
query that selects the host is ordering by v2Hosts.updatedAt in ascending order,
so limit(1) returns the oldest online host; change the ordering to descending to
pick the most recently updated online host. In the dbWs select block that
assigns to host (the query using v2Hosts, v2UsersHosts, and the where on
automation.ownerUserId/organizationId), replace orderBy(v2Hosts.updatedAt) with
an orderBy specifying descending order on v2Hosts.updatedAt (e.g.,
orderBy(desc(v2Hosts.updatedAt)) or the ORM's desc operator) so the limit(1)
returns the latest updated host.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/trpc/src/router/automation/dispatch.ts`:
- Around line 172-198: The query that selects the host is ordering by
v2Hosts.updatedAt in ascending order, so limit(1) returns the oldest online
host; change the ordering to descending to pick the most recently updated online
host. In the dbWs select block that assigns to host (the query using v2Hosts,
v2UsersHosts, and the where on automation.ownerUserId/organizationId), replace
orderBy(v2Hosts.updatedAt) with an orderBy specifying descending order on
v2Hosts.updatedAt (e.g., orderBy(desc(v2Hosts.updatedAt)) or the ORM's desc
operator) so the limit(1) returns the latest updated host.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8c4be6f1-9b1f-4940-bca6-ff5d5cd4d406

📥 Commits

Reviewing files that changed from the base of the PR and between 3b14ffb and cd3fbaf.

📒 Files selected for processing (15)
  • apps/api/src/app/api/automations/evaluate/route.ts
  • apps/desktop/src/renderer/components/Paywall/components/FeaturePreview/FeaturePreview.tsx
  • apps/desktop/src/renderer/components/Paywall/components/FeaturePreview/components/AutomationsDemo/AutomationsDemo.tsx
  • apps/desktop/src/renderer/components/Paywall/components/FeaturePreview/components/AutomationsDemo/index.ts
  • apps/desktop/src/renderer/components/Paywall/components/FeaturePreview/components/SlackIntegrationDemo/SlackIntegrationDemo.tsx
  • apps/desktop/src/renderer/components/Paywall/components/FeaturePreview/components/SlackIntegrationDemo/index.ts
  • apps/desktop/src/renderer/components/Paywall/constants.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/automations/layout.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarHeader/DashboardSidebarHeader.tsx
  • apps/desktop/src/renderer/routes/_authenticated/settings/billing/plans/page.tsx
  • apps/docs/content/docs/automations.mdx
  • apps/marketing/src/app/pricing/constants.ts
  • packages/sdk/src/resources/automations.ts
  • packages/trpc/src/router/automation/automation.ts
  • packages/trpc/src/router/automation/dispatch.ts
💤 Files with no reviewable changes (3)
  • apps/desktop/src/renderer/components/Paywall/components/FeaturePreview/components/AutomationsDemo/AutomationsDemo.tsx
  • apps/docs/content/docs/automations.mdx
  • apps/desktop/src/renderer/components/Paywall/components/FeaturePreview/components/AutomationsDemo/index.ts
✅ Files skipped from review due to trivial changes (3)
  • apps/desktop/src/renderer/components/Paywall/components/FeaturePreview/components/SlackIntegrationDemo/index.ts
  • apps/desktop/src/renderer/components/Paywall/components/FeaturePreview/components/SlackIntegrationDemo/SlackIntegrationDemo.tsx
  • packages/sdk/src/resources/automations.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • apps/desktop/src/renderer/routes/_authenticated/settings/billing/plans/page.tsx
  • apps/desktop/src/renderer/components/Paywall/components/FeaturePreview/FeaturePreview.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarHeader/DashboardSidebarHeader.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/automations/layout.tsx
  • apps/api/src/app/api/automations/evaluate/route.ts
  • packages/trpc/src/router/automation/automation.ts

@saddlepaddle saddlepaddle merged commit 7f0b302 into main May 19, 2026
22 of 23 checks passed
sazabi Bot pushed a commit that referenced this pull request May 20, 2026
MocA-Love added a commit to MocA-Love/superset that referenced this pull request May 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant